summaryrefslogtreecommitdiffstats
path: root/DbDiff.php
diff options
context:
space:
mode:
authorJoe Freeman <joe.freeman@bitroot.com>2014-10-29 10:23:44 +0100
committerJoe Freeman <joe.freeman@bitroot.com>2014-10-29 10:23:44 +0100
commit14d6a4960ae34905a7a952480e735fc103777a25 (patch)
treedf74cdacd3c1119e31d67350db69d102695f2706 /DbDiff.php
parentcb3637ae1301aa7b364b886ddf6e9ee3e54d1b69 (diff)
downloaddbdiff-14d6a4960ae34905a7a952480e735fc103777a25.zip
dbdiff-14d6a4960ae34905a7a952480e735fc103777a25.tar.gz
dbdiff-14d6a4960ae34905a7a952480e735fc103777a25.tar.bz2
Initial import.
Diffstat (limited to 'DbDiff.php')
-rw-r--r--DbDiff.php146
1 files changed, 146 insertions, 0 deletions
diff --git a/DbDiff.php b/DbDiff.php
new file mode 100644
index 0000000..72e0d8e
--- /dev/null
+++ b/DbDiff.php
@@ -0,0 +1,146 @@
+<?php
+
+/**
+ * Compare the schemas of between databases.
+ *
+ * For two database schemas to be considered the same, they must have the same
+ * tables, where each table has the same fields, and each field has the same
+ * parameters.
+ *
+ * Field parameters that are compared are those that are given by the MySQL
+ * 'SHOW COLUMNS' command. These are: the field's name, it's type, whether the
+ * field can store null values, whether the column is indexed, the default
+ * values and whether the field was created with the 'auto_increment' keyword.
+ */
+class DbDiff {
+
+ /**
+ * Export the schema of the database into an array.
+ *
+ * @param string $config Config details for the database connection.
+ * @param string $name Name or description of the database.
+ * @return mixed|string An array structure of the exported schema, or an error string.
+ */
+ function export($config, $name) {
+
+ $db = @mysql_connect($config['host'], $config['user'],
+ $config['password']);
+
+ if (!$db) {
+ return null;
+ }
+
+ if (!mysql_select_db($config['name'], $db)) {
+ return null;
+ }
+
+ $result = mysql_query("SHOW TABLES");
+ while ($row = mysql_fetch_row($result)) {
+ $tables[$row[0]] = array();
+ }
+
+ foreach ($tables as $table_name => $fields) {
+
+ $result = mysql_query("SHOW COLUMNS FROM " . $table_name, $db);
+ while ($row = mysql_fetch_assoc($result)) {
+ $tables[$table_name][$row['Field']] = $row;
+ }
+ }
+
+ mysql_close();
+
+ $data = array(
+ 'name' => $name,
+ 'time' => time(),
+ 'tables' => $tables
+ );
+
+ return $data;
+ }
+
+ /**
+ * Compare two schemas (as generated by the 'export' method.)
+ *
+ * @param string $schema1 The first database schema.
+ * @param string $schema2 The second database schema.
+ * @return array The results of the comparison.
+ */
+ function compare($schema1, $schema2) {
+
+ $tables1 = array_keys($schema1['tables']);
+ $tables2 = array_keys($schema2['tables']);
+
+ $tables = array_unique(array_merge($tables1, $tables2));
+
+ $results = array();
+
+ foreach ($tables as $table_name) {
+
+ // Check tables exist in both databases
+
+ if (!isset($schema1['tables'][$table_name])) {
+
+ $results[$table_name][] = '<em>' . $schema1['name']
+ . '</em> is missing table: <code>' . $table_name
+ . '</code>.';
+
+ continue;
+ }
+
+ if (!isset($schema2['tables'][$table_name])) {
+
+ $results[$table_name][] = '<em>' . $schema2['name']
+ . '</em> is missing table: <code>' . $table_name
+ . '</code>.';
+
+ continue;
+ }
+
+ // Check fields exist in both tables
+
+ $fields = array_merge($schema1['tables'][$table_name],
+ $schema2['tables'][$table_name]);
+
+ foreach ($fields as $field_name => $field) {
+
+ if (!isset($schema1['tables'][$table_name][$field_name])) {
+
+ $results[$table_name][] = '<em>' . $schema1['name']
+ . '</em> is missing field: <code>' . $field_name
+ . '</code>';
+
+ continue;
+ }
+
+ if (!isset($schema2['tables'][$table_name][$field_name])) {
+
+ $results[$table_name][] = '<em>' . $schema2['name']
+ . '</em> is missing field: <code>' . $field_name
+ . '</code>';
+
+ continue;
+ }
+
+ // Check that the specific parameters of the fields match
+
+ $s1_params = $schema1['tables'][$table_name][$field_name];
+ $s2_params = $schema2['tables'][$table_name][$field_name];
+
+ foreach ($s1_params as $name => $details) {
+ if ($s1_params[$name] != $s2_params[$name]) {
+ $results[$table_name][] = 'Field <code>' . $field_name
+ . '</code> differs between databases for parameter \''
+ . $name . '\'. <em>' . $schema1['name']
+ . '</em> has \'' . $s1_params[$name]
+ . '\' and <em>' . $schema2['name']
+ . '</em> has \'' . $s2_params[$name] . '\'.';
+ }
+ }
+ }
+ }
+
+ return $results;
+ }
+}
+
+?>