forked from joefreeman/dbdiff
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDbDiff.php
146 lines (109 loc) · 3.66 KB
/
DbDiff.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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;
}
}
?>