source: main/trunk/greenstone2/perllib/dbutil.pm@ 29794

Last change on this file since 29794 was 23485, checked in by davidb, 13 years ago

read_infodb_entry now returns a hashmap directly. Code updated to take advantage of this, and in places where the hashmap is not needed, the alternative read_infodb_rawentry is called.

File size: 13.3 KB
RevLine 
[15699]1###########################################################################
2#
[21411]3# dbutil.pm -- gateway to utilities for reading/writing to different databases
[15699]4# Copyright (C) 2008 DL Consulting Ltd
5#
6# A component of the Greenstone digital library software
7# from the New Zealand Digital Library Project at the
8# University of Waikato, New Zealand.
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23#
24###########################################################################
25
26package dbutil;
27
28use strict;
29
30
[17087]31sub open_infodb_write_handle
32{
[17476]33 my $infodb_type = shift(@_);
34 my $infodb_file_path = shift(@_);
35
36 if ($infodb_type eq "sqlite")
37 {
[21544]38 require dbutil::sqlite;
[21546]39 return &dbutil::sqlite::open_infodb_write_handle($infodb_file_path, @_);
[17476]40 }
41 elsif ($infodb_type eq "gdbm-txtgz")
42 {
[21544]43 require dbutil::gdbmtxtgz;
[21546]44 return &dbutil::gdbmtxtgz::open_infodb_write_handle($infodb_file_path, @_);
[17476]45 }
[21411]46 elsif ($infodb_type eq "jdbm")
47 {
[21544]48 require dbutil::jdbm;
[21546]49 return &dbutil::jdbm::open_infodb_write_handle($infodb_file_path, @_);
[21411]50 }
[17476]51 elsif ($infodb_type eq "mssql")
52 {
[21544]53 require dbutil::mssql;
[21546]54 return &dbutil::mssql::open_infodb_write_handle($infodb_file_path, @_);
[17476]55 }
[17087]56
[17476]57 # Use GDBM if the infodb type is empty or not one of the values above
[21544]58 require dbutil::gdbm;
[21546]59 return &dbutil::gdbm::open_infodb_write_handle($infodb_file_path, @_);
[17087]60}
61
62
[16176]63sub close_infodb_write_handle
64{
[17476]65 my $infodb_type = shift(@_);
66 my $infodb_handle = shift(@_);
[16176]67
[17476]68 if ($infodb_type eq "sqlite")
69 {
[21544]70 require dbutil::sqlite;
[21546]71 return &dbutil::sqlite::close_infodb_write_handle($infodb_handle, @_);
[17476]72 }
73 elsif ($infodb_type eq "gdbm-txtgz")
74 {
[21544]75 require dbutil::gdbmtxtgz;
[21546]76 return &dbutil::gdbmtxtgz::close_infodb_write_handle($infodb_handle, @_);
[17476]77 }
[21411]78 elsif ($infodb_type eq "jdbm")
79 {
[21544]80 require dbutil::jdbm;
[21546]81 return &dbutil::jdbm::close_infodb_write_handle($infodb_handle, @_);
[21411]82 }
[17476]83 elsif ($infodb_type eq "mssql")
84 {
[21544]85 require dbutil::mssql;
[21546]86 return &dbutil::mssql::close_infodb_write_handle($infodb_handle, @_);
[17476]87 }
88
89 # Use GDBM if the infodb type is empty or not one of the values above
[21544]90 require dbutil::gdbm;
[21546]91 return &dbutil::gdbm::close_infodb_write_handle($infodb_handle, @_);
[17104]92}
[16176]93
94
[15727]95sub get_default_infodb_type
96{
[17476]97 # The default is GDBM so everything works the same for existing collections
98 # To use something else, specify the "infodbtype" in the collection's collect.cfg file
99 return "gdbm";
[15727]100}
101
102
[15710]103sub get_infodb_file_path
104{
[17476]105 my $infodb_type = shift(@_);
106 my $collection_name = shift(@_);
107 my $infodb_directory_path = shift(@_);
[15710]108
[17476]109 if ($infodb_type eq "sqlite")
110 {
[21544]111 require dbutil::sqlite;
[21546]112 return &dbutil::sqlite::get_infodb_file_path($collection_name, $infodb_directory_path, @_);
[17476]113 }
114 elsif ($infodb_type eq "gdbm-txtgz")
115 {
[21544]116 require dbutil::gdbmtxtgz;
[21546]117 return &dbutil::gdbmtxtgz::get_infodb_file_path($collection_name, $infodb_directory_path, @_);
[17476]118 }
[21411]119 elsif ($infodb_type eq "jdbm")
120 {
[21544]121 require dbutil::jdbm;
[21546]122 return &dbutil::jdbm::get_infodb_file_path($collection_name, $infodb_directory_path, @_);
[21411]123 }
[17476]124 elsif ($infodb_type eq "mssql")
125 {
126 #==================================================================================================#
127 # Updated by Jeffrey (2008/08/25 Monday)
128 # After look into the run-time code, it seems we should still create a database file.
129 # Since the run-time code is always try to read a database file, the easiest way here is not
130 # to change the whole structure, but to give whatever the system is looking for.
131 #==================================================================================================#
132 # Added by Jeffrey (2008/08/15 Friday)
133 # No file path required for MS SQL, it is a server-client connection.
[21411]134 # At the moment the information is hard coded in dbutil::mssql::open_infodb_write_handle
[17476]135 # the this might need some tidy up sometime.
136 #==================================================================================================#
[21544]137 require dbutil::mssql;
[21546]138 return &dbutil::mssql::get_infodb_file_path($collection_name, $infodb_directory_path, @_);
[17476]139 }
140
141 # Use GDBM if the infodb type is empty or not one of the values above
[21544]142 require dbutil::gdbm;
[21546]143 return &dbutil::gdbm::get_infodb_file_path($collection_name, $infodb_directory_path, @_);
[15710]144}
145
[22485]146# This function, conceptually, would be better structured if it didn't
147# use return statements, as the database methods it calls do not
148# themselves return anything.
149# Note: if doing this, then the GDBM lines of code should be moved into
150# an 'else' clause
[15710]151
[15705]152sub read_infodb_file
153{
[17476]154 my $infodb_type = shift(@_);
155 my $infodb_file_path = shift(@_);
156 my $infodb_map = shift(@_);
[15705]157
[17476]158 if ($infodb_type eq "sqlite")
159 {
[21544]160 require dbutil::sqlite;
[21546]161 return &dbutil::sqlite::read_infodb_file($infodb_file_path, $infodb_map, @_);
[17476]162 }
163 elsif ($infodb_type eq "gdbm-txtgz")
164 {
[21544]165 require dbutil::gdbmtxtgz;
[21546]166 return &dbutil::gdbmtxtgz::read_infodb_file($infodb_file_path, $infodb_map, @_);
[17476]167 }
[21411]168 elsif ($infodb_type eq "jdbm")
169 {
[21544]170 require dbutil::jdbm;
[21546]171 return &dbutil::jdbm::read_infodb_file($infodb_file_path, $infodb_map, @_);
[21411]172 }
[17476]173 elsif ($infodb_type eq "mssql")
174 {
[21544]175 require dbutil::mssql;
[21546]176 return &dbutil::mssql::read_infodb_file($infodb_file_path, $infodb_map, @_);
[17476]177 }
178
179 # Use GDBM if the infodb type is empty or not one of the values above
[21544]180 require dbutil::gdbm;
[21546]181 return &dbutil::gdbm::read_infodb_file($infodb_file_path, $infodb_map, @_);
[15705]182}
183
[22485]184sub read_infodb_keys
185{
186 my $infodb_type = shift(@_);
187 my $infodb_file_path = shift(@_);
188 my $infodb_map = shift(@_);
189
190 if ($infodb_type eq "sqlite")
191 {
192 require dbutil::sqlite;
193 &dbutil::sqlite::read_infodb_keys($infodb_file_path, $infodb_map, @_);
194 }
195 elsif ($infodb_type eq "gdbm-txtgz")
196 {
197 require dbutil::gdbmtxtgz;
198 &dbutil::gdbmtxtgz::read_infodb_keys($infodb_file_path, $infodb_map, @_);
199 }
200 elsif ($infodb_type eq "jdbm")
201 {
202 require dbutil::jdbm;
203 &dbutil::jdbm::read_infodb_keys($infodb_file_path, $infodb_map, @_);
204 }
205 elsif ($infodb_type eq "mssql")
206 {
207 require dbutil::mssql;
208 &dbutil::mssql::read_infodb_keys($infodb_file_path, $infodb_map, @_);
209 }
210 else {
211 # Use GDBM if the infodb type is empty or not one of the values above
212 require dbutil::gdbm;
213 &dbutil::gdbm::read_infodb_keys($infodb_file_path, $infodb_map, @_);
214 }
215}
[15705]216
[23485]217sub read_infodb_rawentry
218{
219 my $infodb_type = shift(@_);
220 my $infodb_file_path = shift(@_);
221 my $infodb_key = shift(@_);
222
223
224 # !! TEMPORARY: Slow and naive implementation that just reads the entire file and picks out the one value
225 # !! This will soon be replaced with database-specific versions that will use dbget etc.
226 my $infodb_map = {};
227 &read_infodb_file($infodb_type, $infodb_file_path, $infodb_map);
228
229 return $infodb_map->{$infodb_key};
230}
231
232
[21547]233sub read_infodb_entry
234{
235 my $infodb_type = shift(@_);
236 my $infodb_file_path = shift(@_);
237 my $infodb_key = shift(@_);
238
[23399]239
240 if ($infodb_type eq "sqlite")
241 {
242 require dbutil::sqlite;
243 return &dbutil::sqlite::read_infodb_entry($infodb_file_path, $infodb_key, @_);
244 }
245# elsif ($infodb_type eq "gdbm-txtgz")
246# {
247# require dbutil::gdbmtxtgz;
248# return &dbutil::gdbmtxtgz::read_infodb_entry($infodb_file_path, $infodb_key, @_);
249# }
250# elsif ($infodb_type eq "jdbm")
251# {
252# require dbutil::jdbm;
253# return &dbutil::jdbm::read_infodb_entry($infodb_file_path, $infodb_key, @_);
254# }
255# elsif ($infodb_type eq "mssql")
256# {
257# require dbutil::mssql;
258# return &dbutil::mssql::read_infodb_entry($infodb_file_path, $infodb_key, @_);
259# }
260
261# # Use GDBM if the infodb type is empty or not one of the values above
262# require dbutil::gdbm;
263# return &dbutil::gdbm::read_infodb_entry($infodb_file_path, $infodb_key, @_);
264
265
[23485]266 # rawentry above is currently naive implementation
267 my $raw_string = read_infodb_rawentry($infodb_type, $infodb_file_path, $infodb_key);
268 my $infodb_rec = &dbutil::convert_infodb_string_to_hash($raw_string);
[23399]269
[23448]270 return $infodb_rec;
[21547]271}
272
273
[15699]274sub write_infodb_entry
275{
[17476]276 my $infodb_type = shift(@_);
277 my $infodb_handle = shift(@_);
278 my $infodb_key = shift(@_);
279 my $infodb_map = shift(@_);
[15699]280
[17476]281 if ($infodb_type eq "sqlite")
282 {
[21544]283 require dbutil::sqlite;
[21546]284 return &dbutil::sqlite::write_infodb_entry($infodb_handle, $infodb_key, $infodb_map, @_);
[17476]285 }
286 elsif ($infodb_type eq "gdbm-txtgz")
287 {
[21544]288 require dbutil::gdbmtxtgz;
[21546]289 return &dbutil::gdbmtxtgz::write_infodb_entry($infodb_handle, $infodb_key, $infodb_map, @_);
[17476]290 }
[21411]291 elsif ($infodb_type eq "jdbm")
292 {
[21544]293 require dbutil::jdbm;
[21546]294 return &dbutil::jdbm::write_infodb_entry($infodb_handle, $infodb_key, $infodb_map, @_);
[21411]295 }
[17476]296 elsif ($infodb_type eq "mssql")
297 {
[21544]298 require dbutil::mssql;
[21546]299 return &dbutil::mssql::write_infodb_entry($infodb_handle, $infodb_key, $infodb_map, @_);
[17476]300 }
[15725]301
[17476]302 # Use GDBM if the infodb type is empty or not one of the values above
[21544]303 require dbutil::gdbm;
[21546]304 return &dbutil::gdbm::write_infodb_entry($infodb_handle, $infodb_key, $infodb_map, @_);
[15699]305}
306
[15705]307
[21856]308sub write_infodb_rawentry
309{
310 my $infodb_type = shift(@_);
311 my $infodb_handle = shift(@_);
312 my $infodb_key = shift(@_);
313 my $infodb_val = shift(@_);
314
315 if ($infodb_type eq "sqlite")
316 {
317 require dbutil::sqlite;
318 return &dbutil::sqlite::write_infodb_rawentry($infodb_handle, $infodb_key, $infodb_val, @_);
319 }
320 elsif ($infodb_type eq "gdbm-txtgz")
321 {
322 require dbutil::gdbmtxtgz;
323 return &dbutil::gdbmtxtgz::write_infodb_rawentry($infodb_handle, $infodb_key, $infodb_val, @_);
324 }
325 elsif ($infodb_type eq "jdbm")
326 {
327 require dbutil::jdbm;
328 return &dbutil::jdbm::write_infodb_rawentry($infodb_handle, $infodb_key, $infodb_val, @_);
329 }
330 elsif ($infodb_type eq "mssql")
331 {
332 require dbutil::mssql;
333 return &dbutil::mssql::write_infodb_rawentry($infodb_handle, $infodb_key, $infodb_val, @_);
334 }
335
336 # Use GDBM if the infodb type is empty or not one of the values above
337 require dbutil::gdbm;
338 return &dbutil::gdbm::write_infodb_rawentry($infodb_handle, $infodb_key, $infodb_val, @_);
339}
340
341
[23399]342sub set_infodb_entry
343{
344 my $infodb_type = shift(@_);
345 my $infodb_file_path = shift(@_);
346 my $infodb_key = shift(@_);
347 my $infodb_map = shift(@_);
[21856]348
[23399]349 if ($infodb_type eq "sqlite")
350 {
351 require dbutil::sqlite;
352 return &dbutil::sqlite::set_infodb_entry($infodb_file_path, $infodb_key, $infodb_map, @_);
353 }
354 elsif ($infodb_type eq "gdbm-txtgz")
355 {
356 require dbutil::gdbmtxtgz;
357 return &dbutil::gdbmtxtgz::set_infodb_entry($infodb_file_path, $infodb_key, $infodb_map, @_);
358 }
359 elsif ($infodb_type eq "jdbm")
360 {
361 require dbutil::jdbm;
362 return &dbutil::jdbm::set_infodb_entry($infodb_file_path, $infodb_key, $infodb_map, @_);
363 }
364 elsif ($infodb_type eq "mssql")
365 {
366 require dbutil::mssql;
367 return &dbutil::mssql::set_infodb_entry($infodb_file_path, $infodb_key, $infodb_map, @_);
368 }
369
370 # Use GDBM if the infodb type is empty or not one of the values above
371 require dbutil::gdbm;
372 return &dbutil::gdbm::set_infodb_entry($infodb_file_path, $infodb_key, $infodb_map, @_);
373}
374
375
376
[18467]377sub delete_infodb_entry
378{
379 my $infodb_type = shift(@_);
380 my $infodb_handle = shift(@_);
381 my $infodb_key = shift(@_);
[15705]382
[18467]383 if ($infodb_type eq "sqlite")
384 {
[21544]385 require dbutil::sqlite;
[21546]386 return &dbutil::sqlite::delete_infodb_entry($infodb_handle, $infodb_key, @_);
[18467]387 }
388 elsif ($infodb_type eq "gdbm-txtgz")
389 {
[21544]390 require dbutil::gdbmtxtgz;
[21546]391 return &dbutil::gdbmtxtgz::delete_infodb_entry($infodb_handle, $infodb_key, @_);
[18467]392 }
[21411]393 elsif ($infodb_type eq "jdbm")
394 {
[21544]395 require dbutil::jdbm;
[21546]396 return &dbutil::jdbm::delete_infodb_entry($infodb_handle, $infodb_key, @_);
[21411]397 }
[18467]398 elsif ($infodb_type eq "mssql")
399 {
[21544]400 require dbutil::mssql;
[21546]401 return &dbutil::mssql::delete_infodb_entry($infodb_handle, $infodb_key, @_);
[18467]402 }
403
404 # Use GDBM if the infodb type is empty or not one of the values above
[21544]405 require dbutil::gdbm;
[21546]406 return &dbutil::gdbm::delete_infodb_entry($infodb_handle, $infodb_key, @_);
[18467]407}
408
409
[21550]410# ---- GENERAL FUNCTIONS --------
411
412sub convert_infodb_hash_to_string
413{
414 my $infodb_map = shift(@_);
415
416 my $infodb_entry_value = "";
417 foreach my $infodb_value_key (keys(%$infodb_map))
418 {
419 foreach my $infodb_value (@{$infodb_map->{$infodb_value_key}})
420 {
421 $infodb_entry_value .= "<$infodb_value_key>" . $infodb_value . "\n";
422 }
423 }
424
425 return $infodb_entry_value;
426}
427
428
429sub convert_infodb_string_to_hash
430{
431 my $infodb_entry_value = shift(@_);
432 my $infodb_map = ();
[22121]433
434 if (!defined $infodb_entry_value) {
435 print STDERR "Warning: No value to convert into a infodb hashtable\n";
436 }
437 else {
438 while ($infodb_entry_value =~ /^<(.*?)>(.*)$/mg)
439 {
440 my $infodb_value_key = $1;
441 my $infodb_value = $2;
[21550]442
[22121]443 if (!defined($infodb_map->{$infodb_value_key}))
444 {
445 $infodb_map->{$infodb_value_key} = [ $infodb_value ];
446 }
447 else
448 {
449 push(@{$infodb_map->{$infodb_value_key}}, $infodb_value);
450 }
451 }
[21550]452 }
453
454 return $infodb_map;
455}
456
457
[15699]4581;
Note: See TracBrowser for help on using the repository browser.