1 // Copyright 2011 Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // * Neither the name of Google Inc. nor the names of its contributors 14 // may be used to endorse or promote products derived from this software 15 // without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 #include "engine/drivers/scan_action.hpp" 30 31 #include "engine/action.hpp" 32 #include "engine/exceptions.hpp" 33 #include "engine/test_result.hpp" 34 #include "store/backend.hpp" 35 #include "store/exceptions.hpp" 36 #include "store/transaction.hpp" 37 #include "utils/optional.ipp" 38 39 namespace fs = utils::fs; 40 namespace scan_action = engine::drivers::scan_action; 41 42 using utils::optional; 43 44 45 namespace { 46 47 48 /// Gets an action from the store. 49 /// 50 /// \param tx The open store transaction. 51 /// \param [in,out] action_id The specific action to get, or none to fetch the 52 /// latest available action. This is updated to contain the action id of 53 /// the returned action. 54 /// 55 /// \return The fetched action. 56 /// 57 /// \throw error If there is any problem while loading the action. 58 static engine::action 59 get_action(store::transaction& tx, optional< int64_t >& action_id) 60 { 61 try { 62 if (action_id) 63 return tx.get_action(action_id.get()); 64 else { 65 const std::pair< int64_t, engine::action > latest_action = 66 tx.get_latest_action(); 67 action_id = latest_action.first; 68 return latest_action.second; 69 } 70 } catch (const store::error& e) { 71 throw engine::error(e.what()); 72 } 73 } 74 75 76 } // anonymous namespace 77 78 79 /// Pure abstract destructor. 80 scan_action::base_hooks::~base_hooks(void) 81 { 82 } 83 84 85 /// Executes the operation. 86 /// 87 /// \param store_path The path to the database store. 88 /// \param action_id The identifier of the action to scan; if none, scans the 89 /// latest action in the store. 90 /// \param hooks The hooks for this execution. 91 /// 92 /// \returns A structure with all results computed by this driver. 93 scan_action::result 94 scan_action::drive(const fs::path& store_path, 95 optional< int64_t > action_id, 96 base_hooks& hooks) 97 { 98 store::backend db = store::backend::open_ro(store_path); 99 store::transaction tx = db.start(); 100 101 const engine::action action = get_action(tx, action_id); 102 hooks.got_action(action_id.get(), action); 103 104 store::results_iterator iter = tx.get_action_results(action_id.get()); 105 while (iter) { 106 hooks.got_result(iter); 107 ++iter; 108 } 109 110 return result(); 111 } 112