flattendb 0.0.1.96
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/COPYING +676 -0
- data/ChangeLog +5 -0
- data/README +33 -0
- data/Rakefile +23 -0
- data/bin/flattendb +129 -0
- data/bin/flattendb.mysql +97 -0
- data/example/mysql-sample.flat.xml +120 -0
- data/example/mysql-sample.sql +0 -0
- data/example/mysql-sample.xml +162 -0
- data/example/mysql-sample2flat.yaml +10 -0
- data/lib/flattendb/base.rb +99 -0
- data/lib/flattendb/mysql.rb +199 -0
- data/lib/flattendb/version.rb +55 -0
- data/lib/flattendb.rb +40 -0
- metadata +97 -0
@@ -0,0 +1,199 @@
|
|
1
|
+
#--
|
2
|
+
###############################################################################
|
3
|
+
# #
|
4
|
+
# A component of flattendb, the relational database flattener. #
|
5
|
+
# #
|
6
|
+
# Copyright (C) 2007 University of Cologne, #
|
7
|
+
# Albertus-Magnus-Platz, #
|
8
|
+
# 50932 Cologne, Germany #
|
9
|
+
# #
|
10
|
+
# Authors: #
|
11
|
+
# Jens Wille <jens.wille@uni-koeln.de> #
|
12
|
+
# #
|
13
|
+
# flattendb is free software; you can redistribute it and/or modify it under #
|
14
|
+
# the terms of the GNU General Public License as published by the Free #
|
15
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
16
|
+
# any later version. #
|
17
|
+
# #
|
18
|
+
# flattendb is distributed in the hope that it will be useful, but WITHOUT #
|
19
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
20
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
21
|
+
# more details. #
|
22
|
+
# #
|
23
|
+
# You should have received a copy of the GNU General Public License along #
|
24
|
+
# with flattendb. If not, see <http://www.gnu.org/licenses/>. #
|
25
|
+
# #
|
26
|
+
###############################################################################
|
27
|
+
#++
|
28
|
+
|
29
|
+
require 'yaml'
|
30
|
+
require 'xml/libxml'
|
31
|
+
|
32
|
+
require 'flattendb/base'
|
33
|
+
|
34
|
+
module FlattenDB
|
35
|
+
|
36
|
+
class MySQL < Base
|
37
|
+
|
38
|
+
JOIN_KEY = '@key'
|
39
|
+
|
40
|
+
attr_reader :root, :config, :output, :document, :database, :name, :tables, :builder
|
41
|
+
|
42
|
+
def initialize(infile, outfile, config)
|
43
|
+
config = case config
|
44
|
+
when Hash
|
45
|
+
config
|
46
|
+
when String
|
47
|
+
# assume file name
|
48
|
+
YAML.load_file(config)
|
49
|
+
else
|
50
|
+
raise ArgumentError, "invalid config argument of type '#{config.class}'"
|
51
|
+
end
|
52
|
+
raise ArgumentError, "can't have more than one primary (root) table" if config.size > 1
|
53
|
+
|
54
|
+
(@root, @config), _ = *config # get "first" (and only) hash element
|
55
|
+
|
56
|
+
@output = case outfile
|
57
|
+
when IO
|
58
|
+
outfile
|
59
|
+
when String
|
60
|
+
# assume file name
|
61
|
+
File.open(outfile, 'w')
|
62
|
+
else
|
63
|
+
raise ArgumentError, "invalid outfile argument of type '#{outfile.class}'"
|
64
|
+
end
|
65
|
+
|
66
|
+
@document = XML::Document.file(case infile
|
67
|
+
when String
|
68
|
+
infile
|
69
|
+
when File
|
70
|
+
infile.path
|
71
|
+
else
|
72
|
+
raise ArgumentError, "invalid infile argument of type '#{infile.class}'"
|
73
|
+
end)
|
74
|
+
|
75
|
+
@database = @document.root.find_first('database[@name]')
|
76
|
+
@name = @database[:name]
|
77
|
+
@tables = {}
|
78
|
+
|
79
|
+
parse
|
80
|
+
end
|
81
|
+
|
82
|
+
def flatten!(options = {}, builder_options = {})
|
83
|
+
flatten_tables!(tables, root, config)
|
84
|
+
|
85
|
+
self
|
86
|
+
end
|
87
|
+
|
88
|
+
def to_xml(output = output, builder_options = {})
|
89
|
+
initialize_builder(:xml, output, builder_options)
|
90
|
+
|
91
|
+
builder.instruct!
|
92
|
+
|
93
|
+
if tables.size > 1
|
94
|
+
builder.tag!(name) {
|
95
|
+
tables.sort.each { |table, rows|
|
96
|
+
table_to_xml(table, rows, builder)
|
97
|
+
}
|
98
|
+
}
|
99
|
+
else
|
100
|
+
(table, rows), _ = *tables # get "first" (and only) hash element
|
101
|
+
table_to_xml(name, rows, builder)
|
102
|
+
end
|
103
|
+
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def parse
|
110
|
+
database.find('table_data[@name]').each { |table|
|
111
|
+
rows = []
|
112
|
+
|
113
|
+
table.find('row').each { |row|
|
114
|
+
fields = {}
|
115
|
+
|
116
|
+
row.find('field[@name]').each { |field|
|
117
|
+
fields[field[:name]] = field.content
|
118
|
+
}
|
119
|
+
|
120
|
+
rows << fields
|
121
|
+
}
|
122
|
+
|
123
|
+
tables[table[:name]] = rows
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
def flatten_tables!(tables, primary_table, config)
|
128
|
+
config.each { |foreign_table, spec|
|
129
|
+
case spec
|
130
|
+
when String
|
131
|
+
inject_foreign(tables, primary_table, foreign_table, spec)
|
132
|
+
when Array
|
133
|
+
inject_foreign(tables, primary_table, foreign_table, *spec)
|
134
|
+
when Hash
|
135
|
+
raise "invalid join table spec, '#{JOIN_KEY}' missing" unless spec.has_key?(JOIN_KEY)
|
136
|
+
|
137
|
+
local_key, foreign_key = spec.delete(JOIN_KEY)
|
138
|
+
foreign_key ||= local_key
|
139
|
+
|
140
|
+
joined_tables = tables.dup
|
141
|
+
flatten_tables!(joined_tables, foreign_table, spec)
|
142
|
+
|
143
|
+
inject_foreign(tables, primary_table, foreign_table, local_key, foreign_key, joined_tables)
|
144
|
+
else
|
145
|
+
raise ArgumentError, "don't know how to handle spec of type '#{spec.class}'"
|
146
|
+
end
|
147
|
+
}
|
148
|
+
|
149
|
+
tables.delete_if { |table, _|
|
150
|
+
table != primary_table
|
151
|
+
}
|
152
|
+
end
|
153
|
+
|
154
|
+
def inject_foreign(tables, primary_table, foreign_table, local_key, foreign_key = local_key, foreign_tables = tables)
|
155
|
+
tables[primary_table].each { |row|
|
156
|
+
next unless row.has_key?(local_key)
|
157
|
+
|
158
|
+
foreign_content = foreign_tables[foreign_table].find_all { |foreign_row|
|
159
|
+
row[local_key] == foreign_row[foreign_key]
|
160
|
+
}
|
161
|
+
|
162
|
+
row[foreign_table] = foreign_content unless foreign_content.empty?
|
163
|
+
}
|
164
|
+
end
|
165
|
+
|
166
|
+
def table_to_xml(table, rows, builder)
|
167
|
+
builder.tag!(table) {
|
168
|
+
rows.each { |row|
|
169
|
+
row_to_xml('row', row, builder)
|
170
|
+
}
|
171
|
+
}
|
172
|
+
end
|
173
|
+
|
174
|
+
def row_to_xml(name, row, builder)
|
175
|
+
builder.tag!(name) {
|
176
|
+
row.sort.each { |field, content|
|
177
|
+
field_to_xml(field, content, builder)
|
178
|
+
}
|
179
|
+
}
|
180
|
+
end
|
181
|
+
|
182
|
+
def field_to_xml(field, content, builder)
|
183
|
+
case content
|
184
|
+
when String
|
185
|
+
builder.tag!(column_to_element(field), content)
|
186
|
+
when Array
|
187
|
+
content.each { |item|
|
188
|
+
field_to_xml(field, item, builder)
|
189
|
+
}
|
190
|
+
when Hash
|
191
|
+
row_to_xml(field, content, builder)
|
192
|
+
else
|
193
|
+
raise ArgumentError, "don't know how to handle content of type '#{content.class}'"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#--
|
2
|
+
###############################################################################
|
3
|
+
# #
|
4
|
+
# A component of flattendb, the relational database flattener. #
|
5
|
+
# #
|
6
|
+
# Copyright (C) 2007 University of Cologne, #
|
7
|
+
# Albertus-Magnus-Platz, #
|
8
|
+
# 50932 Cologne, Germany #
|
9
|
+
# #
|
10
|
+
# Authors: #
|
11
|
+
# Jens Wille <jens.wille@uni-koeln.de> #
|
12
|
+
# #
|
13
|
+
# flattendb is free software; you can redistribute it and/or modify it under #
|
14
|
+
# the terms of the GNU General Public License as published by the Free #
|
15
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
16
|
+
# any later version. #
|
17
|
+
# #
|
18
|
+
# flattendb is distributed in the hope that it will be useful, but WITHOUT #
|
19
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
20
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
21
|
+
# more details. #
|
22
|
+
# #
|
23
|
+
# You should have received a copy of the GNU General Public License along #
|
24
|
+
# with flattendb. If not, see <http://www.gnu.org/licenses/>. #
|
25
|
+
# #
|
26
|
+
###############################################################################
|
27
|
+
#++
|
28
|
+
|
29
|
+
module FlattenDB
|
30
|
+
|
31
|
+
module Version
|
32
|
+
|
33
|
+
MAJOR = 0
|
34
|
+
MINOR = 0
|
35
|
+
TINY = 1
|
36
|
+
|
37
|
+
class << self
|
38
|
+
|
39
|
+
# Returns array representation.
|
40
|
+
def to_a
|
41
|
+
[MAJOR, MINOR, TINY]
|
42
|
+
end
|
43
|
+
|
44
|
+
# Short-cut for version string.
|
45
|
+
def to_s
|
46
|
+
to_a.join('.')
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
VERSION = Version.to_s
|
54
|
+
|
55
|
+
end
|
data/lib/flattendb.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#--
|
2
|
+
###############################################################################
|
3
|
+
# #
|
4
|
+
# flattendb -- Flatten relational databases #
|
5
|
+
# #
|
6
|
+
# Copyright (C) 2007 University of Cologne, #
|
7
|
+
# Albertus-Magnus-Platz, #
|
8
|
+
# 50932 Cologne, Germany #
|
9
|
+
# #
|
10
|
+
# Authors: #
|
11
|
+
# Jens Wille <jens.wille@uni-koeln.de> #
|
12
|
+
# #
|
13
|
+
# flattendb is free software; you can redistribute it and/or modify it under #
|
14
|
+
# the terms of the GNU General Public License as published by the Free #
|
15
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
16
|
+
# any later version. #
|
17
|
+
# #
|
18
|
+
# flattendb is distributed in the hope that it will be useful, but WITHOUT #
|
19
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
20
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
21
|
+
# more details. #
|
22
|
+
# #
|
23
|
+
# You should have received a copy of the GNU General Public License along #
|
24
|
+
# with flattendb. If not, see <http://www.gnu.org/licenses/>. #
|
25
|
+
# #
|
26
|
+
###############################################################################
|
27
|
+
#++
|
28
|
+
|
29
|
+
require 'flattendb/version'
|
30
|
+
require 'flattendb/base'
|
31
|
+
|
32
|
+
module FlattenDB
|
33
|
+
|
34
|
+
extend self
|
35
|
+
|
36
|
+
def [](type)
|
37
|
+
Base[type]
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.4
|
3
|
+
specification_version: 1
|
4
|
+
name: flattendb
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1.96
|
7
|
+
date: 2007-10-11 00:00:00 +02:00
|
8
|
+
summary: Flatten relational databases
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: jens.wille@uni-koeln.de
|
12
|
+
homepage:
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Jens Wille
|
31
|
+
files:
|
32
|
+
- lib/flattendb.rb
|
33
|
+
- lib/flattendb/version.rb
|
34
|
+
- lib/flattendb/mysql.rb
|
35
|
+
- lib/flattendb/base.rb
|
36
|
+
- bin/flattendb
|
37
|
+
- bin/flattendb.mysql
|
38
|
+
- COPYING
|
39
|
+
- README
|
40
|
+
- ChangeLog
|
41
|
+
- Rakefile
|
42
|
+
- example/mysql-sample.sql
|
43
|
+
- example/mysql-sample2flat.yaml
|
44
|
+
- example/mysql-sample.flat.xml
|
45
|
+
- example/mysql-sample.xml
|
46
|
+
test_files: []
|
47
|
+
|
48
|
+
rdoc_options: []
|
49
|
+
|
50
|
+
extra_rdoc_files:
|
51
|
+
- README
|
52
|
+
- COPYING
|
53
|
+
- ChangeLog
|
54
|
+
executables:
|
55
|
+
- flattendb
|
56
|
+
- flattendb.mysql
|
57
|
+
extensions: []
|
58
|
+
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
dependencies:
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: highline
|
64
|
+
version_requirement:
|
65
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.0.0
|
70
|
+
version:
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: mysql
|
73
|
+
version_requirement:
|
74
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">"
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 0.0.0
|
79
|
+
version:
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: libxml-ruby
|
82
|
+
version_requirement:
|
83
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 0.0.0
|
88
|
+
version:
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: builder
|
91
|
+
version_requirement:
|
92
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.0.0
|
97
|
+
version:
|