~danieru-dressler/gsoc2011danieldressler/sqllayer

3 by Daniel Dressler
working on initial import path, not generalized yet, no sql let either
1
package sqlLayer;
2
2 by Daniel Dressler
printer phonebook extended to define relationship of perl data structure to database schema
3
use strict;
4
use warnings;
5 by Daniel Dressler
Got a the code path to import the printer database done. Next is generalizing and supporting more tables
5
use Data::Dumper;
2 by Daniel Dressler
printer phonebook extended to define relationship of perl data structure to database schema
6
7
use DBI;
8
use phonebook;
9
10
11
sub new( $ $ $ ) {
12
	my ($class, $dbHandle, $dbType, $version) = @_;
13
	my $this = {};
14
	bless $this, $class;
15
	
5 by Daniel Dressler
Got a the code path to import the printer database done. Next is generalizing and supporting more tables
16
	$this->{'dbh'} = $dbHandle;
2 by Daniel Dressler
printer phonebook extended to define relationship of perl data structure to database schema
17
	
18
	$this->{'type'} = $dbType;
19
	
20
	
21
	#default to 0, perfect compatablity with C primary xml parsing
22
	# 1 = compatibility of C combo parsing
23
	# 2 = multilingual support and printers_byname in drivers
24
	$this->{'version'} = 0;
25
	$this->{'version'} = $version if(defined($version));
26
	
27
	my $phonebook = phonebook->new($this->{'version'});
28
	$this->{'printerPhonebook'} = $phonebook->printer();
29
	$this->{'driverPhonebook'}  = $phonebook->driver();
30
	$this->{'optionPhonebook'}  = $phonebook->option();
4 by Daniel Dressler
Stumped, I have to find a general way of expanding complex phonebook entries such as languages into multiple table keys.
31
	$this->{'schemaPhonebook'}  = $phonebook->schema();
2 by Daniel Dressler
printer phonebook extended to define relationship of perl data structure to database schema
32
	
33
	
34
	return $this;
35
}
36
7 by Daniel Dressler
added support for the tables options and options_translation
37
#TODO: Move this and the version in xmlParse to a helper lib
38
sub getCleanId {
39
	my ($id) = @_;
40
	$id =~ s/^[^\/]*\///;
41
	#remove everything before the leading slash
42
	return $id;
43
}
44
3 by Daniel Dressler
working on initial import path, not generalized yet, no sql let either
45
sub getSchema {
46
	my ($this, $table) = @_;
4 by Daniel Dressler
Stumped, I have to find a general way of expanding complex phonebook entries such as languages into multiple table keys.
47
	
48
	return $this->{'schemaPhonebook'}{$table};
49
}
50
51
sub initDatabase {
5 by Daniel Dressler
Got a the code path to import the printer database done. Next is generalizing and supporting more tables
52
	my ($this) = @_;
4 by Daniel Dressler
Stumped, I have to find a general way of expanding complex phonebook entries such as languages into multiple table keys.
53
	
6 by Daniel Dressler
support for printer_translation table.
54
	#Create the Tables
4 by Daniel Dressler
Stumped, I have to find a general way of expanding complex phonebook entries such as languages into multiple table keys.
55
	foreach my $table (keys %{$this->{'schemaPhonebook'}}) {
56
		my $schema = $this->getSchema($table);
57
		my $sth = $this->{'dbh'}->prepare($schema);
58
		
59
		$sth->execute();
60
	}
61
	$this->{'dbh'}->commit();
3 by Daniel Dressler
working on initial import path, not generalized yet, no sql let either
62
}
63
5 by Daniel Dressler
Got a the code path to import the printer database done. Next is generalizing and supporting more tables
64
sub getSortedKeys {
65
	my ($this, $data) = @_;
66
	
67
	my @keys;
68
	foreach my $key (keys %{$data}) {
69
		push(@keys, $key);
70
	}
71
	
72
	@keys = sort(@keys);
73
	
74
	#create a string that sums the contents of @keys, this allows us to identify 
75
	#similar sets of keys
76
	my $sumString;
77
	foreach my $key (@keys) {
78
		$sumString .= $key;
79
	}
80
	
81
	return (\@keys, $sumString);
82
}
83
3 by Daniel Dressler
working on initial import path, not generalized yet, no sql let either
84
sub getPreparedStatement {
5 by Daniel Dressler
Got a the code path to import the printer database done. Next is generalizing and supporting more tables
85
	my ($this, $wantedTable, $data) = @_;
3 by Daniel Dressler
working on initial import path, not generalized yet, no sql let either
86
5 by Daniel Dressler
Got a the code path to import the printer database done. Next is generalizing and supporting more tables
87
	my ($sortedKeys, $summedKeys) = $this->getSortedKeys($data);
88
	
4 by Daniel Dressler
Stumped, I have to find a general way of expanding complex phonebook entries such as languages into multiple table keys.
89
	#use cached copy if present
6 by Daniel Dressler
support for printer_translation table.
90
	if (defined($this->{'cache'}{'preparedStatements'}{$wantedTable}{$summedKeys})) {
91
		return $this->{'cache'}{'preparedStatements'}{$wantedTable}{$summedKeys};
4 by Daniel Dressler
Stumped, I have to find a general way of expanding complex phonebook entries such as languages into multiple table keys.
92
	}
93
	
94
	#Create the SQL
95
	my $statementBegining = "INSERT INTO ".$wantedTable."(";
96
	
5 by Daniel Dressler
Got a the code path to import the printer database done. Next is generalizing and supporting more tables
97
	my $tableKeys = join(",", @{$sortedKeys});
4 by Daniel Dressler
Stumped, I have to find a general way of expanding complex phonebook entries such as languages into multiple table keys.
98
	
99
	my $statementMiddle = ") VALUES (";
100
	
101
	my $bindValues;
5 by Daniel Dressler
Got a the code path to import the printer database done. Next is generalizing and supporting more tables
102
	for(my $i = 0; $i < @{$sortedKeys}; $i++) {
4 by Daniel Dressler
Stumped, I have to find a general way of expanding complex phonebook entries such as languages into multiple table keys.
103
		$bindValues .= ',' if ($i > 0);
104
		$bindValues .= '?';
105
	}
106
	
5 by Daniel Dressler
Got a the code path to import the printer database done. Next is generalizing and supporting more tables
107
	my $statementEnd = ");";
4 by Daniel Dressler
Stumped, I have to find a general way of expanding complex phonebook entries such as languages into multiple table keys.
108
	
109
	my $statementSql = $statementBegining . $tableKeys . 
110
	                      $statementMiddle . $bindValues . $statementEnd;
111
	
112
	my $sth = $this->{'dbh'}->prepare($statementSql);
113
	
114
	#add the sth to our cache
6 by Daniel Dressler
support for printer_translation table.
115
	$this->{'cache'}{'preparedStatements'}{$wantedTable}{$summedKeys} = $sth;
4 by Daniel Dressler
Stumped, I have to find a general way of expanding complex phonebook entries such as languages into multiple table keys.
116
	
117
	return $sth;
3 by Daniel Dressler
working on initial import path, not generalized yet, no sql let either
118
}
119
7 by Daniel Dressler
added support for the tables options and options_translation
120
sub setPreparedData {
121
	my ($this, $data, $phonebook) = @_;
2 by Daniel Dressler
printer phonebook extended to define relationship of perl data structure to database schema
122
	
7 by Daniel Dressler
added support for the tables options and options_translation
123
	#compute the namespace from the phonebook
124
	my $nodePath = $phonebook->[0][0];#the nodepath of the first element
125
	$nodePath =~ m!^/([^/]*)/!;
126
	my $namespace = $1;
127
		
3 by Daniel Dressler
working on initial import path, not generalized yet, no sql let either
128
	#We sort the data by table and rename if needed.
7 by Daniel Dressler
added support for the tables options and options_translation
129
	foreach my $element (@{$phonebook}) {
3 by Daniel Dressler
working on initial import path, not generalized yet, no sql let either
130
		my ($ignore, $source, $mainGroup, $table, $destination, $minorGroup) = @{$element};
131
		$destination = $source if (!$destination);
132
		
6 by Daniel Dressler
support for printer_translation table.
133
		#Only sort if the table is defined and if the destination key has not 
134
		#been set, does not work for complex types 
7 by Daniel Dressler
added support for the tables options and options_translation
135
		if($table && !exists $data->{'prepared'}{$table}{$destination}) {
136
			
137
			if($minorGroup == 4) {
138
				if($namespace eq 'option') {
139
					$data->{'prepared'}{$table}{$destination} = getCleanId($data->{$source});
140
				}
141
			
142
			} elsif($minorGroup == 7) {#multilingual comments
143
				foreach my $lang (keys %{$data->{$source}}) {
144
					if($namespace eq 'printer') {
145
						my %preparedComment;
146
						$preparedComment{'id'} = $data->{'id'};
147
						$preparedComment{'lang'} = $lang;
148
						$preparedComment{'comments'} = $data->{'comments'}{$lang};
149
						push(@{$data->{'prepared'}{$table}{$destination}}, \%preparedComment);
150
					} elsif ($namespace eq 'option') {
151
						my %preparedComment;
152
						$preparedComment{'id'} = getCleanId($data->{'idx'});
153
						$preparedComment{'lang'} = $lang;
154
						$preparedComment{'longname'} = $data->{'comments'}{$lang};
155
						push(@{$data->{'prepared'}{$table}{$destination}}, \%preparedComment);
156
					}
157
				}
158
				
6 by Daniel Dressler
support for printer_translation table.
159
			} elsif($mainGroup == 13) { #Languages
7 by Daniel Dressler
added support for the tables options and options_translation
160
				if($namespace eq 'printer') {
161
					# A complex data key must not be undef
162
					# since there is no direct key in the table for it
163
					next() if !defined($data->{$source});
5 by Daniel Dressler
Got a the code path to import the printer database done. Next is generalizing and supporting more tables
164
					
7 by Daniel Dressler
added support for the tables options and options_translation
165
					foreach my $lang (@{$data->{$source}}) {
166
						my $name = $lang->{'name'};
167
						$data->{'prepared'}{$table}{$name}  = 1;
168
						
169
						if(defined($lang->{'level'}) && !($name eq 'proprietary') ) {
170
							$data->{'prepared'}{$table}{$name.'_level'} = $lang->{'level'};
171
						}
3 by Daniel Dressler
working on initial import path, not generalized yet, no sql let either
172
					}
173
				}
7 by Daniel Dressler
added support for the tables options and options_translation
174
			} elsif( defined($data->{$source})) {
175
				$data->{'prepared'}{$table}{$destination} = $data->{$source};
3 by Daniel Dressler
working on initial import path, not generalized yet, no sql let either
176
			}
177
		}
178
	}
2 by Daniel Dressler
printer phonebook extended to define relationship of perl data structure to database schema
179
}
180
7 by Daniel Dressler
added support for the tables options and options_translation
181
sub insertData {
6 by Daniel Dressler
support for printer_translation table.
182
	my ($this, $data, $table) = @_;
183
	
184
	my $sth = $this->getPreparedStatement($table, $data);
185
	
186
	#Sort data alphabetically, required for prepared statements
187
	my ($sortedKeys) = $this->getSortedKeys($data);
5 by Daniel Dressler
Got a the code path to import the printer database done. Next is generalizing and supporting more tables
188
	my @sortedData;
189
	foreach my $key (@{$sortedKeys}) {
6 by Daniel Dressler
support for printer_translation table.
190
		push(@sortedData, $data->{$key});
5 by Daniel Dressler
Got a the code path to import the printer database done. Next is generalizing and supporting more tables
191
	}
192
	
193
	
194
	if( !$sth->execute(@sortedData) ) {
195
		
6 by Daniel Dressler
support for printer_translation table.
196
		print Dumper($data);
197
		die $this->{'dbh'}->errstr . "\n------\n";
5 by Daniel Dressler
Got a the code path to import the printer database done. Next is generalizing and supporting more tables
198
		
199
	}
3 by Daniel Dressler
working on initial import path, not generalized yet, no sql let either
200
}
2 by Daniel Dressler
printer phonebook extended to define relationship of perl data structure to database schema
201
7 by Daniel Dressler
added support for the tables options and options_translation
202
sub insertTranslationData {
203
	my ($this, $data, $table) = @_;
204
	foreach my $comment (@{ $data->{'prepared'}{$table}{'comments'} }) {
205
		$this->insertData($comment, $table);
206
	}
207
}
208
209
sub pushOption {
210
	my ($this, $option) = @_;
211
	$this->setPreparedData($option, $this->{'optionPhonebook'});
212
	
213
	$this->insertData($option->{'prepared'}{'options'},'options');
214
	$this->insertTranslationData($option, 'options_translation');
215
	
216
	$this->{'dbh'}->commit;
217
}
218
219
sub pushPrinter {
220
	my ($this, $printer) = @_;
221
	
222
	$this->setPreparedData($printer, $this->{'printerPhonebook'});
223
	
224
	$this->insertData($printer->{'prepared'}{'printer'},'printer');
225
	$this->insertTranslationData($printer, 'printer_translation');
226
	
227
	$this->{'dbh'}->commit;
228
}
229
2 by Daniel Dressler
printer phonebook extended to define relationship of perl data structure to database schema
230
1;