~drizzle-trunk/drizzle/development

0.67.612 by eve
a foundation for a new simplification framework
1
#
2
# This program is free software; you can redistribute it and/or modify
3
# it under the terms of the GNU General Public License as published by
4
# the Free Software Foundation; version 2 of the License.
5
#
6
# This program is distributed in the hope that it will be useful, but
7
# WITHOUT ANY WARRANTY; without even the implied warranty of
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9
# General Public License for more details.
10
#
11
# You should have received a copy of the GNU General Public License
12
# along with this program; if not, write to the Free Software
13
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
14
# USA
15
#
16
0.67.617 by eve
misc improvements to the Simpipe framework
17
package GenTest::SimPipe::DBObject;
0.67.612 by eve
a foundation for a new simplification framework
18
19
require Exporter;
20
@ISA = qw(GenTest);
0.67.617 by eve
misc improvements to the Simpipe framework
21
@EXPORT = qw(COLUMN_NAME COLUMN_TYPE COLUMN_COLLATION KEY_COLUMN DBOBJECT_NAME DBOBJECT_ENGINE);
0.67.612 by eve
a foundation for a new simplification framework
22
23
use strict;
24
use DBI;
25
use GenTest;
26
27
28
use constant DBOBJECT_NAME	=> 0;
29
use constant DBOBJECT_COLUMNS	=> 1;
30
use constant DBOBJECT_KEYS	=> 2;
31
use constant DBOBJECT_DATA	=> 3;
32
use constant DBOBJECT_ENGINE	=> 4;
33
34
use constant COLUMN_NAME		=> 0;
35
use constant COLUMN_ORIG_NAME		=> 1;
36
use constant COLUMN_DEFAULT		=> 2;
37
use constant COLUMN_IS_NULLABLE		=> 3;
38
use constant COLUMN_TYPE		=> 4;
39
use constant COLUMN_COLLATION		=> 5;
40
41
use constant KEY_NAME	=> 0;
42
use constant KEY_COLUMN	=> 1;
43
44
my $dbname = 'test';
45
46
47
sub new {
48
	my $class = shift;
49
50
	my $dbobject = $class->SUPER::new({
51
		'name'		=> DBOBJECT_NAME,
52
		'columns'	=> DBOBJECT_COLUMNS,
53
		'keys'		=> DBOBJECT_KEYS,
54
		'data'		=> DBOBJECT_DATA,
55
		'engine'	=> DBOBJECT_ENGINE
56
	}, @_);
57
	
58
	return $dbobject;
59
}
60
61
sub newFromDSN {
0.67.655 by eve
misc fixes to the Simpipe simplification framework
62
	my ($class, $dsn, $table_name) = @_;
0.67.612 by eve
a foundation for a new simplification framework
63
64
	my $dbh = DBI->connect($dsn);
0.67.655 by eve
misc fixes to the Simpipe simplification framework
65
66
	return $class->newFromDBH($dbh, $table_name);
67
}
68
69
sub newFromDBH {
70
	my ($class, $dbh, $table_name) = @_;
0.67.612 by eve
a foundation for a new simplification framework
71
	
72
	my $table_info = $dbh->selectrow_hashref("
73
		SELECT * FROM INFORMATION_SCHEMA.TABLES
74
		WHERE TABLE_NAME = ?
75
		AND TABLE_SCHEMA = ?
76
	", undef, $table_name, $dbname);
77
78
	my $engine = $table_info->{ENGINE};
79
80
	my @columns;
81
	my $sth_columns = $dbh->prepare("
82
		SELECT * FROM INFORMATION_SCHEMA.COLUMNS
83
		WHERE TABLE_NAME = ?
84
		AND TABLE_SCHEMA = ?
85
	");
86
	$sth_columns->execute($table_name, $dbname);
87
88
	while (my $column_info = $sth_columns->fetchrow_hashref()) {
89
		my $new_column;
90
		$new_column->[COLUMN_NAME] = $new_column->[COLUMN_ORIG_NAME] = $column_info->{'COLUMN_NAME'};
91
		$new_column->[COLUMN_DEFAULT] = $column_info->{'COLUMN_DEFAULT'};
92
		$new_column->[COLUMN_IS_NULLABLE] = $column_info->{'COLUMN_IS_NULLABLE'};
93
		$new_column->[COLUMN_TYPE] = $column_info->{'COLUMN_TYPE'};
94
		$new_column->[COLUMN_COLLATION] = $column_info->{'COLLATION_NAME'};
95
		push @columns, $new_column;
96
	}
97
98
	my @keys;
99
	my $sth_keys = $dbh->prepare("
100
		SELECT * FROM INFORMATION_SCHEMA.STATISTICS
101
		WHERE TABLE_NAME = ?
102
		AND TABLE_SCHEMA = ?
103
	");
104
	$sth_keys->execute($table_name, $dbname);
105
106
	while (my $key_info = $sth_keys->fetchrow_hashref()) {
107
		my $new_key;
108
		$new_key->[KEY_NAME] = $key_info->{'INDEX_NAME'};
109
		$new_key->[KEY_COLUMN] = $key_info->{'COLUMN_NAME'};
110
		push @keys, $new_key;
111
	}
112
113
	my @data;
114
	my $sth_data = $dbh->prepare("SELECT * FROM `$dbname`.`$table_name`");
115
	$sth_data->execute();
116
	while (my $row = $sth_data->fetchrow_hashref()) {
117
		push @data, $row;
118
	}
119
0.67.617 by eve
misc improvements to the Simpipe framework
120
	my $dbobject = GenTest::SimPipe::DBObject->new(
0.67.612 by eve
a foundation for a new simplification framework
121
		name	=> $table_name,
122
		engine	=> $engine,
123
		columns	=> \@columns,
124
		keys	=> \@keys,
125
		data	=> \@data
126
	);
127
}
128
129
sub toString {
130
	my $dbobject = shift;
131
132
	my @column_strings;
133
	foreach my $column (@{$dbobject->columns()}) {
134
		next if not defined $column;
0.67.617 by eve
misc improvements to the Simpipe framework
135
		next if not defined $column->[COLUMN_NAME];
136
0.67.612 by eve
a foundation for a new simplification framework
137
		my $column_string = $column->[COLUMN_NAME]." ".$column->[COLUMN_TYPE];
138
		$column_string .= " COLLATE ".$column->[COLUMN_COLLATION] if defined $column->[COLUMN_COLLATION];
139
		push @column_strings, $column_string;
140
	}
141
0.67.617 by eve
misc improvements to the Simpipe framework
142
	return "" if ($#column_strings == -1);
143
0.67.612 by eve
a foundation for a new simplification framework
144
	foreach my $key (@{$dbobject->keys()}) {
145
		next if not defined $key;
0.67.617 by eve
misc improvements to the Simpipe framework
146
		my $underlying_column_exists = 0;
147
		foreach my $column (@{$dbobject->columns()}) {
148
			$underlying_column_exists = 1 if $column->[COLUMN_NAME] eq $key->[KEY_COLUMN];
149
		}
150
		next if !$underlying_column_exists;
0.67.612 by eve
a foundation for a new simplification framework
151
		if ($key->[KEY_NAME] eq 'PRIMARY') {
152
			push @column_strings, "PRIMARY KEY (".$key->[KEY_COLUMN].")";
153
		} else {
154
			push @column_strings, "KEY (".$key->[KEY_COLUMN].")";
155
		}
156
	}
157
158
	my $create_string = "DROP TABLE IF EXISTS ".$dbobject->name().";\n";
0.67.655 by eve
misc fixes to the Simpipe simplification framework
159
	$create_string .= "CREATE TABLE ".$dbobject->name()." ( ".join(", ", @column_strings).") ";
0.67.617 by eve
misc improvements to the Simpipe framework
160
	$create_string .= " ENGINE=".$dbobject->engine() if defined $dbobject->engine();
161
	$create_string .= " TRANSACTIONAL=0 " if $dbobject->engine() =~ m{Aria}sio;
162
	$create_string .= ";\n";
0.67.612 by eve
a foundation for a new simplification framework
163
0.67.617 by eve
misc improvements to the Simpipe framework
164
	my @rows_data;
0.67.612 by eve
a foundation for a new simplification framework
165
166
	foreach my $row_id (0..$#{$dbobject->[DBOBJECT_DATA]}) {
167
		next if not defined $dbobject->[DBOBJECT_DATA]->[$row_id];
168
		my @row_data;
169
		foreach my $column (@{$dbobject->columns()}) {
0.67.617 by eve
misc improvements to the Simpipe framework
170
			next if not defined $column;
171
			next if not defined $column->[COLUMN_NAME];
0.67.612 by eve
a foundation for a new simplification framework
172
			my $cell = $dbobject->[DBOBJECT_DATA]->[$row_id]->{$column->[COLUMN_NAME]} || $dbobject->[DBOBJECT_DATA]->[$row_id]->{$column->[COLUMN_ORIG_NAME]};
0.67.617 by eve
misc improvements to the Simpipe framework
173
			$cell =~ s{'}{\\'}sgio;
0.67.612 by eve
a foundation for a new simplification framework
174
			push @row_data, defined $cell ? "'".$cell."'" : 'NULL';
175
		}
0.67.617 by eve
misc improvements to the Simpipe framework
176
		push @rows_data, "(".join(',', @row_data).")";
0.67.612 by eve
a foundation for a new simplification framework
177
	}
178
0.67.655 by eve
misc fixes to the Simpipe simplification framework
179
	print "Object ".$dbobject->name()." has ".($#rows_data + 1)." rows\n";
180
181
#	my $data_string = "ALTER TABLE ".$dbobject->name()." DISABLE KEYS;\n";
182
	my $data_string .= "INSERT IGNORE INTO ".$dbobject->name()." VALUES ".join(',', @rows_data).";\n" if $#rows_data > -1;
183
#	$data_string .= "ALTER TABLE ".$dbobject->name()." ENABLE KEYS;\n";
0.67.617 by eve
misc improvements to the Simpipe framework
184
0.67.612 by eve
a foundation for a new simplification framework
185
	return $create_string.$data_string;
186
	
187
}
188
189
sub name {
190
	return $_[0]->[DBOBJECT_NAME];
191
}
192
193
sub columns {
194
	return $_[0]->[DBOBJECT_COLUMNS];
195
}
196
197
sub keys {
198
	return $_[0]->[DBOBJECT_KEYS];
199
}
200
201
sub data {
202
	return $_[0]->[DBOBJECT_DATA];
203
}
204
205
sub engine {
206
	return $_[0]->[DBOBJECT_ENGINE];
207
}
208
209
1;