occams-record 1.0.0.rc8 → 1.0.0.rc9

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77e8b9c5da26d6d76932bfca57a9470648e97bb07ca33ee3fbdfe7fa5e67aed7
4
- data.tar.gz: 694e75291ee550813f0732cd8d4d2361e5c6e44f324637789af0afa4637e7865
3
+ metadata.gz: dffcac805f1cbe701d082c2b965aeaa98c89c289fbb1d5bf3e164e5ce5ad8af1
4
+ data.tar.gz: a94cda603a6c408c77f751e2d9358a1f52decb34464bbd8967af9f16fd978712
5
5
  SHA512:
6
- metadata.gz: 5831bafffa9f1da1677d2dff25d59d9a1480be2db886a0e275fa9a7e0d7f874dd22314bd18632df383e7213cb5e0fd50b046a526e44d5cae553c7d807af6bb0a
7
- data.tar.gz: 40ab48b4680d2cf5aabbd48fa90e5564111fc77239bbfa6a0ec7ecdd7f3cc05bb4a906fd28134706a9a216c0eb8c2c9b9cf449791ec1a6dc225334d9fe356233
6
+ metadata.gz: afeb27a07b31d12257161618ea4d9a17088963014d354691de035b3e0e423d7f8d5d1c62991f4c9256282ec7ab4afecf32806ba4f56182cdb9d36a91e4436bf0
7
+ data.tar.gz: aecefa1ddbcb7179b5b24805d1ffcadbd71a25a1f4888c8bb89a433f7900f39dd576885a4e85e33502f568cef82b9da04eccdcaa3f4d9c44964ac59631595442
@@ -2,7 +2,8 @@ require 'active_record'
2
2
  require 'occams-record/version'
3
3
  require 'occams-record/merge'
4
4
  require 'occams-record/eager_loaders'
5
- require 'occams-record/results'
5
+ require 'occams-record/results/results'
6
+ require 'occams-record/results/row'
6
7
  require 'occams-record/query'
7
8
  require 'occams-record/raw_query'
8
9
  require 'occams-record/errors'
@@ -56,13 +56,14 @@ module OccamsRecord
56
56
  node.send(link.name).reduce(Set.new) { |a, child|
57
57
  result = reduce(child, depth + 1)
58
58
  case result
59
+ when nil then a
59
60
  when Array then a + result
60
61
  else a << result
61
62
  end
62
63
  }.to_a
63
64
  when :has_one, :belongs_to
64
65
  child = node.send(link.name)
65
- reduce(child, depth + 1)
66
+ child ? reduce(child, depth + 1) : nil
66
67
  else
67
68
  raise "Unsupported through chain link type '#{link.macro}'"
68
69
  end
@@ -0,0 +1,69 @@
1
+ module OccamsRecord
2
+ # Classes and methods for handing query results.
3
+ module Results
4
+ # ActiveRecord's internal type casting API changes from version to version.
5
+ CASTER = case ActiveRecord::VERSION::MAJOR
6
+ when 4 then :type_cast_from_database
7
+ when 5 then :deserialize
8
+ end
9
+
10
+ #
11
+ # Dynamically build a class for a specific set of result rows. It inherits from OccamsRecord::Results::Row, and optionall includes
12
+ # a user-defined module.
13
+ #
14
+ # @param column_names [Array<String>] the column names in the result set. The order MUST match the order returned by the query.
15
+ # @param column_types [Hash] Column name => type from an ActiveRecord::Result
16
+ # @param association_names [Array<String>] names of associations that will be eager loaded into the results.
17
+ # @param model [ActiveRecord::Base] the AR model representing the table (it holds column & type info).
18
+ # @param modules [Array<Module>] (optional)
19
+ # @return [OccamsRecord::Results::Row] a class customized for this result set
20
+ #
21
+ def self.klass(column_names, column_types, association_names = [], model: nil, modules: nil)
22
+ Class.new(Results::Row) do
23
+ Array(modules).each { |mod| prepend mod } if modules
24
+
25
+ self.columns = column_names.map(&:to_s)
26
+ self.associations = association_names.map(&:to_s)
27
+ self.model_name = model ? model.name : nil
28
+ self.table_name = model ? model.table_name : nil
29
+ self.primary_key = model&.primary_key&.to_s
30
+
31
+ # Build getters & setters for associations. (We need setters b/c they're set AFTER the row is initialized
32
+ attr_accessor(*association_names)
33
+
34
+ # Build id getters for associations, e.g. "widget_ids" for "widgets"
35
+ self.associations.each do |assoc|
36
+ if (ref = model.reflections[assoc]) and !ref.polymorphic? and (ref.macro == :has_many or ref.macro == :has_and_belongs_to_many)
37
+ pkey = ref.association_primary_key.to_sym
38
+ define_method "#{assoc.singularize}_ids" do
39
+ begin
40
+ self.send(assoc).map(&pkey).uniq
41
+ rescue NoMethodError => e
42
+ raise MissingColumnError.new(self, e.name)
43
+ end
44
+ end
45
+ end
46
+ end if model
47
+
48
+ # Build a getter for each attribute returned by the query. The values will be type converted on demand.
49
+ model_column_types = model ? model.attributes_builder.types : {}
50
+ self.columns.each_with_index do |col, idx|
51
+ type =
52
+ column_types[col] ||
53
+ model_column_types[col] ||
54
+ raise("OccamsRecord: Column `#{col}` does not exist on model `#{self.model_name}`")
55
+
56
+ case type.type
57
+ when :datetime
58
+ define_method(col) { @cast_values[idx] ||= type.send(CASTER, @raw_values[idx])&.in_time_zone }
59
+ when :boolean
60
+ define_method(col) { @cast_values[idx] ||= type.send(CASTER, @raw_values[idx]) }
61
+ define_method("#{col}?") { !!send(col) }
62
+ else
63
+ define_method(col) { @cast_values[idx] ||= type.send(CASTER, @raw_values[idx]) }
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,71 +1,5 @@
1
1
  module OccamsRecord
2
- # Classes and methods for handing query results.
3
2
  module Results
4
- # ActiveRecord's internal type casting API changes from version to version.
5
- CASTER = case ActiveRecord::VERSION::MAJOR
6
- when 4 then :type_cast_from_database
7
- when 5 then :deserialize
8
- end
9
-
10
- #
11
- # Dynamically build a class for a specific set of result rows. It inherits from OccamsRecord::Results::Row, and optionall includes
12
- # a user-defined module.
13
- #
14
- # @param column_names [Array<String>] the column names in the result set. The order MUST match the order returned by the query.
15
- # @param column_types [Hash] Column name => type from an ActiveRecord::Result
16
- # @param association_names [Array<String>] names of associations that will be eager loaded into the results.
17
- # @param model [ActiveRecord::Base] the AR model representing the table (it holds column & type info).
18
- # @param modules [Array<Module>] (optional)
19
- # @return [OccamsRecord::Results::Row] a class customized for this result set
20
- #
21
- def self.klass(column_names, column_types, association_names = [], model: nil, modules: nil)
22
- Class.new(Results::Row) do
23
- Array(modules).each { |mod| prepend mod } if modules
24
-
25
- self.columns = column_names.map(&:to_s)
26
- self.associations = association_names.map(&:to_s)
27
- self.model_name = model ? model.name : nil
28
- self.table_name = model ? model.table_name : nil
29
- self.primary_key = model&.primary_key&.to_s
30
-
31
- # Build getters & setters for associations. (We need setters b/c they're set AFTER the row is initialized
32
- attr_accessor(*association_names)
33
-
34
- # Build id getters for associations, e.g. "widget_ids" for "widgets"
35
- self.associations.each do |assoc|
36
- if (ref = model.reflections[assoc]) and !ref.polymorphic? and (ref.macro == :has_many or ref.macro == :has_and_belongs_to_many)
37
- pkey = ref.association_primary_key.to_sym
38
- define_method "#{assoc.singularize}_ids" do
39
- begin
40
- self.send(assoc).map(&pkey).uniq
41
- rescue NoMethodError => e
42
- raise MissingColumnError.new(self, e.name)
43
- end
44
- end
45
- end
46
- end if model
47
-
48
- # Build a getter for each attribute returned by the query. The values will be type converted on demand.
49
- model_column_types = model ? model.attributes_builder.types : {}
50
- self.columns.each_with_index do |col, idx|
51
- type =
52
- column_types[col] ||
53
- model_column_types[col] ||
54
- raise("OccamsRecord: Column `#{col}` does not exist on model `#{self.model_name}`")
55
-
56
- case type.type
57
- when :datetime
58
- define_method(col) { @cast_values[idx] ||= type.send(CASTER, @raw_values[idx])&.in_time_zone }
59
- when :boolean
60
- define_method(col) { @cast_values[idx] ||= type.send(CASTER, @raw_values[idx]) }
61
- define_method("#{col}?") { !!send(col) }
62
- else
63
- define_method(col) { @cast_values[idx] ||= type.send(CASTER, @raw_values[idx]) }
64
- end
65
- end
66
- end
67
- end
68
-
69
3
  #
70
4
  # Abstract class for result rows.
71
5
  #
@@ -3,5 +3,5 @@
3
3
  #
4
4
  module OccamsRecord
5
5
  # Library version
6
- VERSION = '1.0.0.rc8'.freeze
6
+ VERSION = '1.0.0.rc9'.freeze
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: occams-record
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc8
4
+ version: 1.0.0.rc9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Hollinger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-20 00:00:00.000000000 Z
11
+ date: 2019-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -57,7 +57,8 @@ files:
57
57
  - lib/occams-record/merge.rb
58
58
  - lib/occams-record/query.rb
59
59
  - lib/occams-record/raw_query.rb
60
- - lib/occams-record/results.rb
60
+ - lib/occams-record/results/results.rb
61
+ - lib/occams-record/results/row.rb
61
62
  - lib/occams-record/ugly.rb
62
63
  - lib/occams-record/version.rb
63
64
  homepage: https://jhollinger.github.io/occams-record/