rasti-db 2.3.2 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 335b135a71edd9bbb047407d8a288094a19f58b6c2e481837bf4406c06605350
4
- data.tar.gz: 89c5da3b13e1a1f9a82faaa2eb414bc063d72c8588b35c4871deb44d189c3d5b
3
+ metadata.gz: c26c0f818529ec0d1a752cf310c1d23cf235d2c8c83e13a62d8d61bc90b3b400
4
+ data.tar.gz: 57022ffbb145a76ad9532d16a1ed890f31862f7fc6ad4cea6d40aae0490908ca
5
5
  SHA512:
6
- metadata.gz: b27407dcb968c5dc6056a50160cc06b6e89f7008623f0ea2234294195080ebc153da762a79a32618740c79915ff7a5424368f58ed5ee64ff951cd1c4e6f9dc32
7
- data.tar.gz: 77203709a9d842b819aaca51b789a8ac4c27fcd269f617f680530da18ce96607f610c13c4b78b72a91b75a1be4487efcb66e7daaeb7025a89888397799f2b128
6
+ metadata.gz: 94746821604273fdf6483d5410f8c73f4793901116478a17d3ecba6e7039705ecf8cf5b8ad0ccb30adb294d052ff144c6d0fe5ca042ca1fd558e3caf5c45de62
7
+ data.tar.gz: '0684ae374582f8cd633d44aacd720e80b3575e3ef8186de2252d9f73e17f03fe438a54a407127bb320f9ec8996f3f5dc71c99294b503c28797e34faf4c886f22'
data/.travis.yml CHANGED
@@ -8,6 +8,7 @@ rvm:
8
8
  - 2.5
9
9
  - 2.6
10
10
  - 2.7
11
+ - 3.0
11
12
  - jruby-9.2.9.0
12
13
  - ruby-head
13
14
  - jruby-head
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in rasti-db.gemspec
4
- gemspec
4
+ gemspec
data/lib/rasti/db.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'sequel'
2
+ require 'rasti-model'
2
3
  require 'consty'
3
4
  require 'time'
4
5
  require 'timing'
@@ -15,13 +16,13 @@ module Rasti
15
16
  extend MultiRequire
16
17
  extend ClassConfig
17
18
 
18
- require_relative 'db/query'
19
- require_relative_pattern 'db/relations/*'
20
- require_relative_pattern 'db/type_converters/postgres_types/*'
21
- require_relative_pattern 'db/type_converters/sqlite_types/*'
22
- require_relative 'db/nql/nodes/constants/base'
23
- require_relative_pattern 'db/nql/filter_condition_strategies/types/*'
24
- require_relative_pattern 'db/**/*'
19
+ require_relative 'db/query'
20
+ require_relative_pattern 'db/relations/*'
21
+ require_relative_pattern 'db/type_converters/postgres_types/*'
22
+ require_relative_pattern 'db/type_converters/sqlite_types/*'
23
+ require_relative 'db/nql/nodes/constants/base'
24
+ require_relative_pattern 'db/nql/filter_condition_strategies/types/*'
25
+ require_relative_pattern 'db/**/*'
25
26
 
26
27
  attr_config :type_converters, []
27
28
  attr_config :nql_filter_condition_strategy, nil
@@ -14,7 +14,7 @@ module Rasti
14
14
  end
15
15
 
16
16
  def collection_attributes
17
- @collection_attributes ||= model.attributes - relations.keys - computed_attributes.keys
17
+ @collection_attributes ||= model.attribute_names - relations.keys - computed_attributes.keys
18
18
  end
19
19
 
20
20
  def primary_key
@@ -89,7 +89,7 @@ module Rasti
89
89
  raise "Query #{name} already exists" if queries.key? name
90
90
 
91
91
  queries[name] = lambda || block
92
-
92
+
93
93
  define_method name do |*args|
94
94
  default_query.instance_exec(*args, &self.class.queries.fetch(name))
95
95
  end
@@ -210,21 +210,21 @@ module Rasti
210
210
  def qualified_collection_name
211
211
  data_source.qualify self.class.collection_name
212
212
  end
213
-
213
+
214
214
  def qualify(collection_name, data_source_name: nil)
215
215
  data_source_name ||= self.class.data_source_name
216
216
  environment.qualify data_source_name, collection_name
217
217
  end
218
218
 
219
219
  def default_query
220
- Query.new collection_class: self.class,
221
- dataset: dataset.select_all(self.class.collection_name),
220
+ Query.new collection_class: self.class,
221
+ dataset: dataset.select_all(self.class.collection_name),
222
222
  environment: environment
223
223
  end
224
224
 
225
225
  def build_query(filter=nil, &block)
226
226
  raise ArgumentError, 'must specify filter hash or block' if filter.nil? && block.nil?
227
-
227
+
228
228
  if filter
229
229
  default_query.where(filter)
230
230
  else
@@ -233,7 +233,7 @@ module Rasti
233
233
  end
234
234
 
235
235
  def transform_attributes_to_db(attributes)
236
- attributes.each_with_object({}) do |(attribute_name, value), result|
236
+ attributes.each_with_object({}) do |(attribute_name, value), result|
237
237
  transformed_value = Rasti::DB.to_db data_source.db, qualified_collection_name, attribute_name, value
238
238
  result[attribute_name] = transformed_value
239
239
  end
@@ -247,7 +247,7 @@ module Rasti
247
247
 
248
248
  [collection_attributes, relations_ids]
249
249
  end
250
-
250
+
251
251
  def save_relations(primary_key, relations_primary_keys)
252
252
  relations_primary_keys.each do |relation_name, relation_primary_keys|
253
253
  relation = self.class.relations[relation_name]
@@ -281,9 +281,9 @@ module Rasti
281
281
  relation_data_source = environment.data_source relation.relation_data_source_name
282
282
  relation_collection_name = relation_data_source.qualify relation.relation_collection_name
283
283
 
284
- values = relation_primary_keys.map do |relation_pk|
284
+ values = relation_primary_keys.map do |relation_pk|
285
285
  {
286
- relation.source_foreign_key => primary_key,
286
+ relation.source_foreign_key => primary_key,
287
287
  relation.target_foreign_key => relation_pk
288
288
  }
289
289
  end
@@ -9,8 +9,8 @@ module Rasti
9
9
  @join = join
10
10
  end
11
11
 
12
- def apply_join(dataset)
13
- join ? join.call(dataset) : dataset
12
+ def apply_join(dataset, environment)
13
+ join ? join.call(dataset, environment) : dataset
14
14
  end
15
15
 
16
16
  private
@@ -12,7 +12,7 @@ module Rasti
12
12
  def qualify(collection_name)
13
13
  schema ? Sequel[schema][collection_name] : Sequel[collection_name]
14
14
  end
15
-
15
+
16
16
  end
17
17
  end
18
18
  end
@@ -1,112 +1,11 @@
1
1
  module Rasti
2
2
  module DB
3
- class Model
3
+ class Model < Rasti::Model
4
4
 
5
- class UninitializedAttributeError < StandardError
6
-
7
- attr_reader :attribute
8
-
9
- def initialize(attribute)
10
- @attribute = attribute
11
- super "Uninitialized attribute #{attribute}"
12
- end
13
-
14
- end
15
-
16
-
17
- class << self
18
-
19
- def [](*attribute_names)
20
- Class.new(self) do
21
- attribute(*attribute_names)
22
-
23
- def self.inherited(subclass)
24
- subclass.instance_variable_set :@attributes, attributes.dup
25
- end
26
- end
27
- end
28
-
29
- def attributes
30
- @attributes ||= []
31
- end
32
-
33
- def model_name
34
- name || self.superclass.name
35
- end
36
-
37
- def to_s
38
- "#{model_name}[#{attributes.join(', ')}]"
39
- end
40
- alias_method :inspect, :to_s
41
-
42
- private
43
-
44
- def attribute(*names)
45
- names.each do |name|
46
- raise ArgumentError, "Attribute #{name} already exists" if attributes.include?(name)
47
-
48
- attributes << name
49
-
50
- define_method name do
51
- fetch_attribute name
52
- end
53
- end
54
- end
55
-
56
- end
57
-
58
-
59
- def initialize(attributes)
60
- invalid_attributes = attributes.keys - self.class.attributes
61
- raise "#{self.class.model_name} invalid attributes: #{invalid_attributes.join(', ')}" unless invalid_attributes.empty?
62
- @attributes = attributes
63
- end
64
-
65
- def merge(new_attributes)
66
- self.class.new attributes.merge(new_attributes)
67
- end
68
-
69
- def eql?(other)
70
- instance_of?(other.class) && to_h.eql?(other.to_h)
71
- end
72
-
73
- def ==(other)
74
- other.kind_of?(self.class) && to_h == other.to_h
75
- end
76
-
77
- def hash
78
- attributes.map(&:hash).hash
79
- end
80
-
81
- def to_s
82
- "#<#{self.class.model_name}[#{attributes.map { |n,v| "#{n}: #{v.inspect}" }.join(', ')}]>"
83
- end
84
- alias_method :inspect, :to_s
85
-
86
- def to_h
87
- self.class.attributes.each_with_object({}) do |name, hash|
88
- if attributes.key? name
89
- value = fetch_attribute name
90
- case value
91
- when Model
92
- hash[name] = value.to_h
93
- when Array
94
- hash[name] = value.map do |e|
95
- e.is_a?(Model) ? e.to_h : e
96
- end
97
- else
98
- hash[name] = value
99
- end
100
- end
101
- end
102
- end
103
-
104
5
  private
105
6
 
106
- attr_reader :attributes
107
-
108
- def fetch_attribute(name)
109
- attributes.key?(name) ? Rasti::DB.from_db(attributes[name]) : raise(UninitializedAttributeError, name)
7
+ def cast_attribute(type, value)
8
+ super type, Rasti::DB.from_db(value)
110
9
  end
111
10
 
112
11
  end
@@ -3,7 +3,7 @@ module Rasti
3
3
  module NQL
4
4
  module Nodes
5
5
  class BinaryNode < Treetop::Runtime::SyntaxNode
6
-
6
+
7
7
  def dependency_tables
8
8
  values.flat_map(&:dependency_tables)
9
9
  end
@@ -3,7 +3,7 @@ module Rasti
3
3
  module NQL
4
4
  module Nodes
5
5
  class ParenthesisSentence < Treetop::Runtime::SyntaxNode
6
-
6
+
7
7
  def dependency_tables
8
8
  sentence.dependency_tables
9
9
  end
@@ -60,7 +60,7 @@ module Rasti
60
60
  def select_computed_attributes(*computed_attributes)
61
61
  ds = computed_attributes.inject(dataset) do |ds, name|
62
62
  computed_attribute = collection_class.computed_attributes[name]
63
- computed_attribute.apply_join(ds).select_append(computed_attribute.identifier.as(name))
63
+ computed_attribute.apply_join(ds, environment).select_append(computed_attribute.identifier.as(name))
64
64
  end
65
65
  build_query dataset: ds
66
66
  end
@@ -138,7 +138,7 @@ module Rasti
138
138
  raise NQL::InvalidExpressionError.new(filter_expression) if sentence.nil?
139
139
 
140
140
  ds = sentence.computed_attributes(collection_class).inject(dataset) do |ds, name|
141
- collection_class.computed_attributes[name].apply_join ds
141
+ collection_class.computed_attributes[name].apply_join ds, environment
142
142
  end
143
143
  query = build_query dataset: ds
144
144
 
@@ -2,7 +2,7 @@ module Rasti
2
2
  module DB
3
3
  module Relations
4
4
  class Base
5
-
5
+
6
6
  include Sequel::Inflections
7
7
 
8
8
  attr_reader :name, :source_collection_class
@@ -63,10 +63,10 @@ module Rasti
63
63
 
64
64
  def validate_join!
65
65
  if source_collection_class.data_source_name != target_collection_class.data_source_name
66
- raise "Invalid join of multiple data sources: #{source_collection_class.data_source_name}.#{source_collection_class.collection_name} > #{target_collection_class.data_source_name}.#{target_collection_class.collection_name}"
66
+ raise "Invalid join of multiple data sources: #{source_collection_class.data_source_name}.#{source_collection_class.collection_name} > #{target_collection_class.data_source_name}.#{target_collection_class.collection_name}"
67
67
  end
68
68
  end
69
-
69
+
70
70
  end
71
71
  end
72
72
  end
@@ -6,15 +6,15 @@ module Rasti
6
6
  def initialize(environment, collection_class, relations=[], selected_attributes={}, excluded_attributes={})
7
7
  @environment = environment
8
8
  @collection_class = collection_class
9
- @graph = build_graph relations,
10
- Hash::Indifferent.new(selected_attributes),
9
+ @graph = build_graph relations,
10
+ Hash::Indifferent.new(selected_attributes),
11
11
  Hash::Indifferent.new(excluded_attributes)
12
12
  end
13
13
 
14
14
  def merge(relations:[], selected_attributes:{}, excluded_attributes:{})
15
- Graph.new environment,
16
- collection_class,
17
- (flat_relations | relations),
15
+ Graph.new environment,
16
+ collection_class,
17
+ (flat_relations | relations),
18
18
  flat_selected_attributes.merge(selected_attributes),
19
19
  flat_excluded_attributes.merge(excluded_attributes)
20
20
  end
@@ -22,7 +22,7 @@ module Rasti
22
22
  def with_all_attributes_for(relations)
23
23
  relations_with_all_attributes = relations.map { |r| [r, nil] }.to_h
24
24
 
25
- merge selected_attributes: relations_with_all_attributes,
25
+ merge selected_attributes: relations_with_all_attributes,
26
26
  excluded_attributes: relations_with_all_attributes
27
27
  end
28
28
 
@@ -37,7 +37,7 @@ module Rasti
37
37
 
38
38
  graph.roots.each do |node|
39
39
  relation_of(node).fetch_graph environment,
40
- rows,
40
+ rows,
41
41
  node[:selected_attributes],
42
42
  node[:excluded_attributes] ,
43
43
  subgraph_of(node)
@@ -88,25 +88,25 @@ module Rasti
88
88
  excluded[id] = descendant[:excluded_attributes]
89
89
  end
90
90
 
91
- Graph.new environment,
92
- relation_of(node).target_collection_class,
93
- relations,
94
- selected,
91
+ Graph.new environment,
92
+ relation_of(node).target_collection_class,
93
+ relations,
94
+ selected,
95
95
  excluded
96
96
  end
97
97
 
98
98
  def build_graph(relations, selected_attributes, excluded_attributes)
99
99
  HierarchicalGraph.new.tap do |graph|
100
- flatten(relations).each do |relation|
100
+ flatten(relations).each do |relation|
101
101
  sections = relation.split('.')
102
-
102
+
103
103
  graph.add_node relation, name: sections.last.to_sym,
104
104
  selected_attributes: selected_attributes[relation],
105
105
  excluded_attributes: excluded_attributes[relation]
106
-
106
+
107
107
  if sections.count > 1
108
108
  parent_id = sections[0..-2].join('.')
109
- graph.add_relation parent_id: parent_id,
109
+ graph.add_relation parent_id: parent_id,
110
110
  child_id: relation
111
111
  end
112
112
  end
@@ -54,19 +54,19 @@ module Rasti
54
54
 
55
55
  relations_graph.fetch_graph join_rows if relations_graph
56
56
 
57
- relation_rows = join_rows.each_with_object(Hash.new { |h,k| h[k] = [] }) do |row, hash|
58
- attributes = row.select { |attr,_| target_collection_class.model.attributes.include? attr }
57
+ relation_rows = join_rows.each_with_object(Hash.new { |h,k| h[k] = [] }) do |row, hash|
58
+ attributes = row.select { |attr,_| target_collection_class.model.attribute_names.include? attr }
59
59
  hash[row[:source_foreign_key]] << target_collection_class.model.new(attributes)
60
60
  end
61
61
 
62
- rows.each do |row|
62
+ rows.each do |row|
63
63
  row[name] = relation_rows.fetch row[source_collection_class.primary_key], []
64
64
  end
65
65
  end
66
66
 
67
67
  def add_join(environment, dataset, prefix=nil)
68
68
  validate_join!
69
-
69
+
70
70
  many_to_many_relation_alias = with_prefix prefix, "#{relation_collection_name}_#{SecureRandom.base64}"
71
71
 
72
72
  relation_name = prefix ? Sequel[prefix] : Sequel[source_collection_class.collection_name]
@@ -17,18 +17,18 @@ module Rasti
17
17
  query = query.select_attributes(*selected_attributes) if selected_attributes
18
18
  query = relations_graph.apply_to query if relations_graph
19
19
 
20
- relation_rows = query.each_with_object({}) do |row, hash|
20
+ relation_rows = query.each_with_object({}) do |row, hash|
21
21
  hash[row.public_send(source_collection_class.primary_key)] = row
22
22
  end
23
-
24
- rows.each do |row|
23
+
24
+ rows.each do |row|
25
25
  row[name] = relation_rows[row[foreign_key]]
26
26
  end
27
27
  end
28
28
 
29
29
  def add_join(environment, dataset, prefix=nil)
30
30
  validate_join!
31
-
31
+
32
32
  relation_alias = join_relation_name prefix
33
33
 
34
34
  relation_name = prefix ? Sequel[prefix] : Sequel[source_collection_class.collection_name]
@@ -19,14 +19,14 @@ module Rasti
19
19
 
20
20
  relation_rows = query.group_by(&foreign_key)
21
21
 
22
- rows.each do |row|
22
+ rows.each do |row|
23
23
  row[name] = build_graph_result relation_rows.fetch(row[source_collection_class.primary_key], [])
24
24
  end
25
25
  end
26
26
 
27
27
  def add_join(environment, dataset, prefix=nil)
28
28
  validate_join!
29
-
29
+
30
30
  relation_alias = join_relation_name prefix
31
31
 
32
32
  relation_name = prefix ? Sequel[prefix] : Sequel[source_collection_class.collection_name]
@@ -6,7 +6,7 @@ module Rasti
6
6
  class << self
7
7
 
8
8
  def to_db(db, collection_name, attribute_name, value)
9
- value
9
+ value.is_a?(Timing::TimeInZone) ? value.to_time : value
10
10
  end
11
11
 
12
12
  def from_db(value)
@@ -1,5 +1,5 @@
1
1
  module Rasti
2
2
  module DB
3
- VERSION = '2.3.2'
3
+ VERSION = '4.1.0'
4
4
  end
5
5
  end
data/rasti-db.gemspec CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ['lib']
20
20
 
21
21
  spec.add_runtime_dependency 'sequel', '~> 5.0'
22
+ spec.add_runtime_dependency 'rasti-model', '~> 2.0'
22
23
  spec.add_runtime_dependency 'treetop', '~> 1.4.8'
23
24
  spec.add_runtime_dependency 'consty', '~> 1.0', '>= 1.0.3'
24
25
  spec.add_runtime_dependency 'timing', '~> 0.1', '>= 0.1.3'
@@ -52,7 +52,7 @@ describe 'Collection' do
52
52
  it 'Insert with many to many' do
53
53
  user_id = db[:users].insert name: 'User 1'
54
54
 
55
- 1.upto(2) do |i|
55
+ 1.upto(2) do |i|
56
56
  db[:posts].insert user_id: user_id, title: "Post #{i}", body: '...', language_id: 1
57
57
  db[:categories].insert name: "Category #{i}"
58
58
  end
@@ -65,7 +65,7 @@ describe 'Collection' do
65
65
  end
66
66
 
67
67
  it 'Insert only many to many' do
68
- 1.upto(3) do |i|
68
+ 1.upto(3) do |i|
69
69
  db[:categories].insert name: "Category #{i}"
70
70
  end
71
71
 
@@ -101,7 +101,7 @@ describe 'Collection' do
101
101
  it 'Update with many to many' do
102
102
  user_id = db[:users].insert name: 'User 1'
103
103
 
104
- 1.upto(3) do |i|
104
+ 1.upto(3) do |i|
105
105
  db[:posts].insert user_id: user_id, title: "Post #{i}", body: '...', language_id: 1
106
106
  db[:categories].insert name: "Category #{i}"
107
107
  end
@@ -115,11 +115,11 @@ describe 'Collection' do
115
115
  posts.update 1, categories: [2,3]
116
116
 
117
117
  db[:categories_posts].where(post_id: 1).map(:category_id).must_equal [2,3]
118
-
118
+
119
119
  db[:categories_posts].where(category_id: 2).map(:post_id).must_equal [1,2]
120
120
 
121
121
  categories.update 2, posts: [2,3]
122
-
122
+
123
123
  db[:categories_posts].where(category_id: 2).map(:post_id).must_equal [2,3]
124
124
  end
125
125
 
@@ -145,7 +145,7 @@ describe 'Collection' do
145
145
  end
146
146
 
147
147
  it 'Delete only many to many' do
148
- 1.upto(3) do |i|
148
+ 1.upto(3) do |i|
149
149
  db[:categories].insert name: "Category #{i}"
150
150
  end
151
151
 
@@ -172,14 +172,14 @@ describe 'Collection' do
172
172
  1.upto(3) do |i|
173
173
  user_id = db[:users].insert name: "User #{i}"
174
174
 
175
- db[:people].insert document_number: "document_#{i}",
175
+ db[:people].insert document_number: "document_#{i}",
176
176
  first_name: "John #{i}",
177
177
  last_name: "Doe #{i}",
178
178
  birth_date: Time.now - i,
179
179
  user_id: user_id
180
180
 
181
- category_id = db[:categories].insert name: "Category #{i}"
182
-
181
+ category_id = db[:categories].insert name: "Category #{i}"
182
+
183
183
  1.upto(3) do |n|
184
184
  post_id = db[:posts].insert user_id: user_id, title: "Post #{i}.#{n}", body: '...', language_id: 1
185
185
  db[:categories_posts].insert post_id: post_id, category_id: category_id
@@ -227,7 +227,7 @@ describe 'Collection' do
227
227
  db[:posts].where(user_id: 1).count.must_equal 0
228
228
  db[:comments].join(:posts, id: :post_id).where(Sequel[:posts][:user_id] => 1).count.must_equal 0
229
229
  db[:categories_posts].join(:posts, id: :post_id).where(Sequel[:posts][:user_id] => 1).count.must_equal 0
230
-
230
+
231
231
  db[:users].count.must_equal 2
232
232
  db[:people].count.must_equal 2
233
233
  db[:categories].count.must_equal 3
@@ -241,9 +241,9 @@ describe 'Collection' do
241
241
  describe 'Multiple data sources' do
242
242
 
243
243
  before do
244
- 1.upto(3) do |i|
244
+ 1.upto(3) do |i|
245
245
  db[:users].insert name: "User #{i}"
246
- db[:people].insert document_number: "document_#{i}",
246
+ db[:people].insert document_number: "document_#{i}",
247
247
  first_name: "John #{i}",
248
248
  last_name: "Doe #{i}",
249
249
  birth_date: Time.now - i,
@@ -303,7 +303,7 @@ describe 'Collection' do
303
303
 
304
304
  it 'Find' do
305
305
  id = db[:users].insert name: 'User 1'
306
-
306
+
307
307
  users.find(id).must_equal User.new(id: id, name: 'User 1')
308
308
  end
309
309
 
@@ -410,26 +410,26 @@ describe 'Collection' do
410
410
 
411
411
  1.upto(2) do |i|
412
412
  db[:categories].insert name: "Category #{i}"
413
-
413
+
414
414
  db[:users].insert name: "User #{i}"
415
-
416
- db[:people].insert document_number: "document_#{i}",
415
+
416
+ db[:people].insert document_number: "document_#{i}",
417
417
  first_name: "John #{i}",
418
418
  last_name: "Doe #{i}",
419
419
  birth_date: Time.now - i,
420
420
  user_id: i
421
-
421
+
422
422
  end
423
423
 
424
424
  db[:languages_people].insert language_id: 1, document_number: 'document_1'
425
425
  db[:languages_people].insert language_id: 2, document_number: 'document_2'
426
426
 
427
- 1.upto(3) do |i|
427
+ 1.upto(3) do |i|
428
428
  db[:posts].insert user_id: 1, title: "Post #{i}", body: '...', language_id: 1
429
429
  db[:categories_posts].insert category_id: 1, post_id: i
430
430
  end
431
-
432
- 4.upto(5) do |i|
431
+
432
+ 4.upto(5) do |i|
433
433
  db[:posts].insert user_id: 2, title: "Post #{i}", body: '...', language_id: 2
434
434
  db[:categories_posts].insert category_id: 2, post_id: i
435
435
  end
@@ -475,7 +475,7 @@ describe 'Collection' do
475
475
  it 'Global' do
476
476
  result_1 = posts.created_by(1)
477
477
  result_1.primary_keys.must_equal [1,2,3]
478
-
478
+
479
479
  result_2 = posts.created_by(2)
480
480
  result_2.primary_keys.must_equal [4,5]
481
481
  end
@@ -490,7 +490,7 @@ describe 'Collection' do
490
490
  it 'Graph' do
491
491
  1.upto(3) do |i|
492
492
  db[:users].insert name: "User #{i}"
493
- db[:people].insert document_number: "document_#{i}",
493
+ db[:people].insert document_number: "document_#{i}",
494
494
  first_name: "John #{i}",
495
495
  last_name: "Doe #{i}",
496
496
  birth_date: Time.now - i,
@@ -521,10 +521,10 @@ describe 'Collection' do
521
521
 
522
522
  comment.post_id.must_equal 1
523
523
  comment.user_id.must_equal i
524
-
524
+
525
525
  comment.user.id.must_equal i
526
526
  comment.user.name.must_equal "User #{i}"
527
-
527
+
528
528
  comment.user.posts.count.must_equal 1
529
529
  comment.user.posts[0].id.must_equal i
530
530
  comment.user.posts[0].title.must_equal "Post #{i}"
@@ -544,7 +544,7 @@ describe 'Collection' do
544
544
  stubs = Proc.new do |sql|
545
545
  case sql
546
546
 
547
- when 'SELECT users.* FROM schema_1.users',
547
+ when 'SELECT users.* FROM schema_1.users',
548
548
  'SELECT users.* FROM schema_1.users WHERE (users.id IN (2, 1))'
549
549
  [
550
550
  {id: 1},
@@ -588,7 +588,7 @@ describe 'Collection' do
588
588
  Sequel.mock fetch: stubs, autoid: autoid
589
589
  end
590
590
 
591
- let :stub_environment do
591
+ let :stub_environment do
592
592
  Rasti::DB::Environment.new default: Rasti::DB::DataSource.new(stub_db, :schema_1),
593
593
  custom: Rasti::DB::DataSource.new(stub_db, :schema_2)
594
594
  end
@@ -627,7 +627,7 @@ describe 'Collection' do
627
627
 
628
628
  stub_users.insert name: 'User 1'
629
629
 
630
- stub_people.insert document_number: 'document_1',
630
+ stub_people.insert document_number: 'document_1',
631
631
  first_name: 'John',
632
632
  last_name: 'Doe',
633
633
  birth_date: Time.parse('2020-04-24'),
@@ -680,7 +680,7 @@ describe 'Collection' do
680
680
 
681
681
  stub_db.sqls.must_equal [
682
682
  'SELECT posts.* FROM schema_1.posts',
683
- 'SELECT categories.*, categories_posts.post_id AS source_foreign_key FROM schema_1.categories INNER JOIN schema_1.categories_posts ON (schema_1.categories_posts.category_id = schema_1.categories.id) WHERE (categories_posts.post_id IN (3, 4))',
683
+ 'SELECT categories.*, categories_posts.post_id AS source_foreign_key FROM schema_1.categories INNER JOIN schema_1.categories_posts ON (schema_1.categories_posts.category_id = schema_1.categories.id) WHERE (categories_posts.post_id IN (3, 4))',
684
684
  'SELECT comments.* FROM schema_1.comments WHERE (comments.post_id IN (3, 4))',
685
685
  'SELECT users.* FROM schema_1.users WHERE (users.id IN (2, 1))',
686
686
  'SELECT posts.* FROM schema_1.posts WHERE (posts.user_id IN (1, 2))',
@@ -2,7 +2,7 @@ require 'minitest_helper'
2
2
 
3
3
  describe 'ComputedAttribute' do
4
4
 
5
- it 'Apply Join wiht join attribute must generate correct query' do
5
+ it 'Apply Join with join attribute must generate correct query' do
6
6
  dataset = db[:users]
7
7
  computed_attribute = Rasti::DB::ComputedAttribute.new(Sequel[:comments_count][:value]) do |dataset|
8
8
  subquery = dataset.db.from(:comments)
@@ -13,7 +13,7 @@ describe 'ComputedAttribute' do
13
13
  dataset.join_table(:inner, subquery, :user_id => :id)
14
14
  end
15
15
  expected_query = "SELECT *, `comments_count`.`value` AS 'value' FROM `users` INNER JOIN (SELECT `user_id`, count(`id`) AS 'value' FROM `comments` GROUP BY `user_id`) AS 'comments_count' ON (`comments_count`.`user_id` = `users`.`id`)"
16
- computed_attribute.apply_join(dataset)
16
+ computed_attribute.apply_join(dataset, environment)
17
17
  .select_append(computed_attribute.identifier)
18
18
  .sql
19
19
  .must_equal expected_query
@@ -23,10 +23,30 @@ describe 'ComputedAttribute' do
23
23
  dataset = db[:people]
24
24
  computed_attribute = Rasti::DB::ComputedAttribute.new Sequel.join([:first_name, ' ', :last_name])
25
25
  expected_query = "SELECT * FROM `people` WHERE ((`first_name` || ' ' || `last_name`) = 'FULL NAME')"
26
- computed_attribute.apply_join(dataset)
26
+ computed_attribute.apply_join(dataset, environment)
27
27
  .where(computed_attribute.identifier => 'FULL NAME')
28
28
  .sql
29
29
  .must_equal expected_query
30
30
  end
31
31
 
32
+ it 'Apply join with join and environment attributes must generate correct query' do
33
+ dataset = db[:users]
34
+
35
+ expected_query = "SELECT *, `comments_count`.`value` AS 'value' FROM `users` INNER JOIN (SELECT `user_id`, count(`id`) AS 'value' FROM `comments` GROUP BY `user_id`) AS 'comments_count' ON (`comments_count`.`user_id` = `users`.`id`)"
36
+
37
+ computed_attribute = Rasti::DB::ComputedAttribute.new(Sequel[:comments_count][:value]) do |dataset, environment|
38
+ subquery = dataset.db.from(environment.data_source(:custom).qualify(:comments))
39
+ .select(Sequel[:user_id], Sequel.function('count', :id).as(:value))
40
+ .group(:user_id)
41
+ .as(:comments_count)
42
+
43
+ dataset.join_table(:inner, subquery, :user_id => :id)
44
+ end
45
+
46
+ computed_attribute.apply_join(dataset, environment)
47
+ .select_append(computed_attribute.identifier)
48
+ .sql
49
+ .must_equal expected_query
50
+ end
51
+
32
52
  end
@@ -8,15 +8,15 @@ describe 'Relations' do
8
8
 
9
9
  it 'Implicit' do
10
10
  relation = Rasti::DB::Relations::OneToMany.new :posts, Users
11
-
11
+
12
12
  relation.target_collection_class.must_equal Posts
13
13
  relation.foreign_key.must_equal :user_id
14
14
  end
15
15
 
16
16
  it 'Explicit' do
17
- relation = Rasti::DB::Relations::OneToMany.new :articles, Users, collection: 'Posts',
17
+ relation = Rasti::DB::Relations::OneToMany.new :articles, Users, collection: 'Posts',
18
18
  foreign_key: :id_user
19
-
19
+
20
20
  relation.target_collection_class.must_equal Posts
21
21
  relation.foreign_key.must_equal :id_user
22
22
  end
@@ -41,9 +41,9 @@ describe 'Relations' do
41
41
  user_id = db[:users].insert name: 'User 1'
42
42
  1.upto(2) { |i| db[:posts].insert user_id: user_id, title: "Post #{i}", body: '...', language_id: 1 }
43
43
  rows = db[:users].all
44
-
44
+
45
45
  Users.relations[:posts].fetch_graph environment, rows
46
-
46
+
47
47
  rows[0][:posts].must_equal posts.where(user_id: user_id).all
48
48
  end
49
49
 
@@ -55,15 +55,15 @@ describe 'Relations' do
55
55
 
56
56
  it 'Implicit' do
57
57
  relation = Rasti::DB::Relations::ManyToOne.new :user, Posts
58
-
58
+
59
59
  relation.target_collection_class.must_equal Users
60
60
  relation.foreign_key.must_equal :user_id
61
61
  end
62
62
 
63
63
  it 'Explicit' do
64
- relation = Rasti::DB::Relations::ManyToOne.new :publisher, Posts, collection: 'Users',
64
+ relation = Rasti::DB::Relations::ManyToOne.new :publisher, Posts, collection: 'Users',
65
65
  foreign_key: :publisher_id
66
-
66
+
67
67
  relation.target_collection_class.must_equal Users
68
68
  relation.foreign_key.must_equal :publisher_id
69
69
  end
@@ -102,7 +102,7 @@ describe 'Relations' do
102
102
 
103
103
  it 'Implicit' do
104
104
  relation = Rasti::DB::Relations::ManyToMany.new :categories, Posts
105
-
105
+
106
106
  relation.target_collection_class.must_equal Categories
107
107
  relation.source_foreign_key.must_equal :post_id
108
108
  relation.target_foreign_key.must_equal :category_id
@@ -110,11 +110,11 @@ describe 'Relations' do
110
110
  end
111
111
 
112
112
  it 'Explicit' do
113
- relation = Rasti::DB::Relations::ManyToMany.new :tags, Posts, collection: 'Categories',
114
- source_foreign_key: :article_id,
115
- target_foreign_key: :tag_id,
113
+ relation = Rasti::DB::Relations::ManyToMany.new :tags, Posts, collection: 'Categories',
114
+ source_foreign_key: :article_id,
115
+ target_foreign_key: :tag_id,
116
116
  relation_collection_name: :tags_articles
117
-
117
+
118
118
  relation.target_collection_class.must_equal Categories
119
119
  relation.source_foreign_key.must_equal :article_id
120
120
  relation.target_foreign_key.must_equal :tag_id
@@ -165,15 +165,15 @@ describe 'Relations' do
165
165
 
166
166
  it 'Implicit' do
167
167
  relation = Rasti::DB::Relations::OneToOne.new :person, Users
168
-
168
+
169
169
  relation.target_collection_class.must_equal People
170
170
  relation.foreign_key.must_equal :user_id
171
171
  end
172
172
 
173
173
  it 'Explicit' do
174
- relation = Rasti::DB::Relations::OneToOne.new :person, Users, collection: 'Users',
174
+ relation = Rasti::DB::Relations::OneToOne.new :person, Users, collection: 'Users',
175
175
  foreign_key: :id_user
176
-
176
+
177
177
  relation.target_collection_class.must_equal Users
178
178
  relation.foreign_key.must_equal :id_user
179
179
  end
@@ -197,7 +197,7 @@ describe 'Relations' do
197
197
  it 'Graph' do
198
198
  2.times do |i|
199
199
  user_id = db[:users].insert name: "User #{i}"
200
- db[:people].insert document_number: "document_#{i}",
200
+ db[:people].insert document_number: "document_#{i}",
201
201
  first_name: "John #{i}",
202
202
  last_name: "Doe #{i}",
203
203
  birth_date: Time.now - i,
@@ -7,7 +7,7 @@ describe Rasti::DB::TypeConverters::TimeInZone do
7
7
  describe 'To DB' do
8
8
 
9
9
  it 'must not transform Time to TimeInZone' do
10
- time = Time.now
10
+ time = Timing::TimeInZone.now
11
11
 
12
12
  converted_time = type_converter.to_db db, 'table', :time, time
13
13
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rasti-db
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.2
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabriel Naiman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-01 00:00:00.000000000 Z
11
+ date: 2021-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rasti-model
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: treetop
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -352,7 +366,6 @@ files:
352
366
  - spec/computed_attribute_spec.rb
353
367
  - spec/coverage_helper.rb
354
368
  - spec/minitest_helper.rb
355
- - spec/model_spec.rb
356
369
  - spec/nql/computed_attributes_spec.rb
357
370
  - spec/nql/dependency_tables_spec.rb
358
371
  - spec/nql/filter_condition_spec.rb
@@ -382,7 +395,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
382
395
  - !ruby/object:Gem::Version
383
396
  version: '0'
384
397
  requirements: []
385
- rubygems_version: 3.0.1
398
+ rubygems_version: 3.0.9
386
399
  signing_key:
387
400
  specification_version: 4
388
401
  summary: Database collections and relations
@@ -391,7 +404,6 @@ test_files:
391
404
  - spec/computed_attribute_spec.rb
392
405
  - spec/coverage_helper.rb
393
406
  - spec/minitest_helper.rb
394
- - spec/model_spec.rb
395
407
  - spec/nql/computed_attributes_spec.rb
396
408
  - spec/nql/dependency_tables_spec.rb
397
409
  - spec/nql/filter_condition_spec.rb
data/spec/model_spec.rb DELETED
@@ -1,90 +0,0 @@
1
- require 'minitest_helper'
2
-
3
- describe 'Model' do
4
-
5
- describe 'Attribues' do
6
-
7
- it 'Valid definition' do
8
- model = Rasti::DB::Model[:id, :name]
9
- model.attributes.must_equal [:id, :name]
10
- end
11
-
12
- it 'Invalid definition' do
13
- error = proc { Rasti::DB::Model[:id, :name, :name] }.must_raise ArgumentError
14
- error.message.must_equal 'Attribute name already exists'
15
- end
16
-
17
- it 'Accessors' do
18
- post = Post.new id: 1, title: 'Title'
19
-
20
- post.id.must_equal 1
21
- post.title.must_equal 'Title'
22
-
23
- [:body, :user, :comments].each do |attribute|
24
- error = proc { post.send attribute }.must_raise Rasti::DB::Model::UninitializedAttributeError
25
- error.message.must_equal "Uninitialized attribute #{attribute}"
26
- end
27
-
28
- proc { post.invalid_method }.must_raise NoMethodError
29
- end
30
-
31
- end
32
-
33
-
34
- it 'Inheritance' do
35
- subclass = Class.new(User) do
36
- attribute :additional_attribute
37
- end
38
-
39
- subclass.attributes.must_equal (User.attributes + [:additional_attribute])
40
- end
41
-
42
- describe 'To String' do
43
-
44
- it 'Class' do
45
- User.to_s.must_equal 'User[id, name, posts, comments, person, comments_count]'
46
- end
47
-
48
- it 'Instance' do
49
- user = User.new id: 1, name: 'User 1'
50
- user.to_s.must_equal '#<User[id: 1, name: "User 1"]>'
51
- end
52
-
53
- end
54
-
55
- it 'To Hash' do
56
- post = Post.new id: 2,
57
- title: 'Title',
58
- body: 'body',
59
- user_id: 1,
60
- user: User.new(id: 1, name: 'User 1'),
61
- comments: [Comment.new(id: 4, text: 'comment text', user_id: 5)]
62
-
63
- post.to_h.must_equal id: 2,
64
- title: 'Title',
65
- body: 'body',
66
- user_id: 1,
67
- user: {id: 1, name: 'User 1'},
68
- comments: [{id: 4, text: 'comment text', user_id: 5}]
69
- end
70
-
71
- it 'Equality' do
72
- assert User.new(id: 1, name: 'User 1') == User.new(id: 1, name: 'User 1')
73
- refute User.new(id: 1, name: 'User 1') == User.new(id: 2, name: 'User 2')
74
-
75
- assert User.new(id: 1, name: 'User 1').eql? User.new(id: 1, name: 'User 1')
76
- refute User.new(id: 1, name: 'User 1').eql? User.new(id: 2, name: 'User 2')
77
-
78
- assert_equal User.new(id: 1, name: 'User 1').hash, User.new(id: 1, name: 'User 1').hash
79
- refute_equal User.new(id: 1, name: 'User 1').hash, User.new(id: 2, name: 'User 2').hash
80
- end
81
-
82
- it 'Merge' do
83
- user = User.new(id: 1, name: 'User 1')
84
- changed_user = user.merge(name: 'User 2')
85
-
86
- user.must_equal User.new(id: 1, name: 'User 1')
87
- changed_user.must_equal User.new(id: 1, name: 'User 2')
88
- end
89
-
90
- end