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/COPYING +676 -0
- data/ChangeLog +5 -0
- data/README +42 -0
- data/Rakefile +21 -0
- data/bin/flattendb +195 -0
- data/bin/flattendb.mdb +55 -0
- data/bin/flattendb.mysql +91 -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 +18 -0
- data/lib/flattendb.rb +40 -0
- data/lib/flattendb/base.rb +139 -0
- data/lib/flattendb/cli.rb +79 -0
- data/lib/flattendb/types/mdb.rb +53 -0
- data/lib/flattendb/types/mysql.rb +176 -0
- data/lib/flattendb/version.rb +55 -0
- metadata +116 -0
File without changes
|
@@ -0,0 +1,162 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
3
|
+
<database name="ndr">
|
4
|
+
<table_structure name="object">
|
5
|
+
<field Field="ObjID" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
6
|
+
<field Field="Bla" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
7
|
+
<field Field="Blub" Type="varchar(50)" Null="YES" Key="" Extra="" />
|
8
|
+
<options Name="object" Engine="MyISAM" Version="10" Row_format="Fixed" Collation="utf8_general_ci" Create_options="" Comment="" />
|
9
|
+
</table_structure>
|
10
|
+
<table_data name="object">
|
11
|
+
<row>
|
12
|
+
<field name="ObjID">1</field>
|
13
|
+
<field name="Bla">12</field>
|
14
|
+
<field name="Blub"></field>
|
15
|
+
</row>
|
16
|
+
<row>
|
17
|
+
<field name="ObjID">2</field>
|
18
|
+
<field name="Bla">12</field>
|
19
|
+
<field name="Blub">hi</field>
|
20
|
+
</row>
|
21
|
+
<row>
|
22
|
+
<field name="ObjID">3</field>
|
23
|
+
<field name="Bla">1</field>
|
24
|
+
<field name="Blub">ho</field>
|
25
|
+
</row>
|
26
|
+
</table_data>
|
27
|
+
<table_structure name="fooobject">
|
28
|
+
<field Field="ObjID" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
29
|
+
<field Field="attr1ID" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
30
|
+
<field Field="attr3ID" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
31
|
+
<field Field="Foo" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
32
|
+
<options Name="fooobject" Engine="MyISAM" Version="10" Row_format="Fixed" Collation="utf8_general_ci" Create_options="" Comment="" />
|
33
|
+
</table_structure>
|
34
|
+
<table_data name="fooobject">
|
35
|
+
<row>
|
36
|
+
<field name="ObjID">1</field>
|
37
|
+
<field name="attr1ID">1</field>
|
38
|
+
<field name="attr3ID">2</field>
|
39
|
+
<field name="Foo">112</field>
|
40
|
+
</row>
|
41
|
+
<row>
|
42
|
+
<field name="ObjID">2</field>
|
43
|
+
<field name="attr1ID">2</field>
|
44
|
+
<field name="attr3ID">1</field>
|
45
|
+
<field name="Foo">122</field>
|
46
|
+
</row>
|
47
|
+
<row>
|
48
|
+
<field name="ObjID">3</field>
|
49
|
+
<field name="attr1ID">3</field>
|
50
|
+
<field name="attr3ID">3</field>
|
51
|
+
<field name="Foo">111</field>
|
52
|
+
</row>
|
53
|
+
</table_data>
|
54
|
+
<table_structure name="barobject">
|
55
|
+
<field Field="ObjID" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
56
|
+
<field Field="attr4ID" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
57
|
+
<field Field="Bar" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
58
|
+
<options Name="barobject" Engine="MyISAM" Version="10" Row_format="Fixed" Collation="utf8_general_ci" Create_options="" Comment="" />
|
59
|
+
</table_structure>
|
60
|
+
<table_data name="barobject">
|
61
|
+
<row>
|
62
|
+
<field name="ObjID">1</field>
|
63
|
+
<field name="attr4ID">2</field>
|
64
|
+
<field name="Bar">1002</field>
|
65
|
+
</row>
|
66
|
+
<row>
|
67
|
+
<field name="ObjID">2</field>
|
68
|
+
<field name="attr4ID">1</field>
|
69
|
+
<field name="Bar">1200</field>
|
70
|
+
</row>
|
71
|
+
<row>
|
72
|
+
<field name="ObjID">3</field>
|
73
|
+
<field name="attr4ID">3</field>
|
74
|
+
<field name="Bar">1000</field>
|
75
|
+
</row>
|
76
|
+
</table_data>
|
77
|
+
<table_structure name="attr1">
|
78
|
+
<field Field="ObjID" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
79
|
+
<field Field="attr1ID" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
80
|
+
<field Field="Val" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
81
|
+
<options Name="attr1" Engine="MyISAM" Version="10" Row_format="Fixed" Collation="utf8_general_ci" Create_options="" Comment="" />
|
82
|
+
</table_structure>
|
83
|
+
<table_data name="attr1">
|
84
|
+
<row>
|
85
|
+
<field name="ObjID">1</field>
|
86
|
+
<field name="attr1ID">1</field>
|
87
|
+
<field name="Val">3</field>
|
88
|
+
</row>
|
89
|
+
<row>
|
90
|
+
<field name="ObjID">2</field>
|
91
|
+
<field name="attr1ID">2</field>
|
92
|
+
<field name="Val">2</field>
|
93
|
+
</row>
|
94
|
+
<row>
|
95
|
+
<field name="ObjID">3</field>
|
96
|
+
<field name="attr1ID">3</field>
|
97
|
+
<field name="Val">1</field>
|
98
|
+
</row>
|
99
|
+
</table_data>
|
100
|
+
<table_structure name="attr2">
|
101
|
+
<field Field="ObjID" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
102
|
+
<field Field="attr2ID" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
103
|
+
<field Field="Val" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
104
|
+
<options Name="attr2" Engine="MyISAM" Version="10" Row_format="Fixed" Collation="utf8_general_ci" Create_options="" Comment="" />
|
105
|
+
</table_structure>
|
106
|
+
<table_data name="attr2">
|
107
|
+
<row>
|
108
|
+
<field name="ObjID">1</field>
|
109
|
+
<field name="attr2ID">3</field>
|
110
|
+
<field name="Val">4</field>
|
111
|
+
</row>
|
112
|
+
<row>
|
113
|
+
<field name="ObjID">2</field>
|
114
|
+
<field name="attr2ID">2</field>
|
115
|
+
<field name="Val">5</field>
|
116
|
+
</row>
|
117
|
+
<row>
|
118
|
+
<field name="ObjID">3</field>
|
119
|
+
<field name="attr2ID">1</field>
|
120
|
+
<field name="Val">6</field>
|
121
|
+
</row>
|
122
|
+
</table_data>
|
123
|
+
<table_structure name="attr3">
|
124
|
+
<field Field="attr3ID" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
125
|
+
<field Field="Val" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
126
|
+
<options Name="attr3" Engine="MyISAM" Version="10" Row_format="Fixed" Collation="utf8_general_ci" Create_options="" Comment="" />
|
127
|
+
</table_structure>
|
128
|
+
<table_data name="attr3">
|
129
|
+
<row>
|
130
|
+
<field name="attr3ID">1</field>
|
131
|
+
<field name="Val">0</field>
|
132
|
+
</row>
|
133
|
+
<row>
|
134
|
+
<field name="attr3ID">2</field>
|
135
|
+
<field name="Val">8</field>
|
136
|
+
</row>
|
137
|
+
<row>
|
138
|
+
<field name="attr3ID">3</field>
|
139
|
+
<field name="Val">7</field>
|
140
|
+
</row>
|
141
|
+
</table_data>
|
142
|
+
<table_structure name="attr4">
|
143
|
+
<field Field="attr4ID" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
144
|
+
<field Field="Val" Type="int(11)" Null="NO" Key="" Default="" Extra="" />
|
145
|
+
<options Name="attr4" Engine="MyISAM" Version="10" Row_format="Fixed" Collation="utf8_general_ci" Create_options="" Comment="" />
|
146
|
+
</table_structure>
|
147
|
+
<table_data name="attr4">
|
148
|
+
<row>
|
149
|
+
<field name="attr4ID">1</field>
|
150
|
+
<field name="Val">0</field>
|
151
|
+
</row>
|
152
|
+
<row>
|
153
|
+
<field name="attr4ID">2</field>
|
154
|
+
<field name="Val">0</field>
|
155
|
+
</row>
|
156
|
+
<row>
|
157
|
+
<field name="attr4ID">3</field>
|
158
|
+
<field name="Val">9</field>
|
159
|
+
</row>
|
160
|
+
</table_data>
|
161
|
+
</database>
|
162
|
+
</mysqldump>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
object:
|
2
|
+
attr1: ObjID
|
3
|
+
attr2: ObjID
|
4
|
+
fooobject:
|
5
|
+
@key: ObjID
|
6
|
+
attr1: attr1ID
|
7
|
+
attr3: attr3ID
|
8
|
+
barobject:
|
9
|
+
@key: ObjID
|
10
|
+
attr4: attr4ID
|
11
|
+
|
12
|
+
#primary_table:
|
13
|
+
# foreign_table1: foreign_key1 # local_key1 = foreign_key1
|
14
|
+
# foreign_table2: [local_key2, foreign_key2]
|
15
|
+
# foreign_table3:
|
16
|
+
# @key: foreign_key3 # local_key3 = foreign_key3
|
17
|
+
# foreign_table4:
|
18
|
+
# @key: [local_key4, foreign_key4]
|
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
|
@@ -0,0 +1,139 @@
|
|
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
|
+
|
31
|
+
require 'rubygems'
|
32
|
+
require 'builder'
|
33
|
+
|
34
|
+
module FlattenDB
|
35
|
+
|
36
|
+
class Base
|
37
|
+
|
38
|
+
@types = {}
|
39
|
+
|
40
|
+
BUILDER_OPTIONS = {
|
41
|
+
:xml => {
|
42
|
+
:indent => 2
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
# cf. <http://www.w3.org/TR/2006/REC-xml-20060816/#NT-Name>
|
47
|
+
ELEMENT_START = %r{^[a-zA-Z_:]}
|
48
|
+
ELEMENT_CHARS = %q{\w:.-}
|
49
|
+
|
50
|
+
class << self
|
51
|
+
|
52
|
+
def types
|
53
|
+
Base.instance_variable_get :@types
|
54
|
+
end
|
55
|
+
|
56
|
+
def [](type)
|
57
|
+
types[type]
|
58
|
+
end
|
59
|
+
|
60
|
+
protected
|
61
|
+
|
62
|
+
def inherited(klass)
|
63
|
+
types[klass.name.split('::')[1..-1].join('/').downcase.to_sym] = klass
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
attr_reader :root, :config, :input, :output
|
69
|
+
|
70
|
+
def initialize(infiles, outfile, config)
|
71
|
+
config = case config
|
72
|
+
when Hash
|
73
|
+
config
|
74
|
+
when String
|
75
|
+
# assume file name
|
76
|
+
YAML.load_file(config)
|
77
|
+
else
|
78
|
+
raise ArgumentError, "invalid config argument of type '#{config.class}'"
|
79
|
+
end
|
80
|
+
raise ArgumentError, "can't have more than one primary (root) table" if config.size > 1
|
81
|
+
|
82
|
+
(@root, @config), _ = *config # get "first" (and only) hash element
|
83
|
+
|
84
|
+
@input = [*infiles].map { |infile|
|
85
|
+
case infile
|
86
|
+
when String
|
87
|
+
infile
|
88
|
+
when File
|
89
|
+
infile.path
|
90
|
+
else
|
91
|
+
raise ArgumentError, "invalid infile argument of type '#{infile.class}'"
|
92
|
+
end
|
93
|
+
}
|
94
|
+
|
95
|
+
@output = case outfile
|
96
|
+
when IO
|
97
|
+
outfile
|
98
|
+
when String
|
99
|
+
# assume file name
|
100
|
+
File.open(outfile, 'w')
|
101
|
+
else
|
102
|
+
raise ArgumentError, "invalid outfile argument of type '#{outfile.class}'"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def flatten!(*args)
|
107
|
+
raise NotImplementedError, 'must be defined by sub-class'
|
108
|
+
end
|
109
|
+
|
110
|
+
def to_xml(*args)
|
111
|
+
raise NotImplementedError, 'must be defined by sub-class'
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def initialize_builder(type, output, builder_options = {})
|
117
|
+
builder_options = (BUILDER_OPTIONS[type] || {}).merge(builder_options)
|
118
|
+
|
119
|
+
@builder = case type
|
120
|
+
when :xml
|
121
|
+
Builder::XmlMarkup.new(builder_options.merge(:target => output))
|
122
|
+
else
|
123
|
+
raise ArgumentError, "builder of type '#{type}' not supported"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# mysql:: <http://dev.mysql.com/doc/refman/5.0/en/identifiers.html>
|
128
|
+
def column_to_element(column)
|
129
|
+
element = column.dup
|
130
|
+
|
131
|
+
element.insert(0, '_') unless element =~ ELEMENT_START
|
132
|
+
element.gsub!(/[^#{ELEMENT_CHARS}]/, '')
|
133
|
+
|
134
|
+
element
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
@@ -0,0 +1,79 @@
|
|
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 CLI
|
32
|
+
|
33
|
+
def require_libraries(*libraries)
|
34
|
+
parse_arguments(libraries, :gem).each { |lib, gem|
|
35
|
+
begin
|
36
|
+
require lib
|
37
|
+
rescue LoadError
|
38
|
+
abort_with_msg('Ruby library not found: %s', lib, 'Please install gem %s first', gem)
|
39
|
+
end
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def require_commands(*commands)
|
44
|
+
parse_arguments(commands, :pkg).each { |cmd, pkg|
|
45
|
+
catch :cmd_found do
|
46
|
+
ENV['PATH'].split(':').each { |path|
|
47
|
+
throw :cmd_found if File.executable?(File.join(path, cmd))
|
48
|
+
}
|
49
|
+
|
50
|
+
abort_with_msg("Command not found: #{cmd}", "Please install #{pkg} first", pkg || cmd)
|
51
|
+
end
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def abort_with_msg(msg1, arg1, msg2, arg2)
|
56
|
+
msg = msg1 % arg1
|
57
|
+
msg += " (#{msg2})" % (arg2 || arg1)
|
58
|
+
|
59
|
+
abort msg
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def parse_arguments(arguments, option)
|
65
|
+
options = arguments.last.is_a?(Hash) ? arguments.pop : {}
|
66
|
+
special = options.delete(option)
|
67
|
+
|
68
|
+
arguments.map { |arg|
|
69
|
+
[arg, special]
|
70
|
+
} + options.map { |args, spx|
|
71
|
+
[*args].map { |arg|
|
72
|
+
[arg, spx]
|
73
|
+
}
|
74
|
+
}.flatten_once
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -0,0 +1,53 @@
|
|
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 'libxml'
|
30
|
+
|
31
|
+
require 'flattendb/base'
|
32
|
+
|
33
|
+
module FlattenDB
|
34
|
+
|
35
|
+
class MDB < Base
|
36
|
+
|
37
|
+
JOIN_KEY = '@key'
|
38
|
+
|
39
|
+
def initialize(infiles, outfile, config)
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
def flatten!(options = {}, builder_options = {})
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_xml(output = output, builder_options = {})
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|