source: main/trunk/greenstone2/perllib/dbutil/sqlite.pm@ 22485

Last change on this file since 22485 was 22485, checked in by ak19, 14 years ago
  1. Dr Bainbridge fixed the database perl modules to all have the method read_info_keys (which reads the keys from the database into a map), so that dbutil.pm can have the same as a generic method. 2. buildConfigxml.pm only writes out the defaultIndex if it is set (to prevent an Uninitialised Variable warning message from Perl).
File size: 7.7 KB
Line 
1###########################################################################
2#
3# dbutil::sqlite -- utility functions for writing to sqlite databases
4#
5# A component of the Greenstone digital library software
6# from the New Zealand Digital Library Project at the
7# University of Waikato, New Zealand.
8#
9# Copyright (C) 2009
10#
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation; either version 2 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program; if not, write to the Free Software
23# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24#
25###########################################################################
26
27package dbutil::sqlite;
28
29use strict;
30
31
32# -----------------------------------------------------------------------------
33# SQLITE IMPLEMENTATION
34# -----------------------------------------------------------------------------
35
36sub open_infodb_write_handle
37{
38 my $infodb_file_path = shift(@_);
39
40 my $sqlite3_exe = &util::filename_cat($ENV{'GSDLHOME'},"bin",$ENV{'GSDLOS'}, "sqlite3" . &util::get_os_exe());
41 my $infodb_handle = undef;
42
43 if (!-e "$sqlite3_exe")
44 {
45 print STDERR "Error: Unable to find $sqlite3_exe\n";
46 return undef;
47 }
48
49 if(!open($infodb_handle, "| \"$sqlite3_exe\" \"$infodb_file_path\""))
50 {
51 print STDERR "Error: Failed to open pipe to \"$sqlite3_exe\" \"$infodb_file_path\"\n";
52 print STDERR " $!\n";
53 return undef;
54 }
55
56 print $infodb_handle "CREATE TABLE IF NOT EXISTS data (key TEXT PRIMARY KEY, value TEXT);\n";
57 print $infodb_handle "CREATE TABLE IF NOT EXISTS document_metadata (id INTEGER PRIMARY KEY, docOID TEXT, element TEXT, value TEXT);\n";
58
59 # This is crucial for efficiency when importing large amounts of data
60 print $infodb_handle "CREATE INDEX IF NOT EXISTS dmd ON document_metadata(docOID);\n";
61
62 # This is very important for efficiency, otherwise each command will be actioned one at a time
63 print $infodb_handle "BEGIN TRANSACTION;\n";
64
65 return $infodb_handle;
66}
67
68
69sub close_infodb_write_handle
70{
71 my $infodb_handle = shift(@_);
72
73 # Close the transaction we began after opening the file
74 print $infodb_handle "END TRANSACTION;\n";
75
76 # This is crucial for efficient queries on the database!
77 print $infodb_handle "CREATE INDEX IF NOT EXISTS dme ON document_metadata(element);\n";
78
79 close($infodb_handle);
80}
81
82
83sub read_infodb_cmd
84{
85 my $infodb_file_path = shift(@_);
86 my $sqlcmd = shift(@_);
87
88 my $result = "";
89
90 my $sqlite3_exe = &util::filename_cat($ENV{'GSDLHOME'},"bin",$ENV{'GSDLOS'}, "sqlite3" . &util::get_os_exe());
91 my $infodb_handle = undef;
92 my $cmd = "\"$sqlite3_exe\" \"$infodb_file_path\" \"$sqlcmd\"";
93
94 if (!-e "$sqlite3_exe" || !open($infodb_handle, "$cmd |"))
95 {
96 print STDERR "Unable to execute: $cmd\n";
97 print STDERR "$!\n";
98 }
99 else {
100
101 my $line;
102 while (defined($line=<$infodb_handle>)) {
103 $result .= $line;
104 }
105
106 close($infodb_handle);
107 }
108
109 return $result;
110}
111
112sub get_infodb_file_path
113{
114 my $collection_name = shift(@_);
115 my $infodb_directory_path = shift(@_);
116
117 my $infodb_file_extension = ".db";
118 my $infodb_file_name = &util::get_dirsep_tail($collection_name) . $infodb_file_extension;
119 return &util::filename_cat($infodb_directory_path, $infodb_file_name);
120}
121
122
123sub read_infodb_file
124{
125 my $infodb_file_path = shift(@_);
126 my $infodb_map = shift(@_);
127
128
129 my $keys_str = read_infodb_cmd($infodb_file_path,"SELECT key FROM data;");
130
131 my @keys = split(/\n/,$keys_str);
132
133 foreach my $k (@keys) {
134
135 my $k_safe = &sqlite_safe($k);
136 my $select_val_cmd = "SELECT value FROM data WHERE key='$k_safe';";
137
138 my $val_str = read_infodb_cmd($infodb_file_path,$select_val_cmd);
139
140 $infodb_map->{$k} = $val_str;
141 }
142
143}
144
145
146sub read_infodb_keys
147{
148 my $infodb_file_path = shift(@_);
149 my $infodb_map = shift(@_);
150
151
152 my $keys_str = read_infodb_cmd($infodb_file_path,"SELECT key FROM data;");
153
154 my @keys = split(/\n/,$keys_str);
155
156 foreach my $key (@keys)
157 {
158 $infodb_map->{$key} = 1;
159 }
160}
161
162
163sub write_infodb_entry
164{
165 my $infodb_handle = shift(@_);
166 my $infodb_key = shift(@_);
167 my $infodb_map = shift(@_);
168
169 # Add the key -> value mapping into the "data" table
170 my $infodb_entry_value = "";
171 foreach my $infodb_value_key (keys(%$infodb_map))
172 {
173 foreach my $infodb_value (@{$infodb_map->{$infodb_value_key}})
174 {
175 $infodb_entry_value .= "<$infodb_value_key>" . $infodb_value . "\n";
176 }
177 }
178
179 my $safe_infodb_key = &sqlite_safe($infodb_key);
180 print $infodb_handle "INSERT OR REPLACE INTO data (key, value) VALUES ('" . $safe_infodb_key . "', '" . &sqlite_safe($infodb_entry_value) . "');\n";
181
182 # If this infodb entry is for a document, add all the interesting document metadata to the
183 # "document_metadata" table (for use by the dynamic classifiers)
184 if ($infodb_key !~ /\./ && $infodb_entry_value =~ /\<doctype\>doc\n/)
185 {
186 print $infodb_handle "DELETE FROM document_metadata WHERE docOID='" . $safe_infodb_key . "';\n";
187
188 foreach my $infodb_value_key (keys(%$infodb_map))
189 {
190 # We're not interested in most of the automatically added document metadata
191 next if ($infodb_value_key eq "archivedir" ||
192 $infodb_value_key eq "assocfilepath" ||
193 $infodb_value_key eq "childtype" ||
194 $infodb_value_key eq "contains" ||
195 $infodb_value_key eq "docnum" ||
196 $infodb_value_key eq "doctype" ||
197 $infodb_value_key eq "Encoding" ||
198 $infodb_value_key eq "FileSize" ||
199 $infodb_value_key eq "hascover" ||
200 $infodb_value_key eq "hastxt" ||
201 $infodb_value_key eq "lastmodified" ||
202 $infodb_value_key eq "metadataset" ||
203 $infodb_value_key eq "thistype" ||
204 $infodb_value_key =~ /^metadatafreq\-/ ||
205 $infodb_value_key =~ /^metadatalist\-/);
206
207 foreach my $infodb_value (@{$infodb_map->{$infodb_value_key}})
208 {
209 print $infodb_handle "INSERT INTO document_metadata (docOID, element, value) VALUES ('" . $safe_infodb_key . "', '" . &sqlite_safe($infodb_value_key) . "', '" . &sqlite_safe($infodb_value) . "');\n";
210 }
211 }
212 }
213}
214
215
216
217sub write_infodb_rawentry
218{
219 my $infodb_handle = shift(@_);
220 my $infodb_key = shift(@_);
221 my $infodb_val = shift(@_);
222
223 my $safe_infodb_key = &sqlite_safe($infodb_key);
224 print $infodb_handle "INSERT OR REPLACE INTO data (key, value) VALUES ('" . $safe_infodb_key . "', '" . &sqlite_safe($infodb_val) . "');\n";
225}
226
227
228
229sub delete_infodb_entry
230{
231 my $infodb_handle = shift(@_);
232 my $infodb_key = shift(@_);
233
234 # Delete the key from the "data" table
235
236 my $safe_infodb_key = &sqlite_safe($infodb_key);
237
238 print $infodb_handle "DELETE FROM data WHERE key='" . $safe_infodb_key . "';\n";
239
240 # If this infodb entry is for a document, delete the
241 # "document_metadata" table entry also (for use by the dynamic classifiers)
242 if ($infodb_key !~ /\./)
243 {
244 # Possible for there not to be a docOID matching this infodb_key
245 # (entries are only made when <doctype> == doc
246 # Attempt to delete it, and don't complain if one isn't found
247
248 print $infodb_handle "DELETE FROM document_metadata WHERE docOID='" . $safe_infodb_key . "';\n";
249
250 }
251}
252
253
254sub sqlite_safe
255{
256 my $value = shift(@_);
257
258 # Escape any single quotes in the value
259 $value =~ s/\'/\'\'/g;
260
261 return $value;
262}
263
264
2651;
Note: See TracBrowser for help on using the repository browser.