jabara 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b920b55bea41121729957fd1afeda678ff1b1c8e
4
+ data.tar.gz: b9e152304622564a2fa3b2526de4f952056fa7a1
5
+ SHA512:
6
+ metadata.gz: 4cd0bdddb3d6651183eb30f2ab620a2c85eb07811ebe602a7960b956dd3e122b21468c9b794700c1b28ffbfdb9b7d901c6f58bb5e891c93cfbd490d91c4e605b
7
+ data.tar.gz: 8cc7d405f8849bbdc3388cfddfe071c7413164f436189362ad8626e33e4638cdeb1ac1387743d8410063315a8fd8ff8d97576f1d67522692e5a5b4430410c7f9
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jabara.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Yuki Takeichi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Jabara
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'jabara'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install jabara
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/jabara/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ end
7
+
8
+ task :default => :test
9
+
data/bin/jabara ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'jabara'
data/jabara.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jabara/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jabara"
8
+ spec.version = Jabara::VERSION
9
+ spec.authors = ["Yuki Takeichi"]
10
+ spec.email = ["yuki.takeichi@gmail.com"]
11
+ spec.summary = "A gem for pluggable data transformation."
12
+ spec.description = "Nested data to flat, and flat data to nested."
13
+ spec.homepage = "https://github.com/yuki-takeichi/jabara"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "scheman", "0.0.5"
22
+ spec.add_development_dependency "bundler", "~> 1.7"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "minitest"
25
+ end
@@ -0,0 +1,56 @@
1
+ module Jabara
2
+ # Jabara中間表現のためのコンストラクタ/アクセサ
3
+ # 抽象データ型なので、Plugin側からIndexを渡して直接Arrayにアクセスするのは禁止
4
+
5
+ # コンストラクタ
6
+
7
+ def self.primitive(tag, data)
8
+ [tag, data]
9
+ end
10
+
11
+ def self.null
12
+ [:null]
13
+ end
14
+
15
+ def self.object(object_type, data, id=nil)
16
+ [:object, data, object_type, id]
17
+ end
18
+
19
+ def self.array(reprs)
20
+ [:array, reprs]
21
+ end
22
+
23
+ def self.set(reprs)
24
+ [:set, reprs]
25
+ end
26
+
27
+ def self.tag(repr)
28
+ repr[0]
29
+ end
30
+
31
+ # アクセサ
32
+
33
+ def self.data(repr)
34
+ repr[1]
35
+ end
36
+
37
+ def self.set_data(repr, data)
38
+ repr[1] = data
39
+ end
40
+
41
+ # use only for :object
42
+ def self.object_type(repr)
43
+ repr[2]
44
+ end
45
+
46
+ def self.primitive?(repr)
47
+ tag = self.tag(repr)
48
+ not [:array, :object, :set].include?(tag)
49
+ end
50
+
51
+ # use only for :object
52
+ def self.id(repr)
53
+ return nil if repr.length < 4
54
+ return repr[3]
55
+ end
56
+ end
@@ -0,0 +1,64 @@
1
+ require 'jabara/data'
2
+
3
+ module Jabara
4
+ module MySQL
5
+ class Output
6
+
7
+ def initialize
8
+ end
9
+
10
+ def encode(object_repr)
11
+ table_name = ::Jabara.object_type(object_repr)
12
+ mysql_value_hash = {}
13
+ ::Jabara.data(object_repr).each do |key, repr|
14
+ mysql_value_hash[key] = mysql_value(repr)
15
+ end
16
+ build_insert_query(table_name, mysql_value_hash)
17
+ end
18
+
19
+ private
20
+ def quote(str)
21
+ # MySQL の nobackquote_escape option が false であることが前提
22
+ '"%s"' % str.gsub('"', '""').gsub(/\\/, "\\\\\\") # \ を \\ に置き換える
23
+ end
24
+
25
+ # Jabara中間表現をMySQL表現に変換する
26
+ def mysql_value(repr)
27
+ raise ArgumentError, 'repr must not be nil' if repr.nil?
28
+
29
+ data = ::Jabara.data(repr)
30
+ tag = ::Jabara.tag(repr)
31
+ case tag
32
+ when :null
33
+ 'null'
34
+ when :integer
35
+ data
36
+ when :float
37
+ data
38
+ when :datetime
39
+ quote(data.strftime("%Y-%m-%d %H:%M:%S"))
40
+ when :string
41
+ quote(data)
42
+ when :boolean
43
+ data
44
+ when :object, :array
45
+ raise ArgumentError, "Can't accept nested object or array!"
46
+ else
47
+ raise ArgumentError, "Invalid tag was found: %s" % tag
48
+ end
49
+ end
50
+
51
+ # Insertクエリを生成する
52
+ def build_insert_query(table_name, mysql_repr)
53
+ cols = []
54
+ vals = []
55
+ mysql_repr.each do |column, value|
56
+ cols << column
57
+ vals << value
58
+ end
59
+ "insert into %s (%s) values(%s);\n" % [table_name, cols.join(', '), vals.join(', ')]
60
+ end
61
+ end
62
+ end
63
+ end
64
+
@@ -0,0 +1,201 @@
1
+ require 'jabara/data'
2
+
3
+ require 'date'
4
+ require 'scheman'
5
+
6
+ module Jabara
7
+ module MySQL
8
+ module Schema
9
+
10
+ class Char
11
+ def self.tag
12
+ :string
13
+ end
14
+
15
+ def initialize(max:nil)
16
+ @max = max
17
+ end
18
+
19
+ def parse
20
+ # TODO
21
+ # unquote and de-escape
22
+ end
23
+
24
+ def validate(repr)
25
+ return false, 'not string type.' unless ::Jabara.tag(repr) == :string
26
+ return false, 'max length exceeded.' unless ::Jabara.data(repr).length > @max
27
+ return true, nil
28
+ end
29
+ end
30
+
31
+ class Text
32
+ def self.tag
33
+ :string
34
+ end
35
+
36
+ def initialize
37
+ end
38
+
39
+ def parse
40
+ # TODO
41
+ # unquote and de-escape
42
+ end
43
+
44
+ def validate(repr)
45
+ return false, 'not string type.' unless ::Jabara.tag(repr) == :string
46
+ return true, nil
47
+ end
48
+ end
49
+
50
+ class Boolean
51
+ def self.tag
52
+ :boolean
53
+ end
54
+
55
+ def parse(data)
56
+ raise ArgumentError, 'must be string' unless data.is_a? ::String
57
+ return true if data == 'true'
58
+ return false if data == 'false'
59
+ raise ArgumentError, 'must be "true" or "false"'
60
+ end
61
+
62
+ def validate(repr)
63
+ data = ::Jabara.data(repr)
64
+ return true if [true, false].include? data
65
+ return false, 'must be "true" or "false"'
66
+ end
67
+ end
68
+
69
+ class Integer
70
+ def self.tag
71
+ :integer
72
+ end
73
+
74
+ def parse(parse)
75
+ Integer(data) # may raise ArgumentError
76
+ end
77
+
78
+ def validate(repr)
79
+ return ::Jabara.data(repr).is_a? ::Integer
80
+ end
81
+ end
82
+
83
+ class DateTime
84
+ def self.tag
85
+ :datetime
86
+ end
87
+
88
+ def parse(data)
89
+ raise ArgumentError, 'must be string' unless data.is_a? ::String
90
+ begin
91
+ DateTime.strptime(date, '%Y-%m-%d %H:%M:%S.%N')
92
+ rescue ArgumentError
93
+ DateTime.strptime(date, '%Y-%m-%d %H:%M:%S') # may raise ArgumentError
94
+ end
95
+ end
96
+
97
+ def validate(repr)
98
+ return ::Jabara.data(repr).is_a? ::DateTime
99
+ end
100
+ end
101
+
102
+ class Schema
103
+
104
+ attr_accessor :columns, :table_name
105
+
106
+ def initialize
107
+ @columns = []
108
+ end
109
+ end
110
+
111
+ class Builder
112
+
113
+ attr_reader :schema
114
+
115
+ def initialize
116
+ @schema = Schema.new
117
+ end
118
+
119
+ def self.build(&block)
120
+ this = Builder.new
121
+ this.instance_eval(&block)
122
+ return this.schema
123
+ end
124
+
125
+ def self.build_from_create_stmt(crete_table_str)
126
+ parser = Scheman::Parsers::Mysql.new
127
+ create_stmt_hash = parser.parse(crete_table_str).to_hash[0][:create_table]
128
+
129
+ this = Builder.new
130
+ this.table_name create_stmt_hash[:name]
131
+ create_stmt_hash[:fields].each do |field_hash|
132
+ field_hash = field_hash[:field]
133
+ type = case field_hash[:type]
134
+ when "char", "varchar"
135
+ max = field_hash[:values][0]
136
+ if max.nil? then Char.new else Char.new max: max end
137
+ when "text"
138
+ Text.new
139
+ when "integer"
140
+ max = field_hash[:values][0]
141
+ if max.nil? then Integer.new else Integer.new max: max end
142
+ when "boolean"
143
+ Boolean.new
144
+ when "double"
145
+ Double.new
146
+ when "datetime"
147
+ DateTime.new
148
+ else
149
+ raise ArgumentError, 'invalid type'
150
+ end
151
+
152
+ if field_hash[:qualifiers].include?({qualifier: {type: "not_null"}}) then
153
+ this.column field_hash[:name], type, :not_null
154
+ else
155
+ this.column field_hash[:name], type
156
+ end
157
+ end
158
+
159
+ return this.schema
160
+ end
161
+
162
+ # 以下DSLメソッド。buildに渡すblock内で使う。
163
+
164
+ def table_name(table_name)
165
+ @schema.table_name = table_name
166
+ end
167
+
168
+ def column(key, type, *args)
169
+ @schema.columns.push({key: key, type: type, constraints: args})
170
+ end
171
+
172
+ def not_null
173
+ :not_null
174
+ end
175
+
176
+ def boolean
177
+ Boolean.new
178
+ end
179
+
180
+ def integer
181
+ Integer.new
182
+ end
183
+
184
+ def varchar(max)
185
+ Char.new max: max
186
+ end
187
+
188
+ def char(max, char_set:nil)
189
+ # TODO char_set
190
+ Char.new max: max
191
+ end
192
+
193
+ def datetime
194
+ DateTime.new
195
+ end
196
+ end
197
+
198
+ end
199
+ end
200
+ end
201
+
@@ -0,0 +1,2 @@
1
+ require 'jabara/mysql/schema'
2
+ require 'jabara/mysql/output'
@@ -0,0 +1,70 @@
1
+ require 'jabara/data'
2
+ require 'jabara/mysql/output'
3
+
4
+ module Jabara
5
+ module MySQLBulk
6
+ class Output < Jabara::MySQL::Output
7
+ def initialize(schema:, tuple_size:1000)
8
+ @table_name = schema.table_name
9
+ @schema = schema
10
+ @tuple_size = tuple_size
11
+ reset_buffer
12
+ end
13
+
14
+ def encode(repr)
15
+ data = ::Jabara.data(repr)
16
+ tuple_str = "(%s)" % @schema.columns.map { |column|
17
+ key = column[:key]
18
+ mysql_value(data[key])
19
+ }.join(", ")
20
+
21
+ @buf << tuple_str
22
+ @buf << ","
23
+ @tuple_count = @tuple_count + 1
24
+
25
+ if @tuple_count >= @tuple_size then
26
+ return flush
27
+ else
28
+ return nil
29
+ end
30
+ end
31
+
32
+ def flush
33
+ return nil if @tuple_count == 0
34
+
35
+ terminate
36
+ ret = @buf
37
+ reset_buffer
38
+ return ret
39
+ end
40
+
41
+ def reset_buffer
42
+ @buf = insert_head
43
+ @tuple_count = 0
44
+ end
45
+
46
+ def terminate
47
+ @buf.chop!
48
+ @buf << ";\n"
49
+ end
50
+
51
+ def insert_head
52
+ "insert into `%s` %s values" % [@table_name, column_def]
53
+ end
54
+
55
+ def column_def
56
+ "(%s)" % @schema.columns.map {|column| "`%s`" % column[:key] }.join(", ")
57
+ end
58
+
59
+ def validate
60
+ @schema.columns.each do |column|
61
+ return false, 'violate "not null" constraint.' if column[:constraints].include? :not_null and data.nil?
62
+ valid, err = column[:type].validate(data)
63
+ return false, err unless valid
64
+ end
65
+
66
+ return true, nil
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,21 @@
1
+ require 'jabara/data'
2
+
3
+ module Jabara
4
+ module ParseCom
5
+ class Input
6
+ def initialize(parse_com_schema)
7
+ @schema = parse_com_schema
8
+ end
9
+
10
+ # ParseObjectをJabara中間表現のobjectに変換する
11
+ def decode(hash)
12
+ data = {}
13
+ @schema.key_defs.each do |key, parser|
14
+ data[key] = parser.parse(hash[key]) # raises ArgumentError
15
+ end
16
+ id = ::Jabara.primitive(:string, hash[@schema.id_key_name])
17
+ return ::Jabara.object(@schema.object_type, data, id)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,257 @@
1
+ require 'jabara/data'
2
+ require 'jabara/transformer/key_value'
3
+
4
+ require 'date'
5
+
6
+ module Jabara
7
+ module ParseCom
8
+ module Schema
9
+
10
+ # TODO
11
+ #class Object
12
+ # def parse(data)
13
+ # ::Jabara.object(...)
14
+ # end
15
+ #end
16
+
17
+ # TODO
18
+ #class Array
19
+ # def parse(data)
20
+ # ::Jabara.array(...array...)
21
+ # end
22
+ #end
23
+
24
+ class TimeStamp # Parseが自動生成するカラム (createdAt, updatedAt)
25
+ def parse(data)
26
+ datetime = ::DateTime.iso8601(data)
27
+ ::Jabara.primitive(:datetime, datetime)
28
+ end
29
+ end
30
+
31
+ class Integer
32
+ def initialize(default: nil) # default = nil の場合はnullを許容する
33
+ raise TypeError, 'default must be integer' unless default.is_a? ::Integer or default.nil?
34
+ @default = default
35
+ end
36
+
37
+ def parse(data)
38
+ return ::Jabara.null if data.nil? and @default.nil?
39
+ return ::Jabara.primitive(:integer, @default) if data.nil?
40
+
41
+ raise TypeError, 'default must be integer' unless data.is_a? ::Integer
42
+ ::Jabara.primitive(:integer, data)
43
+ end
44
+ end
45
+
46
+ class Float
47
+ def initialize(default: nil) # default = nil の場合はnullを許容する
48
+ raise TypeError, 'default must be integer' unless default.is_a? ::Float or default.nil?
49
+ @default = default
50
+ end
51
+
52
+ def parse(data)
53
+ return ::Jabara.null if data.nil? and @default.nil?
54
+ return ::Jabara.primitive(:float, @default) if data.nil?
55
+
56
+ raise TypeError, 'default must be float' unless data.is_a? ::Float
57
+ ::Jabara.primitive(:float, data)
58
+ end
59
+ end
60
+
61
+ class ObjectId
62
+ def parse(data)
63
+ ::Jabara.primitive(:string, data)
64
+ end
65
+ end
66
+
67
+ class File
68
+ def parse(data)
69
+ return ::Jabara.null if data.nil?
70
+ raise ArgumentError, 'File object is collapsed' if data['url'].nil?
71
+ ::Jabara.primitive(:string, data['url'])
72
+ end
73
+ end
74
+
75
+ class DateTime
76
+ def initialize(default: nil) # default = nil の場合はnullを許容する
77
+ raise TypeError, 'default must be datetime' unless default.is_a? ::DateTime or default.nil?
78
+ @default = default
79
+ end
80
+
81
+ def parse(data)
82
+ return ::Jabara.null if data.nil? and @default.nil?
83
+ raise ArgumentError, 'datetime object is collapsed' if data['iso'].nil?
84
+ ::Jabara.primitive(:datetime, ::DateTime.iso8601(data['iso']))
85
+ end
86
+ end
87
+
88
+ class String
89
+ def initialize(max: 1000, default: nil) # default = nil の場合はnullを許容する
90
+ raise TypeError, 'default must be string' unless default.is_a? ::String or default.nil?
91
+ raise TypeError, 'max must be integer' unless max.is_a? ::Integer
92
+ @max = max
93
+ @default = default
94
+ end
95
+
96
+ def parse(data)
97
+ return ::Jabara.null if data.nil? and @default.nil?
98
+ return @default if data.nil?
99
+ raise TypeError, 'data must be string' unless data.is_a? ::String or default.nil?
100
+ ::Jabara.primitive(:string, data.slice(0, @max))
101
+ end
102
+ end
103
+
104
+ class Pointer
105
+ def parse(data)
106
+ return ::Jabara.null if data.nil?
107
+ raise ArgumentError, 'pointer object is collapsed' if data['objectId'].nil?
108
+ ::Jabara.primitive(:string, data['objectId'])
109
+ end
110
+ end
111
+
112
+ class Boolean
113
+ def initialize(default: nil) # default = nil の場合はnullを許容する
114
+ raise ArgumentError, 'default must be true of false' unless [true, false].include? default
115
+ @default = default
116
+ end
117
+
118
+ def parse(data)
119
+ return ::Jabara.null if data.nil? and @default.nil?
120
+ return ::Jabara.primitive(:boolean, @default) if data.nil?
121
+ raise TypeError, 'data must be true or false' unless [true, false].include? data
122
+ ::Jabara.primitive(:boolean, data)
123
+ end
124
+ end
125
+
126
+ class ACL
127
+ def initialize user_acl_object_type: , role_acl_object_type:
128
+ @user_acl_object_type = user_acl_object_type
129
+ @role_acl_object_type = role_acl_object_type
130
+ end
131
+
132
+ def parse(data)
133
+ return ::Jabara.set([]) if hash.nil?
134
+ elems = ::Jabara::Transformer::KeyValue.new.to_entries(hash).map {|entry|
135
+ if entry[:key].start_with? 'role:' then
136
+ decode_acl_role_entry(entry[:key].gsub(/role:/, ''), entry[:value])
137
+ else
138
+ decode_acl_user_entry(entry[:key], entry[:value])
139
+ end
140
+ }
141
+
142
+ return ::Jabara.set(elems)
143
+ end
144
+
145
+ def decode_acl_user_entry(user_object_id, acl_permission)
146
+ data = {}
147
+ data['userObjectId'] = ::Jabara.primitive(:string, user_object_id)
148
+ data['read'] = ::Jabara.primitive(:boolean, acl_permission['read'] || false)
149
+ data['write'] = ::Jabara.primitive(:boolean, acl_permission['write'] || false)
150
+ ::Jabara.object(@user_acl_object_type, data)
151
+ end
152
+
153
+ def decode_acl_role_entry(role_name, acl_permission)
154
+ data = {}
155
+ data['roleName'] = ::Jabara.primitive(:string, role_name)
156
+ data['read'] = ::Jabara.primitive(:boolean, acl_permission['read'] || false)
157
+ data['write'] = ::Jabara.primitive(:boolean, acl_permission['write'] || false)
158
+ ::Jabara.object(@role_acl_object_type, data)
159
+ end
160
+ end
161
+
162
+ class Schema
163
+
164
+ attr_accessor :key_defs, :object_type, :id_key_name
165
+
166
+ def initialize
167
+ @key_defs = {}
168
+ @object_type = nil
169
+ @id_key_name = nil
170
+ end
171
+
172
+ end
173
+
174
+ class Builder
175
+
176
+ attr_reader :schema
177
+
178
+ def self.build(&block)
179
+ this = Builder.new
180
+ this.instance_eval(&block)
181
+ return this.schema
182
+ end
183
+
184
+ def initialize
185
+ @schema = Schema.new
186
+ end
187
+
188
+ # 以下DSLメソッド。buildに渡すblock内で使う。
189
+
190
+ # オブジェクトのtype
191
+ def type(object_type)
192
+ @schema.object_type = object_type
193
+ end
194
+
195
+ def id(id_key_name)
196
+ @schema.id_key_name = id_key_name
197
+ end
198
+
199
+ # スキーマにキーを登録する
200
+ def key(key_string, type)
201
+ raise ArgumentError, 'key_name must be string' unless key_string.is_a? ::String
202
+ (@schema.key_defs)[key_string] = type
203
+ end
204
+
205
+ # TODO
206
+ #def object
207
+ # Object.new
208
+ #end
209
+
210
+ # TODO
211
+ #def array
212
+ # Array.new
213
+ #end
214
+
215
+ def timestamp
216
+ TimeStamp.new
217
+ end
218
+
219
+ def integer default: nil
220
+ Integer.new default: default
221
+ end
222
+
223
+ def float default: nil
224
+ Float.new default: default
225
+ end
226
+
227
+ def parse_object_id
228
+ ObjectId.new
229
+ end
230
+
231
+ def file
232
+ File.new
233
+ end
234
+
235
+ def datetime default: nil
236
+ DateTime.new default: default
237
+ end
238
+
239
+ def string max: 1000, default: nil
240
+ String.new max: max, default: default
241
+ end
242
+
243
+ def pointer
244
+ Pointer.new
245
+ end
246
+
247
+ def boolean default: nil
248
+ Boolean.new default: default
249
+ end
250
+
251
+ def acl user_acl_object_type: ,role_acl_object_type:
252
+ ACL.new(user_acl_object_type: user_acl_object_type, role_acl_object_type: role_acl_object_type)
253
+ end
254
+ end
255
+ end
256
+ end
257
+ end
@@ -0,0 +1,2 @@
1
+ require 'jabara/parse_com/schema.rb'
2
+ require 'jabara/parse_com/input.rb'
@@ -0,0 +1,61 @@
1
+ require 'jabara/data'
2
+
3
+ module Jabara
4
+ module Transformer
5
+
6
+ # TODO array と set のflat化は別クラスに責務を切り出した方がいいかも
7
+ class Flatten
8
+ def initialize(id_key_name: 'id', index_key_name: 'index')
9
+ @id_key_name = id_key_name
10
+ @index_key_name = index_key_name
11
+ end
12
+
13
+ # 与えられたオブジェクトを第1正規化する
14
+ def convert(object_repr)
15
+ new_repr_hash = {}
16
+ divided_reprs = []
17
+
18
+ id = ::Jabara.id(object_repr)
19
+ ::Jabara.data(object_repr).each do |key, repr|
20
+ data = ::Jabara.data(repr)
21
+ if ::Jabara.primitive?(repr) then
22
+ new_repr_hash[key] = repr
23
+ else
24
+ tag = ::Jabara.tag(repr)
25
+ case tag
26
+ when :object
27
+ _object_repr = data
28
+ ::Jabara.data(_object_repr)[@id_key_name] = id
29
+ divided_reprs.push(_object_repr)
30
+ when :array
31
+ # TODO ヘテロな要素が来るケースへの対応
32
+ # TODO primitiveな要素が来るケースへの対応
33
+
34
+ ar = data
35
+ ar.each_with_index do |_object_repr, index|
36
+ ::Jabara.data(_object_repr)[@id_key_name] = id
37
+ ::Jabara.data(_object_repr)[@index_key_name] = index
38
+ divided_reprs.push(_object_repr)
39
+ end
40
+ when :set
41
+ # TODO ヘテロな要素が来るケースへの対応
42
+ # TODO primitiveな要素が来るケースへの対応
43
+
44
+ st = data
45
+ st.each do |_object_repr|
46
+ ::Jabara.data(_object_repr)[@id_key_name] = id
47
+ divided_reprs.push(_object_repr)
48
+ end
49
+ else
50
+ raise ArgumentError, "Invalid tag was found :%s" % tag
51
+ end
52
+ end
53
+ end
54
+
55
+ ::Jabara.set_data(object_repr, new_repr_hash)
56
+ return object_repr, divided_reprs
57
+ end
58
+ end
59
+ end
60
+ end
61
+
@@ -0,0 +1,25 @@
1
+ module Jabara
2
+ module Transformer
3
+
4
+ # inspired by jq 'to_entries', 'from_entries' and 'with_entries' functions
5
+ # http://stedolan.github.io/jq/manual/
6
+ class KeyValue
7
+
8
+ #def from_entries()
9
+ #end
10
+
11
+ def to_entries(hash)
12
+ entries = []
13
+ hash.each do |key, value|
14
+ entry = {:key => key, :value => value}
15
+ entries.push(entry)
16
+ end
17
+ return entries
18
+ end
19
+
20
+ #def with_entries()
21
+ #end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,13 @@
1
+ require 'jabara/data'
2
+
3
+ module Jabara
4
+ module Transformer
5
+ class Nest
6
+ def convert(repr_hash, inner_repr_hash, key_string)
7
+ raise ArgumentError, 'key_string must be string' unless key_string.is_a? ::String
8
+ repr_hash[key_string] = inner_repr_hash
9
+ end
10
+ end
11
+ end
12
+ end
13
+
@@ -0,0 +1,3 @@
1
+ module Jabara
2
+ VERSION = "0.0.1"
3
+ end
data/lib/jabara.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "jabara/version"
2
+
3
+ module Jabara
4
+ end
5
+
6
+ require "jabara/data"
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'jabara'
3
+
4
+ require 'minitest/autorun'
@@ -0,0 +1,11 @@
1
+ require 'minitest_helper'
2
+
3
+ class TestJabara < MiniTest::Unit::TestCase
4
+ def test_that_it_has_a_version_number
5
+ refute_nil ::Jabara::VERSION
6
+ end
7
+
8
+ def test_it_does_something_useful
9
+ assert false
10
+ end
11
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jabara
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Yuki Takeichi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: scheman
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Nested data to flat, and flat data to nested.
70
+ email:
71
+ - yuki.takeichi@gmail.com
72
+ executables:
73
+ - jabara
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".travis.yml"
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - bin/jabara
84
+ - jabara.gemspec
85
+ - lib/jabara.rb
86
+ - lib/jabara/data.rb
87
+ - lib/jabara/mysql.rb
88
+ - lib/jabara/mysql/output.rb
89
+ - lib/jabara/mysql/schema.rb
90
+ - lib/jabara/mysql_bulk/output.rb
91
+ - lib/jabara/parse_com.rb
92
+ - lib/jabara/parse_com/input.rb
93
+ - lib/jabara/parse_com/schema.rb
94
+ - lib/jabara/transformer/flatten.rb
95
+ - lib/jabara/transformer/key_value.rb
96
+ - lib/jabara/transformer/nest.rb
97
+ - lib/jabara/version.rb
98
+ - test/minitest_helper.rb
99
+ - test/test_jabara.rb
100
+ homepage: https://github.com/yuki-takeichi/jabara
101
+ licenses:
102
+ - MIT
103
+ metadata: {}
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubyforge_project:
120
+ rubygems_version: 2.2.2
121
+ signing_key:
122
+ specification_version: 4
123
+ summary: A gem for pluggable data transformation.
124
+ test_files:
125
+ - test/minitest_helper.rb
126
+ - test/test_jabara.rb