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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dffcac805f1cbe701d082c2b965aeaa98c89c289fbb1d5bf3e164e5ce5ad8af1
|
4
|
+
data.tar.gz: a94cda603a6c408c77f751e2d9358a1f52decb34464bbd8967af9f16fd978712
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: afeb27a07b31d12257161618ea4d9a17088963014d354691de035b3e0e423d7f8d5d1c62991f4c9256282ec7ab4afecf32806ba4f56182cdb9d36a91e4436bf0
|
7
|
+
data.tar.gz: aecefa1ddbcb7179b5b24805d1ffcadbd71a25a1f4888c8bb89a433f7900f39dd576885a4e85e33502f568cef82b9da04eccdcaa3f4d9c44964ac59631595442
|
data/lib/occams-record.rb
CHANGED
@@ -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
|
#
|
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.
|
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-
|
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/
|