Chris@76: 'smf_db_backup_table', Chris@76: 'db_optimize_table' => 'smf_db_optimize_table', Chris@76: 'db_insert_sql' => 'smf_db_insert_sql', Chris@76: 'db_table_sql' => 'smf_db_table_sql', Chris@76: 'db_list_tables' => 'smf_db_list_tables', Chris@76: 'db_get_version' => 'smf_db_get_version', Chris@76: ); Chris@76: } Chris@76: Chris@76: // Backup $table to $backup_table. Chris@76: function smf_db_backup_table($table, $backup_table) Chris@76: { Chris@76: global $smcFunc, $db_prefix; Chris@76: Chris@76: $table = str_replace('{db_prefix}', $db_prefix, $table); Chris@76: Chris@76: // Do we need to drop it first? Chris@76: $tables = smf_db_list_tables(false, $backup_table); Chris@76: if (!empty($tables)) Chris@76: $smcFunc['db_query']('', ' Chris@76: DROP TABLE {raw:backup_table}', Chris@76: array( Chris@76: 'backup_table' => $backup_table, Chris@76: ) Chris@76: ); Chris@76: Chris@76: //!!! Should we create backups of sequences as well? Chris@76: $smcFunc['db_query']('', ' Chris@76: CREATE TABLE {raw:backup_table} Chris@76: ( Chris@76: LIKE {raw:table} Chris@76: INCLUDING DEFAULTS Chris@76: )', Chris@76: array( Chris@76: 'backup_table' => $backup_table, Chris@76: 'table' => $table, Chris@76: ) Chris@76: ); Chris@76: $smcFunc['db_query']('', ' Chris@76: INSERT INTO {raw:backup_table} Chris@76: SELECT * FROM {raw:table}', Chris@76: array( Chris@76: 'backup_table' => $backup_table, Chris@76: 'table' => $table, Chris@76: ) Chris@76: ); Chris@76: } Chris@76: Chris@76: // Optimize a table - return data freed! Chris@76: function smf_db_optimize_table($table) Chris@76: { Chris@76: global $smcFunc, $db_prefix; Chris@76: Chris@76: $table = str_replace('{db_prefix}', $db_prefix, $table); Chris@76: Chris@76: $request = $smcFunc['db_query']('', ' Chris@76: VACUUM ANALYZE {raw:table}', Chris@76: array( Chris@76: 'table' => $table, Chris@76: ) Chris@76: ); Chris@76: if (!$request) Chris@76: return -1; Chris@76: Chris@76: $row = $smcFunc['db_fetch_assoc']($request); Chris@76: $smcFunc['db_free_result']($request); Chris@76: Chris@76: if (isset($row['Data_free'])) Chris@76: return $row['Data_free'] / 1024; Chris@76: else Chris@76: return 0; Chris@76: } Chris@76: Chris@76: // List all the tables in the database. Chris@76: function smf_db_list_tables($db = false, $filter = false) Chris@76: { Chris@76: global $smcFunc; Chris@76: Chris@76: $request = $smcFunc['db_query']('', ' Chris@76: SELECT tablename Chris@76: FROM pg_tables Chris@76: WHERE schemaname = {string:schema_public}' . ($filter == false ? '' : ' Chris@76: AND tablename LIKE {string:filter}') . ' Chris@76: ORDER BY tablename', Chris@76: array( Chris@76: 'schema_public' => 'public', Chris@76: 'filter' => $filter, Chris@76: ) Chris@76: ); Chris@76: Chris@76: $tables = array(); Chris@76: while ($row = $smcFunc['db_fetch_row']($request)) Chris@76: $tables[] = $row[0]; Chris@76: $smcFunc['db_free_result']($request); Chris@76: Chris@76: return $tables; Chris@76: } Chris@76: Chris@76: // Get the content (INSERTs) for a table. Chris@76: function smf_db_insert_sql($tableName) Chris@76: { Chris@76: global $smcFunc, $db_prefix; Chris@76: Chris@76: $tableName = str_replace('{db_prefix}', $db_prefix, $tableName); Chris@76: Chris@76: // This will be handy... Chris@76: $crlf = "\r\n"; Chris@76: Chris@76: // Get everything from the table. Chris@76: $result = $smcFunc['db_query']('', ' Chris@76: SELECT * Chris@76: FROM {raw:table}', Chris@76: array( Chris@76: 'table' => $tableName, Chris@76: ) Chris@76: ); Chris@76: Chris@76: // The number of rows, just for record keeping and breaking INSERTs up. Chris@76: $num_rows = $smcFunc['db_num_rows']($result); Chris@76: Chris@76: if ($num_rows == 0) Chris@76: return ''; Chris@76: Chris@76: $fields = array_keys($smcFunc['db_fetch_assoc']($result)); Chris@76: $smcFunc['db_data_seek']($result, 0); Chris@76: Chris@76: // Start it off with the basic INSERT INTO. Chris@76: $data = ''; Chris@76: $insert_msg = $crlf . 'INSERT INTO ' . $tableName . $crlf . "\t" . '(' . implode(', ', $fields) . ')' . $crlf . 'VALUES ' . $crlf . "\t"; Chris@76: Chris@76: // Loop through each row. Chris@76: while ($row = $smcFunc['db_fetch_row']($result)) Chris@76: { Chris@76: // Get the fields in this row... Chris@76: $field_list = array(); Chris@76: for ($j = 0; $j < $smcFunc['db_num_fields']($result); $j++) Chris@76: { Chris@76: // Try to figure out the type of each field. (NULL, number, or 'string'.) Chris@76: if (!isset($row[$j])) Chris@76: $field_list[] = 'NULL'; Chris@76: elseif (is_numeric($row[$j]) && (int) $row[$j] == $row[$j]) Chris@76: $field_list[] = $row[$j]; Chris@76: else Chris@76: $field_list[] = '\'' . $smcFunc['db_escape_string']($row[$j]) . '\''; Chris@76: } Chris@76: Chris@76: // 'Insert' the data. Chris@76: $data .= $insert_msg . '(' . implode(', ', $field_list) . ');'; Chris@76: } Chris@76: $smcFunc['db_free_result']($result); Chris@76: Chris@76: // Return an empty string if there were no rows. Chris@76: return $num_rows == 0 ? '' : $data; Chris@76: } Chris@76: Chris@76: // Get the schema (CREATE) for a table. Chris@76: function smf_db_table_sql($tableName) Chris@76: { Chris@76: global $smcFunc, $db_prefix; Chris@76: Chris@76: $tableName = str_replace('{db_prefix}', $db_prefix, $tableName); Chris@76: Chris@76: // This will be needed... Chris@76: $crlf = "\r\n"; Chris@76: Chris@76: // Start the create table... Chris@76: $schema_create = 'CREATE TABLE ' . $tableName . ' (' . $crlf; Chris@76: $index_create = ''; Chris@76: $seq_create = ''; Chris@76: Chris@76: // Find all the fields. Chris@76: $result = $smcFunc['db_query']('', ' Chris@76: SELECT column_name, column_default, is_nullable, data_type, character_maximum_length Chris@76: FROM information_schema.columns Chris@76: WHERE table_name = {string:table} Chris@76: ORDER BY ordinal_position', Chris@76: array( Chris@76: 'table' => $tableName, Chris@76: ) Chris@76: ); Chris@76: while ($row = $smcFunc['db_fetch_assoc']($result)) Chris@76: { Chris@76: if ($row['data_type'] == 'character varying') Chris@76: $row['data_type'] = 'varchar'; Chris@76: elseif ($row['data_type'] == 'character') Chris@76: $row['data_type'] = 'char'; Chris@76: if ($row['character_maximum_length']) Chris@76: $row['data_type'] .= '(' . $row['character_maximum_length'] . ')'; Chris@76: Chris@76: // Make the CREATE for this column. Chris@76: $schema_create .= ' "' . $row['column_name'] . '" ' . $row['data_type'] . ($row['is_nullable'] != 'YES' ? ' NOT NULL' : ''); Chris@76: Chris@76: // Add a default...? Chris@76: if (trim($row['column_default']) != '') Chris@76: { Chris@76: $schema_create .= ' default ' . $row['column_default'] . ''; Chris@76: Chris@76: // Auto increment? Chris@76: if (preg_match('~nextval\(\'(.+?)\'(.+?)*\)~i', $row['column_default'], $matches) != 0) Chris@76: { Chris@76: // Get to find the next variable first! Chris@76: $count_req = $smcFunc['db_query']('', ' Chris@76: SELECT MAX("{raw:column}") Chris@76: FROM {raw:table}', Chris@76: array( Chris@76: 'column' => $row['column_name'], Chris@76: 'table' => $tableName, Chris@76: ) Chris@76: ); Chris@76: list ($max_ind) = $smcFunc['db_fetch_row']($count_req); Chris@76: $smcFunc['db_free_result']($count_req); Chris@76: // Get the right bloody start! Chris@76: $seq_create .= 'CREATE SEQUENCE ' . $matches[1] . ' START WITH ' . ($max_ind + 1) . ';' . $crlf . $crlf; Chris@76: } Chris@76: } Chris@76: Chris@76: $schema_create .= ',' . $crlf; Chris@76: } Chris@76: $smcFunc['db_free_result']($result); Chris@76: Chris@76: // Take off the last comma. Chris@76: $schema_create = substr($schema_create, 0, -strlen($crlf) - 1); Chris@76: Chris@76: $result = $smcFunc['db_query']('', ' Chris@76: SELECT CASE WHEN i.indisprimary THEN 1 ELSE 0 END AS is_primary, pg_get_indexdef(i.indexrelid) AS inddef Chris@76: FROM pg_class AS c Chris@76: INNER JOIN pg_index AS i ON (i.indrelid = c.oid) Chris@76: INNER JOIN pg_class AS c2 ON (c2.oid = i.indexrelid) Chris@76: WHERE c.relname = {string:table}', Chris@76: array( Chris@76: 'table' => $tableName, Chris@76: ) Chris@76: ); Chris@76: $indexes = array(); Chris@76: while ($row = $smcFunc['db_fetch_assoc']($result)) Chris@76: { Chris@76: if ($row['is_primary']) Chris@76: { Chris@76: if (preg_match('~\(([^\)]+?)\)~i', $row['inddef'], $matches) == 0) Chris@76: continue; Chris@76: Chris@76: $index_create .= $crlf . 'ALTER TABLE ' . $tableName . ' ADD PRIMARY KEY ("' . $matches[1] . '");'; Chris@76: } Chris@76: else Chris@76: $index_create .= $crlf . $row['inddef'] . ';'; Chris@76: } Chris@76: $smcFunc['db_free_result']($result); Chris@76: Chris@76: // Finish it off! Chris@76: $schema_create .= $crlf . ');'; Chris@76: Chris@76: return $seq_create . $schema_create . $index_create; Chris@76: } Chris@76: Chris@76: // Get the version number. Chris@76: function smf_db_get_version() Chris@76: { Chris@76: global $smcFunc; Chris@76: Chris@76: $request = $smcFunc['db_query']('', ' Chris@76: SHOW server_version', Chris@76: array( Chris@76: ) Chris@76: ); Chris@76: list ($ver) = $smcFunc['db_fetch_row']($request); Chris@76: $smcFunc['db_free_result']($request); Chris@76: Chris@76: return $ver; Chris@76: } Chris@76: Chris@76: ?>