1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Generic temptables object store 19 * 20 * Provides support to databases lacking some "expected behaviour" related 21 * with some operations with temporary tables like: 22 * 23 * - databases not retrieving temp tables from information schema tables (mysql) 24 * - databases using a different name schema for temp tables (like mssql). 25 * - databases that don't collect planner stats for temp tables (like PgSQL). 26 * 27 * Basically it works as a simple store of created temporary tables, providing 28 * some simple getters/setters methods. Each database can extend it for its own 29 * purposes (for example, return correct name, see the mssql implementation) 30 * 31 * The unique instance of the object by database connection is shared by the database 32 * and the sql_generator, so both are able to use its facilities, with the final goal 33 * of doing temporary tables support 100% cross-db and transparent within the DB API. 34 * 35 * @package core_dml 36 * @copyright 2009 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 40 defined('MOODLE_INTERNAL') || die(); 41 42 class moodle_temptables { 43 44 /** @var circular reference, to be able to use DB facilities here if needed */ 45 protected $mdb; 46 /** @var prefix to be used for all the DB objects */ 47 protected $prefix; 48 /** @var simple array of moodle, not prefixed 'tablename' => DB, final (prefixed) 'tablename' */ 49 protected $temptables; 50 51 /** 52 * Creates new moodle_temptables instance 53 * @param moodle_database $mdb An instance of moodle_database. 54 */ 55 public function __construct($mdb) { 56 $this->mdb = $mdb; 57 $this->prefix = $mdb->get_prefix(); 58 $this->temptables = array(); 59 } 60 61 /** 62 * Add one temptable to the store 63 * 64 * Given one moodle temptable name (without prefix), add it to the store, with the 65 * key being the original moodle name and the value being the real db temptable name 66 * already prefixed 67 * 68 * Override and use this *only* if the database requires modification in the table name. 69 * 70 * @param string $tablename name without prefix of the table created as temptable 71 */ 72 public function add_temptable($tablename) { 73 // TODO: throw exception if exists: if ($this->is_temptable... 74 $this->temptables[$tablename] = $tablename; 75 } 76 77 /** 78 * Delete one temptable from the store 79 * 80 * @param string $tablename name without prefix of the dropped temptable 81 */ 82 public function delete_temptable($tablename) { 83 // TODO: throw exception if not exists: if (!$this->is_temptable.... 84 unset($this->temptables[$tablename]); 85 } 86 87 /** 88 * Returns all the tablenames (without prefix) existing in the store 89 * 90 * @return array containing all the tablenames in the store (tablename both key and value) 91 */ 92 public function get_temptables() { 93 return $this->temptables; 94 } 95 96 /** 97 * Returns if one table, based in the information present in the store, is a temp table 98 * 99 * @param string $tablename name without prefix of the table we are asking about 100 * @return bool true if the table is a temp table (based in the store info), false if not 101 */ 102 public function is_temptable($tablename) { 103 return !empty($this->temptables[$tablename]); 104 } 105 106 /** 107 * Given one tablename (no prefix), return the name of the corresponding temporary table, 108 * If the table isn't a "registered" temp table, returns null 109 * 110 * @param string $tablename name without prefix which corresponding temp tablename needs to know 111 * @return mixed DB name of the temp table or null if it isn't a temp table 112 */ 113 public function get_correct_name($tablename) { 114 if ($this->is_temptable($tablename)) { 115 return $this->temptables[$tablename]; 116 } 117 return null; 118 } 119 120 /** 121 * Analyze the data in temporary tables to force statistics collection after bulk data loads. 122 * The database class detects all temporary tables and will automatically analyze all created tables 123 * 124 * @return void 125 */ 126 public function update_stats() { 127 // By default most databases do automatic on temporary tables, PgSQL does not. 128 // As a result, update_stats call immediately return for non-interesting database types. 129 } 130 131 /** 132 * Dispose the temptables stuff, checking for wrong situations, informing and recovering from them 133 */ 134 public function dispose() { 135 // We shouldn't have any temp table registered at the end of the script. 136 // So we error_log that and, at the same time, drop all the pending temptables 137 if ($temptables = $this->get_temptables()) { 138 error_log('Potential coding error - existing temptables found when disposing database. Must be dropped!'); 139 foreach ($temptables as $temptable) { 140 $this->mdb->get_manager()->drop_table(new xmldb_table($temptable)); 141 } 142 } 143 $this->mdb = null; 144 } 145 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body