1 |
#!/usr/bin/perl -w |
2 |
# |
3 |
# This script will convert (on-the-fly) content of your MySQL libdata |
4 |
# database to PostgreSQL. It's mostly useful if you do migration from |
5 |
# MySQL to PostgreSQL or development of PostgreSQL version. |
6 |
# |
7 |
# 2003-03-05 Dobrica Pavlinusic <dpavlin@rot13.org> |
8 |
# |
9 |
# TODO: convert session data |
10 |
|
11 |
use DBI; |
12 |
use strict; |
13 |
use Getopt::Long; |
14 |
|
15 |
my $mydsn = "DBI:mysql:database=libdata;host=localhost"; |
16 |
my $mydbh = DBI->connect($mydsn, 'root', '', {'RaiseError' => 1}); |
17 |
my $pgdsn = "DBI:Pg:dbname=libdata"; |
18 |
my $pgdbh = DBI->connect($pgdsn, 'dpavlin', '', {'RaiseError' => 1}); |
19 |
|
20 |
$pgdbh->begin_work; |
21 |
|
22 |
# fix pagetitle_style which is reset to 0 instead of null |
23 |
$mydbh->do("update page set pagetitle_style = null where pagetitle_style = 0"); |
24 |
|
25 |
# fix substats which aren't referenced any more |
26 |
# this sucks, bug MySQL doesn't have sub-selects |
27 |
my @sub_ids; |
28 |
my $mysth = $mydbh->prepare("SELECT subject_id FROM subject"); |
29 |
$mysth->execute(); |
30 |
while (my ($id) = $mysth->fetchrow_array()) { |
31 |
push @sub_ids,$id; |
32 |
} |
33 |
$mydbh->do("delete from libstats.substats where subject_id not in (".join(",",@sub_ids).")"); |
34 |
|
35 |
# you might need to add more fixes like this if your database |
36 |
# is more broken than mine. |
37 |
|
38 |
# order of table is important to preserve referential integrity! |
39 |
my @tables = qw(access campus coursesub term style pagetype page course |
40 |
stafftitle staff faculty course_personnel service servicetype location |
41 |
subject mastersubject infotype resource element feature libunit |
42 |
libunit_staff masterinfotype page_staff pastebuffer res_feature res_loc |
43 |
res_mastersubject res_sub_infotype serv_loc serv_servtype sub_coursesub |
44 |
sub_loc sub_mastersubject sub_othersub sub_page sub_staff |
45 |
libstats.elementstats libstats.pagestats libstats.substats); |
46 |
|
47 |
foreach my $table (@tables) { |
48 |
print "working on '$table'\n"; |
49 |
|
50 |
$pgdbh->do("delete from $table"); |
51 |
|
52 |
my $mysth = $mydbh->prepare("select * from $table"); |
53 |
$mysth->execute(); |
54 |
|
55 |
my $pgsth; |
56 |
|
57 |
while (my @row = $mysth->fetchrow_array()) { |
58 |
|
59 |
# prepare insert statement if it doesn't exist! |
60 |
if (! $pgsth) { |
61 |
my $sql = "insert into $table values ("; |
62 |
$sql .= "?," x scalar @row; |
63 |
$sql =~ s/,$//; |
64 |
$sql .= ")"; |
65 |
$pgsth = $pgdbh->prepare($sql); |
66 |
} |
67 |
|
68 |
$pgsth->execute(@row); |
69 |
} |
70 |
|
71 |
$mysth->finish(); |
72 |
$pgsth->finish() if ($pgsth); |
73 |
|
74 |
} |
75 |
|
76 |
# fix sequences |
77 |
my @sequences = qw(access_access_id_seq campus_campus_id_seq |
78 |
coursesub_coursesub_id_seq term_term_id_seq style_style_id_seq |
79 |
pagetype_pagetype_id_seq page_page_id_seq course_course_id_seq |
80 |
stafftitle_stafftitle_id_seq staff_staff_id_seq faculty_faculty_id_seq |
81 |
course_personnel_personnel_id_seq service_service_id_seq |
82 |
servicetype_servicetype_id_seq location_location_id_seq subject_subject_id_seq |
83 |
mastersubject_mastersubject_id_seq infotype_infotype_id_seq |
84 |
resource_resource_id_seq element_element_id_seq feature_feature_id_seq |
85 |
libunit_libunit_id_seq masterinfotype_masterinfotype_id_seq |
86 |
pastebuffer_pastebuffer_id_seq libstats.elementstats_elementstats_id_seq |
87 |
libstats.pagestats_pagestats_id_seq libstats.substats_substats_id_seq |
88 |
session_key_id_seq); |
89 |
|
90 |
foreach my $seq (@sequences) { |
91 |
print "working on '$seq'\n"; |
92 |
|
93 |
my $col; |
94 |
my $table; |
95 |
if ($seq =~ m/^([\w\.]+)_(\w+_id)_seq$/) { |
96 |
($table,$col) = ($1,$2); |
97 |
} else { |
98 |
die "can't decode sequence $seq into table name and column!"; |
99 |
} |
100 |
|
101 |
# maximum sequence name for PostgreSQL is 28 chars |
102 |
my $seq = substr($seq,0,28 + index($seq,'.') + 1); |
103 |
|
104 |
my $sql = "select setval('$seq',(select case when max($col)>0 then max($col)+1 else 1 end from $table))"; |
105 |
$pgdbh->do("select setval('$seq',(select case when max($col)>0 then max($col)+1 else 1 end from $table))"); |
106 |
} |
107 |
|
108 |
# reset all passwords to libdata |
109 |
$pgdbh->do("update staff set password=md5('libdata') where staff_id > 1"); |
110 |
|
111 |
$pgdbh->commit; |
112 |
|
113 |
$mydbh->disconnect(); |
114 |
$pgdbh->disconnect(); |
115 |
|