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

Last change on this file since 23399 was 23399, checked in by max, 13 years ago

Added (for GDBM and Sqlite) set_infodb_entry to directly change one value in the database. Print statements added to other versions of function, alterting that they are not implemented.

Also added read_infodb_rawentry. Plus, more efficient way of accessing a single record from Sqlite.

File size: 12.9 KB
Line 
1###########################################################################
2#
3# dbutil.pm -- gateway to utilities for reading/writing to different databases
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
31sub open_infodb_write_handle
32{
33 my $infodb_type = shift(@_);
34 my $infodb_file_path = shift(@_);
35
36 if ($infodb_type eq "sqlite")
37 {
38 require dbutil::sqlite;
39 return &dbutil::sqlite::open_infodb_write_handle($infodb_file_path, @_);
40 }
41 elsif ($infodb_type eq "gdbm-txtgz")
42 {
43 require dbutil::gdbmtxtgz;
44 return &dbutil::gdbmtxtgz::open_infodb_write_handle($infodb_file_path, @_);
45 }
46 elsif ($infodb_type eq "jdbm")
47 {
48 require dbutil::jdbm;
49 return &dbutil::jdbm::open_infodb_write_handle($infodb_file_path, @_);
50 }
51 elsif ($infodb_type eq "mssql")
52 {
53 require dbutil::mssql;
54 return &dbutil::mssql::open_infodb_write_handle($infodb_file_path, @_);
55 }
56
57 # Use GDBM if the infodb type is empty or not one of the values above
58 require dbutil::gdbm;
59 return &dbutil::gdbm::open_infodb_write_handle($infodb_file_path, @_);
60}
61
62
63sub close_infodb_write_handle
64{
65 my $infodb_type = shift(@_);
66 my $infodb_handle = shift(@_);
67
68 if ($infodb_type eq "sqlite")
69 {
70 require dbutil::sqlite;
71 return &dbutil::sqlite::close_infodb_write_handle($infodb_handle, @_);
72 }
73 elsif ($infodb_type eq "gdbm-txtgz")
74 {
75 require dbutil::gdbmtxtgz;
76 return &dbutil::gdbmtxtgz::close_infodb_write_handle($infodb_handle, @_);
77 }
78 elsif ($infodb_type eq "jdbm")
79 {
80 require dbutil::jdbm;
81 return &dbutil::jdbm::close_infodb_write_handle($infodb_handle, @_);
82 }
83 elsif ($infodb_type eq "mssql")
84 {
85 require dbutil::mssql;
86 return &dbutil::mssql::close_infodb_write_handle($infodb_handle, @_);
87 }
88
89 # Use GDBM if the infodb type is empty or not one of the values above
90 require dbutil::gdbm;
91 return &dbutil::gdbm::close_infodb_write_handle($infodb_handle, @_);
92}
93
94
95sub get_default_infodb_type
96{
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";
100}
101
102
103sub get_infodb_file_path
104{
105 my $infodb_type = shift(@_);
106 my $collection_name = shift(@_);
107 my $infodb_directory_path = shift(@_);
108
109 if ($infodb_type eq "sqlite")
110 {
111 require dbutil::sqlite;
112 return &dbutil::sqlite::get_infodb_file_path($collection_name, $infodb_directory_path, @_);
113 }
114 elsif ($infodb_type eq "gdbm-txtgz")
115 {
116 require dbutil::gdbmtxtgz;
117 return &dbutil::gdbmtxtgz::get_infodb_file_path($collection_name, $infodb_directory_path, @_);
118 }
119 elsif ($infodb_type eq "jdbm")
120 {
121 require dbutil::jdbm;
122 return &dbutil::jdbm::get_infodb_file_path($collection_name, $infodb_directory_path, @_);
123 }
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.
134 # At the moment the information is hard coded in dbutil::mssql::open_infodb_write_handle
135 # the this might need some tidy up sometime.
136 #==================================================================================================#
137 require dbutil::mssql;
138 return &dbutil::mssql::get_infodb_file_path($collection_name, $infodb_directory_path, @_);
139 }
140
141 # Use GDBM if the infodb type is empty or not one of the values above
142 require dbutil::gdbm;
143 return &dbutil::gdbm::get_infodb_file_path($collection_name, $infodb_directory_path, @_);
144}
145
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
151
152sub read_infodb_file
153{
154 my $infodb_type = shift(@_);
155 my $infodb_file_path = shift(@_);
156 my $infodb_map = shift(@_);
157
158 if ($infodb_type eq "sqlite")
159 {
160 require dbutil::sqlite;
161 return &dbutil::sqlite::read_infodb_file($infodb_file_path, $infodb_map, @_);
162 }
163 elsif ($infodb_type eq "gdbm-txtgz")
164 {
165 require dbutil::gdbmtxtgz;
166 return &dbutil::gdbmtxtgz::read_infodb_file($infodb_file_path, $infodb_map, @_);
167 }
168 elsif ($infodb_type eq "jdbm")
169 {
170 require dbutil::jdbm;
171 return &dbutil::jdbm::read_infodb_file($infodb_file_path, $infodb_map, @_);
172 }
173 elsif ($infodb_type eq "mssql")
174 {
175 require dbutil::mssql;
176 return &dbutil::mssql::read_infodb_file($infodb_file_path, $infodb_map, @_);
177 }
178
179 # Use GDBM if the infodb type is empty or not one of the values above
180 require dbutil::gdbm;
181 return &dbutil::gdbm::read_infodb_file($infodb_file_path, $infodb_map, @_);
182}
183
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}
216
217sub read_infodb_entry
218{
219 my $infodb_type = shift(@_);
220 my $infodb_file_path = shift(@_);
221 my $infodb_key = shift(@_);
222
223
224 if ($infodb_type eq "sqlite")
225 {
226 require dbutil::sqlite;
227 return &dbutil::sqlite::read_infodb_entry($infodb_file_path, $infodb_key, @_);
228 }
229# elsif ($infodb_type eq "gdbm-txtgz")
230# {
231# require dbutil::gdbmtxtgz;
232# return &dbutil::gdbmtxtgz::read_infodb_entry($infodb_file_path, $infodb_key, @_);
233# }
234# elsif ($infodb_type eq "jdbm")
235# {
236# require dbutil::jdbm;
237# return &dbutil::jdbm::read_infodb_entry($infodb_file_path, $infodb_key, @_);
238# }
239# elsif ($infodb_type eq "mssql")
240# {
241# require dbutil::mssql;
242# return &dbutil::mssql::read_infodb_entry($infodb_file_path, $infodb_key, @_);
243# }
244
245# # Use GDBM if the infodb type is empty or not one of the values above
246# require dbutil::gdbm;
247# return &dbutil::gdbm::read_infodb_entry($infodb_file_path, $infodb_key, @_);
248
249
250
251 # !! TEMPORARY: Slow and naive implementation that just reads the entire file and picks out the one value
252 # !! This will soon be replaced with database-specific versions that will use dbget etc.
253 my $infodb_map = {};
254 &read_infodb_file($infodb_type, $infodb_file_path, $infodb_map);
255 return $infodb_map->{$infodb_key};
256}
257
258
259sub write_infodb_entry
260{
261 my $infodb_type = shift(@_);
262 my $infodb_handle = shift(@_);
263 my $infodb_key = shift(@_);
264 my $infodb_map = shift(@_);
265
266 if ($infodb_type eq "sqlite")
267 {
268 require dbutil::sqlite;
269 return &dbutil::sqlite::write_infodb_entry($infodb_handle, $infodb_key, $infodb_map, @_);
270 }
271 elsif ($infodb_type eq "gdbm-txtgz")
272 {
273 require dbutil::gdbmtxtgz;
274 return &dbutil::gdbmtxtgz::write_infodb_entry($infodb_handle, $infodb_key, $infodb_map, @_);
275 }
276 elsif ($infodb_type eq "jdbm")
277 {
278 require dbutil::jdbm;
279 return &dbutil::jdbm::write_infodb_entry($infodb_handle, $infodb_key, $infodb_map, @_);
280 }
281 elsif ($infodb_type eq "mssql")
282 {
283 require dbutil::mssql;
284 return &dbutil::mssql::write_infodb_entry($infodb_handle, $infodb_key, $infodb_map, @_);
285 }
286
287 # Use GDBM if the infodb type is empty or not one of the values above
288 require dbutil::gdbm;
289 return &dbutil::gdbm::write_infodb_entry($infodb_handle, $infodb_key, $infodb_map, @_);
290}
291
292
293sub write_infodb_rawentry
294{
295 my $infodb_type = shift(@_);
296 my $infodb_handle = shift(@_);
297 my $infodb_key = shift(@_);
298 my $infodb_val = shift(@_);
299
300 if ($infodb_type eq "sqlite")
301 {
302 require dbutil::sqlite;
303 return &dbutil::sqlite::write_infodb_rawentry($infodb_handle, $infodb_key, $infodb_val, @_);
304 }
305 elsif ($infodb_type eq "gdbm-txtgz")
306 {
307 require dbutil::gdbmtxtgz;
308 return &dbutil::gdbmtxtgz::write_infodb_rawentry($infodb_handle, $infodb_key, $infodb_val, @_);
309 }
310 elsif ($infodb_type eq "jdbm")
311 {
312 require dbutil::jdbm;
313 return &dbutil::jdbm::write_infodb_rawentry($infodb_handle, $infodb_key, $infodb_val, @_);
314 }
315 elsif ($infodb_type eq "mssql")
316 {
317 require dbutil::mssql;
318 return &dbutil::mssql::write_infodb_rawentry($infodb_handle, $infodb_key, $infodb_val, @_);
319 }
320
321 # Use GDBM if the infodb type is empty or not one of the values above
322 require dbutil::gdbm;
323 return &dbutil::gdbm::write_infodb_rawentry($infodb_handle, $infodb_key, $infodb_val, @_);
324}
325
326
327sub set_infodb_entry
328{
329 my $infodb_type = shift(@_);
330 my $infodb_file_path = shift(@_);
331 my $infodb_key = shift(@_);
332 my $infodb_map = shift(@_);
333
334 if ($infodb_type eq "sqlite")
335 {
336 require dbutil::sqlite;
337 return &dbutil::sqlite::set_infodb_entry($infodb_file_path, $infodb_key, $infodb_map, @_);
338 }
339 elsif ($infodb_type eq "gdbm-txtgz")
340 {
341 require dbutil::gdbmtxtgz;
342 return &dbutil::gdbmtxtgz::set_infodb_entry($infodb_file_path, $infodb_key, $infodb_map, @_);
343 }
344 elsif ($infodb_type eq "jdbm")
345 {
346 require dbutil::jdbm;
347 return &dbutil::jdbm::set_infodb_entry($infodb_file_path, $infodb_key, $infodb_map, @_);
348 }
349 elsif ($infodb_type eq "mssql")
350 {
351 require dbutil::mssql;
352 return &dbutil::mssql::set_infodb_entry($infodb_file_path, $infodb_key, $infodb_map, @_);
353 }
354
355 # Use GDBM if the infodb type is empty or not one of the values above
356 require dbutil::gdbm;
357 return &dbutil::gdbm::set_infodb_entry($infodb_file_path, $infodb_key, $infodb_map, @_);
358}
359
360
361
362sub delete_infodb_entry
363{
364 my $infodb_type = shift(@_);
365 my $infodb_handle = shift(@_);
366 my $infodb_key = shift(@_);
367
368 if ($infodb_type eq "sqlite")
369 {
370 require dbutil::sqlite;
371 return &dbutil::sqlite::delete_infodb_entry($infodb_handle, $infodb_key, @_);
372 }
373 elsif ($infodb_type eq "gdbm-txtgz")
374 {
375 require dbutil::gdbmtxtgz;
376 return &dbutil::gdbmtxtgz::delete_infodb_entry($infodb_handle, $infodb_key, @_);
377 }
378 elsif ($infodb_type eq "jdbm")
379 {
380 require dbutil::jdbm;
381 return &dbutil::jdbm::delete_infodb_entry($infodb_handle, $infodb_key, @_);
382 }
383 elsif ($infodb_type eq "mssql")
384 {
385 require dbutil::mssql;
386 return &dbutil::mssql::delete_infodb_entry($infodb_handle, $infodb_key, @_);
387 }
388
389 # Use GDBM if the infodb type is empty or not one of the values above
390 require dbutil::gdbm;
391 return &dbutil::gdbm::delete_infodb_entry($infodb_handle, $infodb_key, @_);
392}
393
394
395# ---- GENERAL FUNCTIONS --------
396
397sub convert_infodb_hash_to_string
398{
399 my $infodb_map = shift(@_);
400
401 my $infodb_entry_value = "";
402 foreach my $infodb_value_key (keys(%$infodb_map))
403 {
404 foreach my $infodb_value (@{$infodb_map->{$infodb_value_key}})
405 {
406 $infodb_entry_value .= "<$infodb_value_key>" . $infodb_value . "\n";
407 }
408 }
409
410 return $infodb_entry_value;
411}
412
413
414sub convert_infodb_string_to_hash
415{
416 my $infodb_entry_value = shift(@_);
417 my $infodb_map = ();
418
419 if (!defined $infodb_entry_value) {
420 print STDERR "Warning: No value to convert into a infodb hashtable\n";
421 }
422 else {
423 while ($infodb_entry_value =~ /^<(.*?)>(.*)$/mg)
424 {
425 my $infodb_value_key = $1;
426 my $infodb_value = $2;
427
428 if (!defined($infodb_map->{$infodb_value_key}))
429 {
430 $infodb_map->{$infodb_value_key} = [ $infodb_value ];
431 }
432 else
433 {
434 push(@{$infodb_map->{$infodb_value_key}}, $infodb_value);
435 }
436 }
437 }
438
439 return $infodb_map;
440}
441
442
4431;
Note: See TracBrowser for help on using the repository browser.