datasource 0.0.2 → 0.0.3

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
  SHA1:
3
- metadata.gz: 714357b54441eac8f8eb1c209dad82fa8c588743
4
- data.tar.gz: 90cb1f1ca000d6683b234c6ccff41425b208be2c
3
+ metadata.gz: 2a9fb1c2535e9067063259742826afd3e588a6ed
4
+ data.tar.gz: a99f6cf865ea1075a2e26165c58c03483e45e93c
5
5
  SHA512:
6
- metadata.gz: 0414aa6f0f18bdb882d9f54e558ed5301e4c52d77d417cdfd62d51fad0a51f5ebc5191d9ab86a56b6ee69d6c7c489f0c2395c10082b27381e04bfbc70152d3b9
7
- data.tar.gz: 94f30d58cd6cd8cef946e87f039445910dd924638d00c40a95599d35e473e6eb840a14d4543c4dd405b953633257c3defafb33c777b0581dc2cb724bd05fa4d1
6
+ metadata.gz: 6b5a9a5c5a9b4af51e1115a152a58b1b2187ffcf4adaa912e9921824d3fbbf96c12b21df77461347ca0569eb6943542bea1dc50b7bbfa0cc57f583a5017c431d
7
+ data.tar.gz: 5742b0fe11b8bd4a61accb93ca762b4c42cdd4a95cc7044d76b1d7ee124ccc9df9ed3911b36ac8861ac57343c1757557eaa7ddc3ce03af036287e3c578ce58f8
@@ -20,18 +20,20 @@ module Datasource
20
20
  self
21
21
  end
22
22
 
23
- def to_a
23
+ private
24
+ def exec_queries
24
25
  if @datasource
25
26
  datasource = @datasource.new(self)
26
27
  datasource.select(*Array(@datasource_select))
27
28
  if @datasource_serializer
28
29
  select = []
29
- Datasource::Base.consumer_adapter.to_datasource_select(select, @datasource.orm_klass, @datasource_serializer)
30
+ Datasource::Base.consumer_adapter.to_datasource_select(select, @datasource.orm_klass, @datasource_serializer, nil, datasource.adapter)
30
31
 
31
32
  datasource.select(*select)
32
33
  end
33
34
 
34
- datasource.results
35
+ @loaded = true
36
+ @records = datasource.results
35
37
  else
36
38
  super
37
39
  end
@@ -74,7 +76,8 @@ module Datasource
74
76
  end
75
77
  end
76
78
 
77
- def self.association_reflection(klass, name)
79
+ module_function
80
+ def association_reflection(klass, name)
78
81
  if reflection = klass.reflections[name]
79
82
  {
80
83
  klass: reflection.klass,
@@ -84,19 +87,23 @@ module Datasource
84
87
  end
85
88
  end
86
89
 
87
- def self.get_table_name(klass)
90
+ def get_table_name(klass)
88
91
  klass.table_name.to_sym
89
92
  end
90
93
 
91
- def self.is_scope?(obj)
94
+ def is_scope?(obj)
92
95
  obj.kind_of?(::ActiveRecord::Relation)
93
96
  end
94
97
 
95
- def self.scope_to_class(scope)
98
+ def scope_to_class(scope)
96
99
  scope.klass
97
100
  end
98
101
 
99
- def self.association_klass(reflection)
102
+ def scope_loaded?(scope)
103
+ scope.loaded?
104
+ end
105
+
106
+ def association_klass(reflection)
100
107
  if reflection.macro == :belongs_to && reflection.options[:polymorphic]
101
108
  fail Datasource::Error, "polymorphic belongs_to not supported, write custom loader"
102
109
  else
@@ -104,7 +111,7 @@ module Datasource
104
111
  end
105
112
  end
106
113
 
107
- def self.preload_association(records, name)
114
+ def preload_association(records, name)
108
115
  return if records.empty?
109
116
  return if records.first.association(name.to_sym).loaded?
110
117
  klass = records.first.class
@@ -144,43 +151,43 @@ module Datasource
144
151
  end
145
152
  end
146
153
 
147
- def to_query
154
+ def to_query(ds)
148
155
  ::ActiveRecord::Base.uncached do
149
- @scope.select(*get_select_values).to_sql
156
+ ds.scope.select(*ds.get_select_values).to_sql
150
157
  end
151
158
  end
152
159
 
153
- def select_scope
154
- @scope.select(*get_select_values)
160
+ def select_scope(ds)
161
+ ds.scope.select(*ds.get_select_values)
155
162
  end
156
163
 
157
- def get_rows
164
+ def get_rows(ds)
158
165
  append_select = []
159
- @expose_associations.each_pair do |assoc_name, assoc_select|
160
- if reflection = Adapters::ActiveRecord.association_reflection(self.class.orm_klass, assoc_name.to_sym)
166
+ ds.expose_associations.each_pair do |assoc_name, assoc_select|
167
+ if reflection = Adapters::ActiveRecord.association_reflection(ds.class.orm_klass, assoc_name.to_sym)
161
168
  Datasource::Base.reflection_select(reflection, append_select, [])
162
169
  end
163
170
  end
164
- select(*append_select)
171
+ ds.select(*append_select)
165
172
 
166
- scope = select_scope
173
+ scope = select_scope(ds)
167
174
  if scope.respond_to?(:use_datasource)
168
175
  scope = scope.spawn.use_datasource(nil)
169
176
  end
170
177
  scope.includes_values = []
171
178
  scope.to_a.tap do |records|
172
- @expose_associations.each_pair do |assoc_name, assoc_select|
179
+ ds.expose_associations.each_pair do |assoc_name, assoc_select|
173
180
  Adapters::ActiveRecord.preload_association(records, assoc_name)
174
181
  end
175
182
  end
176
183
  end
177
184
 
178
- def primary_scope_table(scope)
179
- scope.klass.table_name
185
+ def primary_scope_table(ds)
186
+ ds.scope.klass.table_name
180
187
  end
181
188
 
182
- def ensure_table_join!(name, att)
183
- join_value = @scope.joins_values.find do |value|
189
+ def ensure_table_join!(ds, name, att)
190
+ join_value = ds.scope.joins_values.find do |value|
184
191
  if value.is_a?(Symbol)
185
192
  value.to_s == att[:name]
186
193
  elsif value.is_a?(String)
@@ -203,6 +210,10 @@ module Datasource
203
210
  klass
204
211
  end
205
212
 
213
+ define_singleton_method(:default_adapter) do
214
+ Datasource::Adapters::ActiveRecord
215
+ end
216
+
206
217
  define_method(:primary_key) do
207
218
  klass.primary_key.to_sym
208
219
  end
@@ -25,7 +25,7 @@ module Datasource
25
25
  datasource.select(*Array(@datasource_select))
26
26
  if @datasource_serializer
27
27
  select = []
28
- Datasource::Base.consumer_adapter.to_datasource_select(select, @datasource.orm_klass, @datasource_serializer)
28
+ Datasource::Base.consumer_adapter.to_datasource_select(select, @datasource.orm_klass, @datasource_serializer, nil, datasource.adapter)
29
29
 
30
30
  datasource.select(*select)
31
31
  end
@@ -75,7 +75,8 @@ module Datasource
75
75
  end
76
76
  end
77
77
 
78
- def self.association_reflection(klass, name)
78
+ module_function
79
+ def association_reflection(klass, name)
79
80
  reflection = klass.association_reflections[name]
80
81
 
81
82
  macro = case reflection[:type]
@@ -92,15 +93,15 @@ module Datasource
92
93
  }
93
94
  end
94
95
 
95
- def self.get_table_name(klass)
96
+ def get_table_name(klass)
96
97
  klass.table_name
97
98
  end
98
99
 
99
- def self.is_scope?(obj)
100
+ def is_scope?(obj)
100
101
  obj.kind_of?(::Sequel::Dataset)
101
102
  end
102
103
 
103
- def self.scope_to_class(scope)
104
+ def scope_to_class(scope)
104
105
  if scope.row_proc && scope.row_proc.ancestors.include?(::Sequel::Model)
105
106
  scope.row_proc
106
107
  else
@@ -108,29 +109,8 @@ module Datasource
108
109
  end
109
110
  end
110
111
 
111
- def to_query(scope)
112
- scope.sql
113
- end
114
-
115
- def select_scope
116
- @scope.select(*get_sequel_select_values)
117
- end
118
-
119
- def get_rows
120
- eager = {}
121
- append_select = []
122
- @expose_associations.each_pair do |assoc_name, assoc_select|
123
- eager.merge!(
124
- get_assoc_eager_options(self.class.orm_klass, assoc_name.to_sym, assoc_select, append_select))
125
- end
126
- # TODO: remove/disable datasource on scope if present
127
- scope = select_scope
128
- if scope.respond_to?(:use_datasource)
129
- scope = scope.clone.use_datasource(nil)
130
- end
131
- scope
132
- .select_append(*get_sequel_select_values(append_select.map { |v| primary_scope_table(@scope) + ".#{v}" }))
133
- .eager(eager).all
112
+ def scope_loaded?(scope)
113
+ false
134
114
  end
135
115
 
136
116
  def get_assoc_eager_options(klass, name, assoc_select, append_select)
@@ -153,15 +133,40 @@ module Datasource
153
133
  end
154
134
 
155
135
  def get_sequel_select_values(values = nil)
156
- (values || get_select_values).map { |str| ::Sequel.lit(str) }
136
+ values.map { |str| ::Sequel.lit(str) }
137
+ end
138
+
139
+ def to_query(ds)
140
+ ds.scope.sql
157
141
  end
158
142
 
159
- def primary_scope_table(scope)
160
- scope.first_source_alias.to_s
143
+ def select_scope(ds)
144
+ ds.scope.select(*get_sequel_select_values(ds.get_select_values))
161
145
  end
162
146
 
163
- def ensure_table_join!(name, att)
164
- join_value = Hash(@scope.opts[:join]).find do |value|
147
+ def get_rows(ds)
148
+ eager = {}
149
+ append_select = []
150
+ ds.expose_associations.each_pair do |assoc_name, assoc_select|
151
+ eager.merge!(
152
+ get_assoc_eager_options(ds.class.orm_klass, assoc_name.to_sym, assoc_select, append_select))
153
+ end
154
+ # TODO: remove/disable datasource on scope if present
155
+ scope = select_scope(ds)
156
+ if scope.respond_to?(:use_datasource)
157
+ scope = scope.clone.use_datasource(nil)
158
+ end
159
+ scope
160
+ .select_append(*get_sequel_select_values(append_select.map { |v| primary_scope_table(ds) + ".#{v}" }))
161
+ .eager(eager).all
162
+ end
163
+
164
+ def primary_scope_table(ds)
165
+ ds.scope.first_source_alias.to_s
166
+ end
167
+
168
+ def ensure_table_join!(ds, name, att)
169
+ join_value = Hash(ds.scope.opts[:join]).find do |value|
165
170
  (value.table_alias || value.table).to_s == att[:name]
166
171
  end
167
172
  fail Datasource::Error, "given scope does not join on #{name}, but it is required by #{att[:name]}" unless join_value
@@ -178,6 +183,10 @@ module Datasource
178
183
  klass
179
184
  end
180
185
 
186
+ define_singleton_method(:default_adapter) do
187
+ Datasource::Adapters::Sequel
188
+ end
189
+
181
190
  define_method(:primary_key) do
182
191
  klass.primary_key
183
192
  end
@@ -8,10 +8,9 @@ module Datasource
8
8
  base._attributes = (_attributes || {}).dup
9
9
  base._associations = (_associations || {}).dup
10
10
  base._loaders = (_loaders || {}).dup
11
- self.send :include, adapter
12
11
  end
13
12
 
14
- def adapter
13
+ def default_adapter
15
14
  @adapter ||= begin
16
15
  Datasource::Adapters.const_get(Datasource::Adapters.constants.first)
17
16
  end
@@ -68,7 +67,10 @@ module Datasource
68
67
  end
69
68
  end
70
69
 
71
- def initialize(scope)
70
+ attr_reader :scope, :expose_attributes, :expose_associations, :adapter
71
+
72
+ def initialize(scope, adapter = nil)
73
+ @adapter = adapter || self.class.default_adapter
72
74
  @scope =
73
75
  if self.class._update_scope
74
76
  self.class._update_scope.call(scope)
@@ -115,7 +117,7 @@ module Datasource
115
117
  end
116
118
 
117
119
  def get_select_values
118
- scope_table = primary_scope_table(@scope)
120
+ scope_table = adapter.primary_scope_table(self)
119
121
  select_values = Set.new
120
122
  select_values.add("#{scope_table}.#{primary_key}")
121
123
 
@@ -127,7 +129,7 @@ module Datasource
127
129
  att[:klass]._depends.keys.map(&:to_s).each do |name|
128
130
  next if name == scope_table
129
131
  next if name == "loaders"
130
- ensure_table_join!(name, att)
132
+ adapter.ensure_table_join!(self, name, att)
131
133
  end
132
134
  att[:klass]._depends.each_pair do |table, names|
133
135
  next if table.to_sym == :loaders
@@ -140,7 +142,7 @@ module Datasource
140
142
  select_values.add("(#{att[:klass].select_value}) as #{att[:name]}")
141
143
  att[:klass]._depends.each do |name|
142
144
  next if name == scope_table
143
- ensure_table_join!(name, att)
145
+ adapter.ensure_table_join!(self, name, att)
144
146
  end
145
147
  end
146
148
  end
@@ -153,11 +155,11 @@ module Datasource
153
155
  end
154
156
 
155
157
  def results(rows = nil)
156
- rows ||= get_rows
158
+ rows ||= adapter.get_rows(self)
157
159
 
158
160
  @expose_attributes.each do |name|
159
161
  att = self.class._attributes[name]
160
- fail Datasource::Error, "attribute #{name} doesn't exist for #{self.class.orm_klass.name}, did you forget to call \"computed :#{name}, <dependencies>\" in your datasource_module?" unless att
162
+ fail Datasource::Error, "attribute #{name} doesn't exist for #{self.class.orm_klass.name}, did you forget to call \"computed :#{name}, :db_column_dependency\" in your datasource_module? See https://github.com/mrbrdo/datasource#model-methods--virtual-attributes" unless att
161
163
  klass = att[:klass]
162
164
  next unless klass
163
165
 
@@ -3,25 +3,20 @@ require "active_model/serializer"
3
3
  module Datasource
4
4
  module ConsumerAdapters
5
5
  module ActiveModelSerializers
6
- superclass = if defined?(ActiveModel::Serializer::ArraySerializer)
7
- ActiveModel::Serializer::ArraySerializer
8
- else
9
- ActiveModel::ArraySerializer
10
- end
11
- class ArraySerializer < superclass
12
- def initialize(objects, options = {})
6
+ module ArraySerializer
7
+ def initialize_with_datasource(objects, options = {})
13
8
  datasource_class = options.delete(:datasource)
14
- adapter = Datasource::Base.adapter
15
- if adapter.is_scope?(objects)
9
+ adapter = Datasource.orm_adapters.find { |a| a.is_scope?(objects) }
10
+ if adapter && !adapter.scope_loaded?(objects)
16
11
  datasource_class ||= adapter.scope_to_class(objects).default_datasource
17
12
 
18
13
  records = objects
19
14
  .with_datasource(datasource_class)
20
15
  .for_serializer(options[:serializer]).all.to_a # all needed for Sequel eager loading
21
16
 
22
- super(records, options)
17
+ initialize_without_datasource(records, options)
23
18
  else
24
- super
19
+ initialize_without_datasource(objects, options)
25
20
  end
26
21
  end
27
22
  end
@@ -38,7 +33,8 @@ module Datasource
38
33
  serializer || "#{klass.name}Serializer".constantize
39
34
  end
40
35
 
41
- def to_datasource_select(result, klass, serializer = nil, serializer_assoc = nil)
36
+ def to_datasource_select(result, klass, serializer = nil, serializer_assoc = nil, adapter = nil)
37
+ adapter ||= Datasource::Base.default_adapter
42
38
  serializer ||= get_serializer_for(klass, serializer_assoc)
43
39
  result.concat(serializer._attributes)
44
40
  result_assocs = {}
@@ -46,12 +42,12 @@ module Datasource
46
42
 
47
43
  serializer._associations.each_pair do |name, serializer_assoc|
48
44
  # TODO: what if assoc is renamed in serializer?
49
- reflection = Datasource::Base.adapter.association_reflection(klass, name.to_sym)
45
+ reflection = adapter.association_reflection(klass, name.to_sym)
50
46
  assoc_class = reflection[:klass]
51
47
 
52
48
  name = name.to_s
53
49
  result_assocs[name] = []
54
- to_datasource_select(result_assocs[name], assoc_class, nil, serializer_assoc)
50
+ to_datasource_select(result_assocs[name], assoc_class, nil, serializer_assoc, adapter)
55
51
  end
56
52
  rescue Exception => ex
57
53
  if ex.is_a?(SystemStackError) || ex.is_a?(Datasource::RecursionError)
@@ -62,5 +58,18 @@ module Datasource
62
58
  end
63
59
  end
64
60
  end
65
- ArrayAMS = ConsumerAdapters::ActiveModelSerializers::ArraySerializer
61
+ end
62
+
63
+ array_serializer_class = if defined?(ActiveModel::Serializer::ArraySerializer)
64
+ ActiveModel::Serializer::ArraySerializer
65
+ else
66
+ ActiveModel::ArraySerializer
67
+ end
68
+
69
+ array_serializer_class.class_exec do
70
+ alias_method :initialize_without_datasource, :initialize
71
+ include Datasource::ConsumerAdapters::ActiveModelSerializers::ArraySerializer
72
+ def initialize(*args)
73
+ initialize_with_datasource(*args)
74
+ end
66
75
  end
data/lib/datasource.rb CHANGED
@@ -2,18 +2,39 @@ module Datasource
2
2
  Error = Class.new(StandardError)
3
3
  RecursionError = Class.new(StandardError)
4
4
 
5
- def self.load(adapter = nil)
6
- unless adapter
7
- adapter = if defined? ActiveRecord
8
- :activerecord
5
+ AdapterPaths = {
6
+ activerecord: 'datasource/adapters/active_record',
7
+ active_record: :activerecord,
8
+ sequel: 'datasource/adapters/sequel',
9
+ ams: 'datasource/consumer_adapters/active_model_serializers',
10
+ active_model_serializers: :ams
11
+ }
12
+
13
+ module_function
14
+ def load(*adapters)
15
+ if adapters.empty?
16
+ adapters = []
17
+ if defined? ActiveRecord
18
+ adapters.push(:activerecord)
9
19
  elsif defined? Sequel
10
- :sequel
20
+ adapters.push(:sequel)
21
+ end
22
+ if defined? ActiveModel::Serializer
23
+ adapters.push(:ams)
11
24
  end
12
25
  end
13
26
 
14
- require 'datasource/adapters/active_record' if [:activerecord, :active_record].include?(adapter)
15
- require 'datasource/adapters/sequel' if adapter == :sequel
16
- require 'datasource/consumer_adapters/active_model_serializers' if defined? ActiveModel::Serializer
27
+ adapters.each do |adapter|
28
+ adapter = AdapterPaths[adapter]
29
+ adapter = AdapterPaths[adapter] if adapter.is_a?(Symbol)
30
+ require adapter
31
+ end
32
+ end
33
+
34
+ def orm_adapters
35
+ @orm_adapters ||= begin
36
+ Datasource::Adapters.constants.map { |name| Datasource::Adapters.const_get(name) }
37
+ end
17
38
  end
18
39
  end
19
40
 
@@ -1,11 +1 @@
1
- Datasource.load(:activerecord)
2
-
3
- if defined? ActiveModel::Serializer
4
- if ActiveModel::Serializer.respond_to?(:config)
5
- ActiveModel::Serializer.config.array_serializer = Datasource::ArrayAMS
6
- else
7
- ActiveModel::Serializer.setup do |config|
8
- config.array_serializer = Datasource::ArrayAMS
9
- end
10
- end
11
- end
1
+ Datasource.load(:activerecord, :active_model_serializers)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datasource
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Berdajs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-09 00:00:00.000000000 Z
11
+ date: 2014-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_model_serializers
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sqlite3
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: activerecord
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +94,34 @@ dependencies:
66
94
  - - "~>"
67
95
  - !ruby/object:Gem::Version
68
96
  version: '4'
97
+ - !ruby/object:Gem::Dependency
98
+ name: sequel
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '4.17'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '4.17'
111
+ - !ruby/object:Gem::Dependency
112
+ name: database_cleaner
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.3'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.3'
69
125
  description:
70
126
  email:
71
127
  - mrbrdo@gmail.com
@@ -87,12 +143,6 @@ files:
87
143
  - lib/datasource/serializer.rb
88
144
  - lib/generators/datasource/install_generator.rb
89
145
  - lib/generators/datasource/templates/initializer.rb
90
- - test/active_record_helper.rb
91
- - test/schema.rb
92
- - test/test_helper.rb
93
- - test/test_loader.rb
94
- - test/test_scope.rb
95
- - test/test_serializer.rb
96
146
  homepage: https://github.com/mrbrdo/datasource
97
147
  licenses:
98
148
  - MIT
@@ -116,12 +166,5 @@ rubyforge_project:
116
166
  rubygems_version: 2.2.2
117
167
  signing_key:
118
168
  specification_version: 4
119
- summary: Ruby library for creating data source objects from database data
120
- test_files:
121
- - test/active_record_helper.rb
122
- - test/schema.rb
123
- - test/test_helper.rb
124
- - test/test_loader.rb
125
- - test/test_scope.rb
126
- - test/test_serializer.rb
127
- has_rdoc:
169
+ summary: Ruby library to automatically preload records for your serializers
170
+ test_files: []
@@ -1,23 +0,0 @@
1
- ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
2
- ActiveRecord::Migration.verbose = false
3
- load "schema.rb"
4
-
5
- def clean_db
6
- ActiveRecord::Base.connection.execute("DELETE FROM comments")
7
- ActiveRecord::Base.connection.execute("DELETE FROM posts")
8
- ActiveRecord::Base.connection.execute("DELETE FROM blogs")
9
- ActiveRecord::Base.connection.execute("DELETE FROM sqlite_sequence")
10
- end
11
-
12
- def assert_query_count(count)
13
- old_logger = ActiveRecord::Base.logger
14
- logger = StringIO.new
15
- ActiveRecord::Base.logger = Logger.new(logger)
16
- begin
17
- yield
18
- ensure
19
- ActiveRecord::Base.logger = old_logger
20
- # puts logger.string
21
- end
22
- assert_equal count, logger.string.lines.count
23
- end
data/test/schema.rb DELETED
@@ -1,19 +0,0 @@
1
- ActiveRecord::Schema.define(:version => 0) do
2
- create_table :blogs, :force => true do |t|
3
- t.string :title
4
- end
5
-
6
- create_table :posts, :force => true do |t|
7
- t.integer :blog_id
8
- t.string :title
9
- t.string :author_first_name
10
- t.string :author_last_name
11
- end
12
-
13
- create_table :comments, :force => true do |t|
14
- t.integer :post_id
15
- t.text :comment
16
- end
17
- end
18
-
19
- ActiveRecord::Base.send :include, Datasource::Adapters::ActiveRecord::Model
data/test/test_helper.rb DELETED
@@ -1,14 +0,0 @@
1
- # Configure Rails Environment
2
- ENV["RAILS_ENV"] = "test"
3
-
4
- require 'minitest/autorun'
5
- require 'active_support/all'
6
- require 'active_record'
7
- require 'datasource'
8
- require 'active_model_serializers'
9
- require 'pry'
10
-
11
- Datasource.load(:activerecord)
12
-
13
- # Load support files
14
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
data/test/test_loader.rb DELETED
@@ -1,79 +0,0 @@
1
- require 'test_helper'
2
- require 'active_record_helper'
3
-
4
- class LoaderTest < ActiveSupport::TestCase
5
- class Comment < ActiveRecord::Base
6
- self.table_name = "comments"
7
- belongs_to :post
8
- end
9
-
10
- class Post < ActiveRecord::Base
11
- self.table_name = "posts"
12
- has_many :comments
13
-
14
- datasource_module do
15
- loader :newest_comment, group_by: :post_id, one: true do |post_ids|
16
- Comment.for_serializer.where(post_id: post_ids)
17
- .group("post_id")
18
- .having("id = MAX(id)")
19
- .datasource_select(:post_id)
20
- end
21
-
22
- loader :newest_comment_text, array_to_hash: true do |post_ids|
23
- Comment.where(post_id: post_ids)
24
- .group("post_id")
25
- .having("id = MAX(id)")
26
- .pluck("post_id, comment")
27
- end
28
-
29
- loader :ordered_comments, group_by: :post_id do |post_ids|
30
- Comment.for_serializer(CommentSerializer).where(post_id: post_ids)
31
- .order("post_id, id desc")
32
- .datasource_select(:post_id)
33
- end
34
-
35
- computed :newest_comment, loaders: :newest_comment
36
- computed :newest_comment_text, loaders: :newest_comment_text
37
- computed :ordered_comments, loaders: :ordered_comments
38
- end
39
-
40
- def name_initials
41
- return unless author_first_name && author_last_name
42
- author_first_name[0].upcase + author_last_name[0].upcase
43
- end
44
- end
45
-
46
- class CommentSerializer < ActiveModel::Serializer
47
- attributes :id, :comment
48
- end
49
-
50
- class PostSerializer < ActiveModel::Serializer
51
- attributes :id, :title, :newest_comment, :newest_comment_text, :ordered_comments
52
-
53
- def newest_comment
54
- CommentSerializer.new(object.loaded_values[:newest_comment]).as_json
55
- end
56
-
57
- def newest_comment_text
58
- object.loaded_values[:newest_comment_text]
59
- end
60
-
61
- def ordered_comments
62
- Datasource::ArrayAMS.new(object.loaded_values[:ordered_comments]).as_json
63
- end
64
- end
65
-
66
- def test_loader
67
- post = Post.create! title: "First Post"
68
- 2.times { |i| post.comments.create! comment: "Comment #{i+1}" }
69
-
70
- assert_query_count(4) do
71
- assert_equal Datasource::ArrayAMS.new(Post.all).as_json,
72
- [{:id=>1, :title=>"First Post", :newest_comment=>{"comment"=>{:id=>2, :comment=>"Comment 2"}}, :newest_comment_text=>"Comment 2", :ordered_comments=>[{:id=>2, :comment=>"Comment 2"}, {:id=>1, :comment=>"Comment 1"}]}]
73
- end
74
- end
75
-
76
- def teardown
77
- clean_db
78
- end
79
- end
data/test/test_scope.rb DELETED
@@ -1,50 +0,0 @@
1
- require 'test_helper'
2
- require 'active_record_helper'
3
-
4
- class ScopeTest < ActiveSupport::TestCase
5
- class Post < ActiveRecord::Base
6
- belongs_to :blog
7
-
8
- datasource_module do
9
- query :author_name do
10
- "posts.author_first_name || ' ' || posts.author_last_name"
11
- end
12
- end
13
- end
14
-
15
- class PostSerializer < ActiveModel::Serializer
16
- attributes :id, :title, :author_name
17
- end
18
-
19
- def test_first
20
- Post.create! title: "The Post", author_first_name: "John", author_last_name: "Doe", blog_id: 10
21
- post = Post.for_serializer.first
22
-
23
- assert_equal("The Post", post.title)
24
- assert_equal("John Doe", post.author_name)
25
- assert_raises(ActiveModel::MissingAttributeError) { post.blog_id }
26
- end
27
-
28
- def test_find
29
- post = Post.create! title: "The Post", author_first_name: "John", author_last_name: "Doe", blog_id: 10
30
- post = Post.for_serializer.find(post.id)
31
-
32
- assert_equal("The Post", post.title)
33
- assert_equal("John Doe", post.author_name)
34
- assert_raises(ActiveModel::MissingAttributeError) { post.blog_id }
35
- end
36
-
37
- def test_each
38
- post = Post.create! title: "The Post", author_first_name: "John", author_last_name: "Doe", blog_id: 10
39
-
40
- Post.for_serializer.each do |post|
41
- assert_equal("The Post", post.title)
42
- assert_equal("John Doe", post.author_name)
43
- assert_raises(ActiveModel::MissingAttributeError) { post.blog_id }
44
- end
45
- end
46
-
47
- def teardown
48
- clean_db
49
- end
50
- end
@@ -1,52 +0,0 @@
1
- require 'test_helper'
2
- require 'active_record_helper'
3
-
4
- class SerializerTest < ActiveSupport::TestCase
5
- class Post < ActiveRecord::Base
6
- belongs_to :blog
7
-
8
- datasource_module do
9
- query :author_name do
10
- "posts.author_first_name || ' ' || posts.author_last_name"
11
- end
12
- end
13
- end
14
-
15
- class Blog < ActiveRecord::Base
16
- has_many :posts
17
- end
18
-
19
- class BlogSerializer < ActiveModel::Serializer
20
- attributes :id, :title
21
-
22
- has_many :posts
23
- end
24
-
25
- class PostSerializer < ActiveModel::Serializer
26
- attributes :id, :title, :author_name
27
- end
28
-
29
- def test_blogs_and_posts_serializer
30
- blog = Blog.create! title: "Blog 1"
31
- blog.posts.create! title: "Post 1", author_first_name: "John", author_last_name: "Doe"
32
- blog.posts.create! title: "Post 2", author_first_name: "Maria", author_last_name: "Doe"
33
- blog = Blog.create! title: "Blog 2"
34
-
35
- expected_result = [
36
- {:id =>1, :title =>"Blog 1", :posts =>[
37
- {:id =>1, :title =>"Post 1", :author_name =>"John Doe"},
38
- {:id =>2, :title =>"Post 2", :author_name =>"Maria Doe"}
39
- ]},
40
- {:id =>2, :title =>"Blog 2", :posts =>[]}
41
- ]
42
-
43
- assert_query_count(2) do
44
- serializer = Datasource::ArrayAMS.new(Blog.all)
45
- assert_equal(expected_result, serializer.as_json)
46
- end
47
- end
48
-
49
- def teardown
50
- clean_db
51
- end
52
- end