/** * Merges the incoming structure definition with the existing structure. * * @return void * * @note Currently only supports XML format. * @since 13.1 * @throws RuntimeException on error. */ public function mergeStructure() { $prefix = $this->db->getPrefix(); $tables = $this->db->getTableList(); if ($this->from instanceof SimpleXMLElement) { $xml = $this->from; } else { $xml = new SimpleXMLElement($this->from); } // Get all the table definitions. $xmlTables = $xml->xpath('database/table_structure'); foreach ($xmlTables as $table) { // Convert the magic prefix into the real table name. $tableName = (string) $table['name']; $tableName = preg_replace('|^#__|', $prefix, $tableName); if (in_array($tableName, $tables)) { // The table already exists. Now check if there is any difference. if ($queries = $this->getAlterTableSql($xml->database->table_structure)) { // Run the queries to upgrade the data structure. foreach ($queries as $query) { $this->db->setQuery((string) $query); $this->db->execute(); } } } else { // This is a new table. $sql = $this->xmlToCreate($table); $this->db->setQuery((string) $sql); $this->db->execute(); } } }
/** * Get the columns from a database table. * * @param string Table name. If null current table is used * * @return mixed An array of the field names, or false if an error occurs. */ public function getTableFields($tableName = null) { static $cache = array(); static $tables = array(); // Make sure we have a list of tables in this db if (empty($tables)) { $tables = $this->_db->getTableList(); } if (!$tableName) { $tableName = $this->_tbl; } if (!array_key_exists($tableName, $cache)) { // Lookup the fields for this table only once. $name = $tableName; $prefix = $this->_db->getPrefix(); if (substr($name, 0, 3) == '#__') { $checkName = $prefix . substr($name, 3); } else { $checkName = $name; } if (!in_array($checkName, $tables)) { // The table doesn't exist. Return false. $cache[$tableName] = false; } elseif (version_compare(JVERSION, '3.0', 'ge')) { $fields = $this->_db->getTableColumns($name, false); if (empty($fields)) { $fields = false; } $cache[$tableName] = $fields; } else { $fields = $this->_db->getTableFields($name, false); if (!isset($fields[$name])) { $fields = false; } $cache[$tableName] = $fields[$name]; } } return $cache[$tableName]; }
/** * Method to delete all tables in a database with a given prefix. * * @param JDatabaseDriver $db JDatabaseDriver object. * @param string $prefix Database table prefix. * * @return boolean True on success. * * @since 3.1 */ public function deleteDatabase($db, $prefix) { $return = true; // Get the tables in the database. $tables = $db->getTableList(); if ($tables) { foreach ($tables as $table) { // If the table uses the given prefix, drop it. if (strpos($table, $prefix) === 0) { // Drop the table. try { $db->dropTable($table); } catch (RuntimeException $e) { JFactory::getApplication()->enqueueMessage(JText::sprintf('INSTL_DATABASE_ERROR_DELETE', $e->getMessage()), 'notice'); $return = false; } } } } return $return; }
/** * Get the columns from a database table. * * @param string $tableName Table name. If null current table is used * * @return mixed An array of the field names, or false if an error occurs. */ public function getTableFields($tableName = null) { // Should I load the cached data? $useCache = array_key_exists('use_table_cache', $this->config) ? $this->config['use_table_cache'] : false; // Make sure we have a list of tables in this db if (empty(self::$tableCache)) { if ($useCache) { // Try to load table cache from a cache file $cacheData = FOFPlatform::getInstance()->getCache('tables', null); // Unserialise the cached data, or set the table cache to empty // if the cache data wasn't loaded. if (!is_null($cacheData)) { self::$tableCache = json_decode($cacheData, true); } else { self::$tableCache = array(); } } // This check is true if the cache data doesn't exist / is not loaded if (empty(self::$tableCache)) { self::$tableCache = $this->_db->getTableList(); if ($useCache) { FOFPlatform::getInstance()->setCache('tables', json_encode(self::$tableCache)); } } } // Make sure the cached table fields cache is loaded if (empty(self::$tableFieldCache)) { if ($useCache) { // Try to load table cache from a cache file $cacheData = FOFPlatform::getInstance()->getCache('tablefields', null); // Unserialise the cached data, or set to empty if the cache // data wasn't loaded. if (!is_null($cacheData)) { $decoded = json_decode($cacheData, true); $tableCache = array(); if (count($decoded)) { foreach ($decoded as $myTableName => $tableFields) { $temp = array(); if (is_array($tableFields)) { foreach ($tableFields as $field => $def) { $temp[$field] = (object) $def; } $tableCache[$myTableName] = $temp; } elseif (is_object($tableFields) || is_bool($tableFields)) { $tableCache[$myTableName] = $tableFields; } } } self::$tableFieldCache = $tableCache; } else { self::$tableFieldCache = array(); } } } if (!$tableName) { $tableName = $this->_tbl; } // Try to load again column specifications if the table is not loaded OR if it's loaded and // the previous call returned an error if (!array_key_exists($tableName, self::$tableFieldCache) || isset(self::$tableFieldCache[$tableName]) && !self::$tableFieldCache[$tableName]) { // Lookup the fields for this table only once. $name = $tableName; $prefix = $this->_db->getPrefix(); if (substr($name, 0, 3) == '#__') { $checkName = $prefix . substr($name, 3); } else { $checkName = $name; } if (!in_array($checkName, self::$tableCache)) { // The table doesn't exist. Return false. self::$tableFieldCache[$tableName] = false; } elseif (version_compare(JVERSION, '3.0', 'ge')) { $fields = $this->_db->getTableColumns($name, false); if (empty($fields)) { $fields = false; } self::$tableFieldCache[$tableName] = $fields; } else { $fields = $this->_db->getTableFields($name, false); if (!isset($fields[$name])) { $fields = false; } self::$tableFieldCache[$tableName] = $fields[$name]; } // PostgreSQL date type compatibility if ($this->_db->name == 'postgresql' && self::$tableFieldCache[$tableName] != false) { foreach (self::$tableFieldCache[$tableName] as $field) { if (strtolower($field->type) == 'timestamp without time zone') { if (stristr($field->Default, '\'::timestamp without time zone')) { list($date, $junk) = explode('::', $field->Default, 2); $field->Default = trim($date, "'"); } } } } // Save the data for this table into the cache if ($useCache) { $cacheData = FOFPlatform::getInstance()->setCache('tablefields', json_encode(self::$tableFieldCache)); } } return self::$tableFieldCache[$tableName]; }
/** * Method to delete all tables in a database with a given prefix. * * @param JDatabaseDriver $db JDatabaseDriver object. * @param string $name Name of the database to process. * @param string $prefix Database table prefix. * * @return boolean True on success. * * @since 3.0 */ public function deleteDatabase($db, $name, $prefix) { $return = true; // Get the tables in the database. $tables = $db->getTableList(); if ($tables) { foreach ($tables as $table) { // If the table uses the given prefix, drop it. if (strpos($table, $prefix) === 0) { // Drop the table. try { $db->dropTable($table); } catch (RuntimeException $e) { $this->setError($e->getMessage()); $return = false; } } } } return $return; }