blackwinter-flattendb 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ChangeLog ADDED
@@ -0,0 +1,5 @@
1
+ = Revision history for flattendb
2
+
3
+ == x.y.z [yyyy-mm-dd]
4
+
5
+ * ...
data/README ADDED
@@ -0,0 +1,42 @@
1
+ = flattendb - Flatten relational databases
2
+
3
+ == VERSION
4
+
5
+ This documentation refers to flattendb version 0.0.4
6
+
7
+
8
+ == DESCRIPTION
9
+
10
+ TODO: well, the description... ;-)
11
+
12
+
13
+ == LINKS
14
+
15
+ <b></b>
16
+ Documentation:: <http://prometheus.rubyforge.org/flattendb>
17
+ Source code (old):: <http://prometheus.rubyforge.org/svn/scratch/flattendb>
18
+ Source code:: <http://github.com/blackwinter/flattendb>
19
+ Rubyforge project:: <http://rubyforge.org/projects/prometheus>
20
+
21
+
22
+ == AUTHORS
23
+
24
+ * Jens Wille <mailto:jens.wille@uni-koeln.de>
25
+
26
+
27
+ == LICENSE AND COPYRIGHT
28
+
29
+ Copyright (C) 2007 University of Cologne,
30
+ Albertus-Magnus-Platz, 50932 Cologne, Germany
31
+
32
+ flattendb is free software: you can redistribute it and/or modify it under the
33
+ terms of the GNU General Public License as published by the Free Software
34
+ Foundation, either version 3 of the License, or (at your option) any later
35
+ version.
36
+
37
+ flattendb is distributed in the hope that it will be useful, but WITHOUT ANY
38
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
39
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
40
+
41
+ You should have received a copy of the GNU General Public License along with
42
+ flattendb. If not, see <http://www.gnu.org/licenses/>.
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'hen'
3
+ rescue LoadError
4
+ abort "Please install the 'hen' gem first."
5
+ end
6
+
7
+ require 'lib/flattendb/version'
8
+
9
+ Hen.lay! {{
10
+ :rubyforge => {
11
+ :package => 'flattendb'
12
+ },
13
+
14
+ :gem => {
15
+ :version => FlattenDB::VERSION,
16
+ :summary => 'Flatten relational databases.',
17
+ :files => FileList['lib/**/*.rb', 'bin/*'].to_a,
18
+ :extra_files => FileList['[A-Z]*', 'example/*'].to_a,
19
+ :dependencies => %w[highline libxml-ruby builder ruby-nuggets]
20
+ }
21
+ }}
data/bin/flattendb ADDED
@@ -0,0 +1,195 @@
1
+ #! /usr/bin/ruby
2
+
3
+ #--
4
+ ###############################################################################
5
+ # #
6
+ # flattendb -- Flatten relational databases #
7
+ # #
8
+ # Copyright (C) 2007 University of Cologne, #
9
+ # Albertus-Magnus-Platz, #
10
+ # 50932 Cologne, Germany #
11
+ # #
12
+ # Authors: #
13
+ # Jens Wille <jens.wille@uni-koeln.de> #
14
+ # #
15
+ # flattendb is free software; you can redistribute it and/or modify it under #
16
+ # the terms of the GNU General Public License as published by the Free #
17
+ # Software Foundation; either version 3 of the License, or (at your option) #
18
+ # any later version. #
19
+ # #
20
+ # flattendb is distributed in the hope that it will be useful, but WITHOUT #
21
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
22
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
23
+ # more details. #
24
+ # #
25
+ # You should have received a copy of the GNU General Public License along #
26
+ # with flattendb. If not, see <http://www.gnu.org/licenses/>. #
27
+ # #
28
+ ###############################################################################
29
+ #++
30
+
31
+ require 'optparse'
32
+
33
+ require 'rubygems'
34
+ require 'highline/import'
35
+ require 'nuggets/array/flatten_once'
36
+
37
+ $: << File.join(File.dirname(__FILE__), '..', 'lib')
38
+
39
+ require 'flattendb'
40
+ require 'flattendb/cli'
41
+
42
+ include FlattenDB::CLI
43
+
44
+ USAGE = "Usage: #{$0} [-h|--help] [options]"
45
+ abort USAGE if ARGV.empty?
46
+
47
+ $global_options = {
48
+ :type => :mysql,
49
+ :infiles => [],
50
+ :outfile => nil,
51
+ :confile => nil,
52
+ :keep => false,
53
+ :mysql => {
54
+ :intype => :xml
55
+ },
56
+ :mdb => {
57
+ :intype => :mdb
58
+ }
59
+ }
60
+
61
+ $opts_by_type = {
62
+ :mysql => {
63
+ :title => 'MySQL',
64
+ :opts => lambda { |opts|
65
+ opts.on('-x', '--mysql-xml', "Input file is of type XML [This is the default]") {
66
+ $global_options[:mysql][:intype] = :xml
67
+ }
68
+ opts.on('-s', '--sql', "Input file is of type SQL") {
69
+ $global_options[:mysql][:intype] = :sql
70
+ }
71
+ }
72
+ },
73
+ :mdb => {
74
+ :title => 'MS Access',
75
+ :opts => lambda { |opts|
76
+ opts.on('-m', '--mdb', "Input file is of type MDB [This is the default]") {
77
+ $global_options[:mdb][:intype] = :mdb
78
+ }
79
+ opts.on('-y', '--mdb-xml', "Input file is of type XML") {
80
+ $global_options[:mdb][:intype] = :xml
81
+ }
82
+ }
83
+ }
84
+ }
85
+
86
+ def type_options(type, opts, with_heading = true)
87
+ if type == :all
88
+ $opts_by_type.keys.sort_by { |t| t.to_s }.each { |t|
89
+ type_options(t, opts, with_heading)
90
+ }
91
+ else
92
+ opt = $opts_by_type[type.to_sym]
93
+
94
+ if with_heading
95
+ opts.separator ''
96
+ opts.separator " - [#{type}] #{opt[:title]}"
97
+ end
98
+
99
+ opt[:opts][opts]
100
+ end
101
+ end
102
+
103
+ OptionParser.new { |opts|
104
+ opts.banner = USAGE
105
+
106
+ opts.separator ''
107
+ opts.separator 'Options:'
108
+
109
+ if $type
110
+ opts.separator " [-t, --type] TYPE OVERRIDE IN EFFECT (#{$type})"
111
+ else
112
+ opts.on('-t', '--type TYPE', "Type of database at hand [Default: #{$global_options[:type]}]") { |t|
113
+ $global_options[:type] = t.downcase.to_sym
114
+ }
115
+ end
116
+
117
+ opts.separator ''
118
+
119
+ opts.on('-i', '--input-file FILE', "Input file; depending on the database type, this option", "may be given multiple times [REQUIRED]") { |f|
120
+ $global_options[:infiles] << f
121
+ }
122
+
123
+ opts.on('-o', '--output-file FILE', "Output file (flat XML) [REQUIRED]") { |f|
124
+ $global_options[:outfile] = f
125
+ }
126
+
127
+ opts.on('-c', '--config-file FILE', "Configuration file (YAML) [REQUIRED]") { |f|
128
+ $global_options[:confile] = f
129
+ }
130
+
131
+ opts.separator ''
132
+
133
+ opts.on('-k', '--keep', "Keep any intermediate files (generated XML dumps, etc.)") {
134
+ $global_options[:keep] = true
135
+ }
136
+
137
+ opts.separator ''
138
+ opts.separator 'Database-specific Options:'
139
+
140
+ if $type
141
+ type_options($type, opts, false)
142
+ else
143
+ type_options(:all, opts)
144
+ end
145
+
146
+ opts.separator ''
147
+ opts.separator 'Generic options:'
148
+
149
+ opts.on('-h', '--help', 'Print this help message and exit') {
150
+ abort opts.to_s
151
+ }
152
+
153
+ opts.on('--version', 'Print program version and exit') {
154
+ abort "#{File.basename($0)} v#{FlattenDB::VERSION}"
155
+ }
156
+ }.parse!
157
+
158
+ $type ||= $global_options[:type]
159
+ $options = $global_options[$type] || {}
160
+
161
+ # Load corresponding module
162
+ begin
163
+ require "flattendb/types/#{$type}"
164
+ rescue LoadError
165
+ abort "Database type '#{$type}' is not supported at the moment."
166
+ end
167
+
168
+ abort "No output file specified" unless $global_options[:outfile]
169
+
170
+ if confile = $global_options[:confile]
171
+ abort "Configuration file not found: #{confile}" unless File.readable?(confile)
172
+ else
173
+ abort "No configuration file specified"
174
+ end
175
+
176
+ $global_options[:infiles].each { |infile|
177
+ abort "Input file not found: #{infile}" unless File.readable?(infile)
178
+ }
179
+
180
+ $infiles = $global_options[:infiles]
181
+ $outfile = $global_options[:outfile]
182
+ $confile = $global_options[:confile]
183
+
184
+ # Load type-specific script
185
+ begin
186
+ load File.join(File.dirname(__FILE__), "flattendb.#{$type}")
187
+ rescue LoadError
188
+ # silently ignore
189
+ end
190
+
191
+ FlattenDB[$type].new($infile || $infiles, $outfile, $confile).flatten!.to_xml
192
+
193
+ unless $global_options[:keep]
194
+ File.delete($dump_file) if $dump_file
195
+ end
data/bin/flattendb.mdb ADDED
@@ -0,0 +1,55 @@
1
+ #! /usr/bin/ruby
2
+
3
+ # vi:ft=ruby
4
+
5
+ #--
6
+ ###############################################################################
7
+ # #
8
+ # flattendb -- Flatten relational databases #
9
+ # #
10
+ # Copyright (C) 2007 University of Cologne, #
11
+ # Albertus-Magnus-Platz, #
12
+ # 50932 Cologne, Germany #
13
+ # #
14
+ # Authors: #
15
+ # Jens Wille <jens.wille@uni-koeln.de> #
16
+ # #
17
+ # flattendb is free software; you can redistribute it and/or modify it under #
18
+ # the terms of the GNU General Public License as published by the Free #
19
+ # Software Foundation; either version 3 of the License, or (at your option) #
20
+ # any later version. #
21
+ # #
22
+ # flattendb is distributed in the hope that it will be useful, but WITHOUT #
23
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
24
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
25
+ # more details. #
26
+ # #
27
+ # You should have received a copy of the GNU General Public License along #
28
+ # with flattendb. If not, see <http://www.gnu.org/licenses/>. #
29
+ # #
30
+ ###############################################################################
31
+ #++
32
+
33
+ unless $type
34
+ $type = :mdb
35
+ load File.join(File.dirname(__FILE__), 'flattendb')
36
+ else
37
+ case $options[:intype]
38
+ when :xml
39
+ $infiles.each { |infile|
40
+ unless IO.read(infile, 6) == '<?xml '
41
+ abort "Input file doesn't seem to be a valid XML file, XML declaration missing: #{infile}"
42
+ end
43
+ }
44
+ when :mdb
45
+ tables_cmd = 'mdb-tables'
46
+ export_cmd = 'mdb-export'
47
+
48
+ require_commands(tables_cmd, export_cmd, :pkg => 'mdbtools')
49
+ require_libraries('fastercsv')
50
+
51
+ $infiles.map! { |infile|
52
+ $dump_file
53
+ }
54
+ end
55
+ end
@@ -0,0 +1,91 @@
1
+ #! /usr/bin/ruby
2
+
3
+ # vi:ft=ruby
4
+
5
+ #--
6
+ ###############################################################################
7
+ # #
8
+ # flattendb -- Flatten relational databases #
9
+ # #
10
+ # Copyright (C) 2007 University of Cologne, #
11
+ # Albertus-Magnus-Platz, #
12
+ # 50932 Cologne, Germany #
13
+ # #
14
+ # Authors: #
15
+ # Jens Wille <jens.wille@uni-koeln.de> #
16
+ # #
17
+ # flattendb is free software; you can redistribute it and/or modify it under #
18
+ # the terms of the GNU General Public License as published by the Free #
19
+ # Software Foundation; either version 3 of the License, or (at your option) #
20
+ # any later version. #
21
+ # #
22
+ # flattendb is distributed in the hope that it will be useful, but WITHOUT #
23
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
24
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
25
+ # more details. #
26
+ # #
27
+ # You should have received a copy of the GNU General Public License along #
28
+ # with flattendb. If not, see <http://www.gnu.org/licenses/>. #
29
+ # #
30
+ ###############################################################################
31
+ #++
32
+
33
+ unless $type
34
+ $type = :mysql
35
+ load File.join(File.dirname(__FILE__), 'flattendb')
36
+ else
37
+ $infile = $infiles.first
38
+
39
+ case $options[:intype]
40
+ when :xml
41
+ unless IO.read($infile, 6) == '<?xml '
42
+ abort "Input file doesn't seem to be a valid XML file, XML declaration missing"
43
+ end
44
+ when :sql
45
+ $dump_file = $infile.sub(/\.(?:sql|dump)$/i, '') << '.xml'
46
+ abort "Dump file and output file are the same: #{$dump_file} = #{$outfile}" \
47
+ if File.expand_path($dump_file) == File.expand_path($outfile)
48
+
49
+ mysql_cmd = 'mysql'
50
+ dump_cmd = 'mysqldump'
51
+
52
+ require_commands(mysql_cmd, dump_cmd, :pkg => 'a suitable MySQL client')
53
+ require_libraries('mysql')
54
+
55
+ mysql_user = ask('Please enter the MySQL user name: ') \
56
+ { |q| q.default = ENV['USER'] }
57
+ mysql_pass = ask("Please enter the MySQL password for that user: ") \
58
+ { |q| q.echo = false }
59
+
60
+ # according to <http://www.adamspiers.org/computing/mysqldiff/#how> MySQL
61
+ # default permissions allow anyone to create databases beginning with the
62
+ # prefix 'test_'
63
+ temp_db = 'flattendb_temp_%d_%d' % [Time.now, $$]
64
+ temp_user = 'flattendb_user'
65
+ temp_pass = 'flattendb_pass'
66
+
67
+ mysql_args = "--one-database -u#{temp_user} -p#{temp_pass} #{temp_db} < #{$infile}"
68
+ dump_args = "--xml -u#{temp_user} -p#{temp_pass} #{temp_db} > #{$dump_file}"
69
+
70
+ begin
71
+ mysql = Mysql.real_connect('localhost', mysql_user, mysql_pass)
72
+
73
+ mysql.query("CREATE DATABASE #{temp_db}")
74
+ mysql.query("GRANT ALL ON #{temp_db}.* TO '#{temp_user}'@'localhost' IDENTIFIED BY '#{temp_pass}'")
75
+
76
+ system("#{mysql_cmd} #{mysql_args} && #{dump_cmd} #{dump_args}")
77
+ rescue Mysql::Error => err
78
+ abort "ERROR #{err.errno} (#{err.sqlstate}): #{err.error}"
79
+ ensure
80
+ if mysql
81
+ mysql.query("REVOKE ALL ON #{temp_db}.* FROM '#{temp_user}'@'localhost'") \
82
+ if mysql_user == 'root'
83
+
84
+ mysql.query("DROP DATABASE IF EXISTS #{temp_db}")
85
+ mysql.close
86
+ end
87
+ end
88
+
89
+ $infile = $dump_file
90
+ end
91
+ end
@@ -0,0 +1,120 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <ndr>
3
+ <row>
4
+ <Bla>12</Bla>
5
+ <Blub></Blub>
6
+ <ObjID>1</ObjID>
7
+ <attr1>
8
+ <ObjID>1</ObjID>
9
+ <Val>3</Val>
10
+ <attr1ID>1</attr1ID>
11
+ </attr1>
12
+ <attr2>
13
+ <ObjID>1</ObjID>
14
+ <Val>4</Val>
15
+ <attr2ID>3</attr2ID>
16
+ </attr2>
17
+ <barobject>
18
+ <Bar>1002</Bar>
19
+ <ObjID>1</ObjID>
20
+ <attr4>
21
+ <Val>0</Val>
22
+ <attr4ID>2</attr4ID>
23
+ </attr4>
24
+ <attr4ID>2</attr4ID>
25
+ </barobject>
26
+ <fooobject>
27
+ <Foo>112</Foo>
28
+ <ObjID>1</ObjID>
29
+ <attr1>
30
+ <ObjID>1</ObjID>
31
+ <Val>3</Val>
32
+ <attr1ID>1</attr1ID>
33
+ </attr1>
34
+ <attr1ID>1</attr1ID>
35
+ <attr3>
36
+ <Val>8</Val>
37
+ <attr3ID>2</attr3ID>
38
+ </attr3>
39
+ <attr3ID>2</attr3ID>
40
+ </fooobject>
41
+ </row>
42
+ <row>
43
+ <Bla>12</Bla>
44
+ <Blub>hi</Blub>
45
+ <ObjID>2</ObjID>
46
+ <attr1>
47
+ <ObjID>2</ObjID>
48
+ <Val>2</Val>
49
+ <attr1ID>2</attr1ID>
50
+ </attr1>
51
+ <attr2>
52
+ <ObjID>2</ObjID>
53
+ <Val>5</Val>
54
+ <attr2ID>2</attr2ID>
55
+ </attr2>
56
+ <barobject>
57
+ <Bar>1200</Bar>
58
+ <ObjID>2</ObjID>
59
+ <attr4>
60
+ <Val>0</Val>
61
+ <attr4ID>1</attr4ID>
62
+ </attr4>
63
+ <attr4ID>1</attr4ID>
64
+ </barobject>
65
+ <fooobject>
66
+ <Foo>122</Foo>
67
+ <ObjID>2</ObjID>
68
+ <attr1>
69
+ <ObjID>2</ObjID>
70
+ <Val>2</Val>
71
+ <attr1ID>2</attr1ID>
72
+ </attr1>
73
+ <attr1ID>2</attr1ID>
74
+ <attr3>
75
+ <Val>0</Val>
76
+ <attr3ID>1</attr3ID>
77
+ </attr3>
78
+ <attr3ID>1</attr3ID>
79
+ </fooobject>
80
+ </row>
81
+ <row>
82
+ <Bla>1</Bla>
83
+ <Blub>ho</Blub>
84
+ <ObjID>3</ObjID>
85
+ <attr1>
86
+ <ObjID>3</ObjID>
87
+ <Val>1</Val>
88
+ <attr1ID>3</attr1ID>
89
+ </attr1>
90
+ <attr2>
91
+ <ObjID>3</ObjID>
92
+ <Val>6</Val>
93
+ <attr2ID>1</attr2ID>
94
+ </attr2>
95
+ <barobject>
96
+ <Bar>1000</Bar>
97
+ <ObjID>3</ObjID>
98
+ <attr4>
99
+ <Val>9</Val>
100
+ <attr4ID>3</attr4ID>
101
+ </attr4>
102
+ <attr4ID>3</attr4ID>
103
+ </barobject>
104
+ <fooobject>
105
+ <Foo>111</Foo>
106
+ <ObjID>3</ObjID>
107
+ <attr1>
108
+ <ObjID>3</ObjID>
109
+ <Val>1</Val>
110
+ <attr1ID>3</attr1ID>
111
+ </attr1>
112
+ <attr1ID>3</attr1ID>
113
+ <attr3>
114
+ <Val>7</Val>
115
+ <attr3ID>3</attr3ID>
116
+ </attr3>
117
+ <attr3ID>3</attr3ID>
118
+ </fooobject>
119
+ </row>
120
+ </ndr>