root/wiki-toolkit/trunk/lib/Wiki/Toolkit/Setup/Database.pm

Revision 441, 10.8 KB (checked in by dom, 4 years ago)

Move to new schema version 10, including some missing indexes
and support for deletion flags and verified flags. Note that
the code using these columns has not yet been written (closes #25, #34).

Line 
1package Wiki::Toolkit::Setup::Database;
2
3use strict;
4
5use vars qw( $VERSION @SUPPORTED_SCHEMAS);
6
7$VERSION = 0.09;
8@SUPPORTED_SCHEMAS = qw(8 9 10);
9
10=head1 NAME
11
12Wiki::Toolkit::Setup::Database - parent class for database storage setup
13classes for Wiki::Toolkit
14
15=cut
16
17sub fetch_upgrade_old_to_8 {
18    # Compatible with old_to_10
19    fetch_upgrade_old_to_10(@_);
20}
21
22sub fetch_upgrade_old_to_9 {
23    # Compatible with old_to_10
24    fetch_upgrade_old_to_10(@_);
25}
26
27# Fetch from the old style database, ready for an upgrade to db version 10
28sub fetch_upgrade_old_to_10 {
29    my $dbh = shift;
30    my %nodes;
31    my %metadatas;
32    my %contents;
33    my @internal_links;
34    my %ids;
35
36    print "Grabbing and upgrading old data... ";
37
38    # Grab all the nodes, and give them an ID
39    my $sth = $dbh->prepare("SELECT name,version,text,modified FROM node");
40    $sth->execute;
41    my $id = 0;
42    while( my($name,$version,$text,$modified) = $sth->fetchrow_array) {
43        my %node;
44        $id++;
45        $node{'name'} = $name;
46        $node{'version'} = $version;
47        $node{'text'} = $text;
48        $node{'modified'} = $modified;
49        $node{'id'} = $id;
50        $node{'moderate'} = 0;
51        $nodes{$name} = \%node;
52        $ids{$name} = $id;
53    }
54    print " read $id nodes...  ";
55
56    # Grab all the content, and upgrade to ID from name
57    $sth = $dbh->prepare("SELECT name,version,text,modified,comment FROM content");
58    $sth->execute;
59    while ( my($name,$version,$text,$modified,$comment) = $sth->fetchrow_array) {
60        my $id = $ids{$name};
61        if($id) {
62            my %content;
63            $content{'node_id'} = $id;
64            $content{'version'} = $version;
65            $content{'text'} = $text;
66            $content{'modified'} = $modified;
67            $content{'comment'} = $comment;
68            $content{'moderated'} = 1;
69            $contents{$id."-".$version} = \%content;
70        } else {
71            warn("There was no node entry for content with name '$name', unable to migrate it!");
72        }
73    }
74    print " read ".(scalar keys %contents)." contents...  ";
75
76    # Grab all the metadata, and upgrade to ID from node
77    $sth = $dbh->prepare("SELECT node,version,metadata_type,metadata_value FROM metadata");
78    $sth->execute;
79    my $i = 0;
80    while( my($node,$version,$metadata_type,$metadata_value) = $sth->fetchrow_array) {
81        my $id = $ids{$node};
82        if($id) {
83            my %metadata;
84            $metadata{'node_id'} = $id;
85            $metadata{'version'} = $version;
86            $metadata{'metadata_type'} = $metadata_type;
87            $metadata{'metadata_value'} = $metadata_value;
88            $metadatas{$id."-".($i++)} = \%metadata;
89        } else {
90            warn("There was no node entry for metadata with name (node) '$node', unable to migrate it!");
91        }
92    }
93
94    # Grab all the internal links
95    $sth = $dbh->prepare("SELECT link_from,link_to FROM internal_links");
96    $sth->execute;
97    while( my($link_from,$link_to) = $sth->fetchrow_array) {
98        my %il;
99        $il{'link_from'} = $link_from;
100        $il{'link_to'} = $link_to;
101        push @internal_links, \%il;
102    }
103
104    print "done\n";
105
106    # Return it all
107    return (\%nodes,\%contents,\%metadatas,\@internal_links,\%ids);
108}
109
110sub fetch_upgrade_8_to_9 {
111    # Compatible with 8_to_10
112    fetch_upgrade_8_to_10(@_);
113}
114
115# Fetch from schema version 8, and upgrade to version 10
116sub fetch_upgrade_8_to_10 {
117    my $dbh = shift;
118    my %nodes;
119    my %metadatas;
120    my %contents;
121    my @internal_links;
122
123    print "Grabbing and upgrading old data... ";
124
125    # Grab all the nodes
126    my $sth = $dbh->prepare("SELECT id,name,version,text,modified FROM node");
127    $sth->execute;
128    while( my($id,$name,$version,$text,$modified) = $sth->fetchrow_array) {
129        my %node;
130        $node{'name'} = $name;
131        $node{'version'} = $version;
132        $node{'text'} = $text;
133        $node{'modified'} = $modified;
134        $node{'id'} = $id;
135        $node{'moderate'} = 0;
136        $nodes{$name} = \%node;
137    }
138
139    # Grab all the content
140    $sth = $dbh->prepare("SELECT node_id,version,text,modified,comment FROM content");
141    $sth->execute;
142    while ( my($node_id,$version,$text,$modified,$comment) = $sth->fetchrow_array) {
143        my %content;
144        $content{'node_id'} = $node_id;
145        $content{'version'} = $version;
146        $content{'text'} = $text;
147        $content{'modified'} = $modified;
148        $content{'comment'} = $comment;
149        $content{'moderated'} = 1;
150        $contents{$node_id."-".$version} = \%content;
151    }
152
153    # Grab all the metadata
154    $sth = $dbh->prepare("SELECT node_id,version,metadata_type,metadata_value FROM metadata");
155    $sth->execute;
156    my $i = 0;
157    while( my($node_id,$version,$metadata_type,$metadata_value) = $sth->fetchrow_array) {
158        my %metadata;
159        $metadata{'node_id'} = $node_id;
160        $metadata{'version'} = $version;
161        $metadata{'metadata_type'} = $metadata_type;
162        $metadata{'metadata_value'} = $metadata_value;
163        $metadatas{$node_id."-".($i++)} = \%metadata;
164    }
165
166    # Grab all the internal links
167    $sth = $dbh->prepare("SELECT link_from,link_to FROM internal_links");
168    $sth->execute;
169    while( my($link_from,$link_to) = $sth->fetchrow_array) {
170        my %il;
171        $il{'link_from'} = $link_from;
172        $il{'link_to'} = $link_to;
173        push @internal_links, \%il;
174    }
175
176    print "done\n";
177
178    # Return it all
179    return (\%nodes,\%contents,\%metadatas,\@internal_links);
180}
181
182# Fetch from schema version 9, and upgrade to version 10
183sub fetch_upgrade_9_to_10 {
184    my $dbh = shift;
185    my %nodes;
186    my %metadatas;
187    my %contents;
188    my @internal_links;
189
190    print "Grabbing and upgrading old data... ";
191
192    # Grab all the nodes
193    my $sth = $dbh->prepare("SELECT id,name,version,text,modified,moderate FROM node");
194    $sth->execute;
195    while( my($id,$name,$version,$text,$modified,$moderate) = $sth->fetchrow_array) {
196        my %node;
197        $node{'name'} = $name;
198        $node{'version'} = $version;
199        $node{'text'} = $text;
200        $node{'modified'} = $modified;
201        $node{'id'} = $id;
202        $node{'moderate'} = $moderate;
203        $nodes{$name} = \%node;
204    }
205
206    # Grab all the content
207    $sth = $dbh->prepare("SELECT node_id,version,text,modified,comment,moderated FROM content");
208    $sth->execute;
209    while ( my($node_id,$version,$text,$modified,$comment,$moderated) = $sth->fetchrow_array) {
210        my %content;
211        $content{'node_id'} = $node_id;
212        $content{'version'} = $version;
213        $content{'text'} = $text;
214        $content{'modified'} = $modified;
215        $content{'comment'} = $comment;
216        $content{'moderated'} = $moderated;
217        $contents{$node_id."-".$version} = \%content;
218    }
219
220    # Grab all the metadata
221    $sth = $dbh->prepare("SELECT node_id,version,metadata_type,metadata_value FROM metadata");
222    $sth->execute;
223    my $i = 0;
224    while( my($node_id,$version,$metadata_type,$metadata_value) = $sth->fetchrow_array) {
225        my %metadata;
226        $metadata{'node_id'} = $node_id;
227        $metadata{'version'} = $version;
228        $metadata{'metadata_type'} = $metadata_type;
229        $metadata{'metadata_value'} = $metadata_value;
230        $metadatas{$node_id."-".($i++)} = \%metadata;
231    }
232
233    # Grab all the internal links
234    $sth = $dbh->prepare("SELECT link_from,link_to FROM internal_links");
235    $sth->execute;
236    while( my($link_from,$link_to) = $sth->fetchrow_array) {
237        my %il;
238        $il{'link_from'} = $link_from;
239        $il{'link_to'} = $link_to;
240        push @internal_links, \%il;
241    }
242
243    print "done\n";
244
245    # Return it all
246    return (\%nodes,\%contents,\%metadatas,\@internal_links);
247}
248
249# Get the version of the database schema
250sub get_database_version {
251    my $dbh = shift;
252    my $sql = "SELECT version FROM schema_info";
253    my $sth;
254    eval{ $sth = $dbh->prepare($sql) };
255    if($@) { return "old"; }
256    eval{ $sth->execute };
257    if($@) { return "old"; }
258
259    my ($cur_schema) = $sth->fetchrow_array;
260    unless($cur_schema) { return "old"; }
261
262    return $cur_schema;
263}
264
265# Is an upgrade to the database required?
266sub get_database_upgrade_required {
267    my ($dbh,$new_version) = @_;
268
269    # Get the schema version
270    my $schema_version = get_database_version($dbh);
271
272    # Compare it
273    if($schema_version eq $new_version) {
274        # At latest version
275        return undef;
276    } elsif ($schema_version eq 'old' or $schema_version < $new_version) {
277        return $schema_version."_to_".$new_version;
278    } else {
279        die "Aiee! We seem to be trying to downgrade the database schema from $schema_version to $new_version. Aborting.\n";
280    }
281}
282
283# Put the latest data into the latest database structure
284sub bulk_data_insert {
285    my ($dbh, $nodesref, $contentsref, $metadataref, $internallinksref) = @_;
286
287    print "Bulk inserting upgraded data... ";
288
289    # Add nodes
290    my $sth = $dbh->prepare("INSERT INTO node (id,name,version,text,modified,moderate) VALUES (?,?,?,?,?,?)");
291    foreach my $name (keys %$nodesref) {
292        my %node = %{$nodesref->{$name}};
293        $sth->execute($node{'id'},
294                      $node{'name'},
295                      $node{'version'},
296                      $node{'text'},
297                      $node{'modified'},
298                      $node{'moderate'});
299    }
300    print "added ".(scalar keys %$nodesref)." nodes...  ";
301
302    # Add content
303    $sth = $dbh->prepare("INSERT INTO content (node_id,version,text,modified,comment,moderated) VALUES (?,?,?,?,?,?)");
304    foreach my $key (keys %$contentsref) {
305        my %content = %{$contentsref->{$key}};
306        $sth->execute($content{'node_id'},
307                      $content{'version'},
308                      $content{'text'},
309                      $content{'modified'},
310                      $content{'comment'},
311                      $content{'moderated'});
312    }
313
314    # Add metadata
315    $sth = $dbh->prepare("INSERT INTO metadata (node_id,version,metadata_type,metadata_value) VALUES (?,?,?,?)");
316    foreach my $key (keys %$metadataref) {
317        my %metadata = %{$metadataref->{$key}};
318        $sth->execute($metadata{'node_id'},
319                      $metadata{'version'},
320                      $metadata{'metadata_type'},
321                      $metadata{'metadata_value'});
322    }
323
324    # Add internal links
325    $sth = $dbh->prepare("INSERT INTO internal_links (link_from,link_to) VALUES (?,?)");
326    foreach my $ilr (@$internallinksref) {
327        my %il = %{$ilr};
328        $sth->execute($il{'link_from'},
329                      $il{'link_to'});
330    }
331
332    print "done\n";
333}
334
335sub perm_check {
336    my $dbh = shift;
337    # If we can do all this, we'll be able to do a bulk upgrade too
338    eval {
339        my $sth = $dbh->prepare("CREATE TABLE dbtest (test int)");
340        $sth->execute;
341
342        $sth = $dbh->prepare("CREATE INDEX dbtest_index ON dbtest (test)");
343        $sth->execute;
344
345        $sth = $dbh->prepare("DROP TABLE dbtest");
346        $sth->execute;
347    };
348    return $@;
349}
Note: See TracBrowser for help on using the browser.