associate_jsonb 0.0.3 → 0.0.4

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: cfb874f973a7bd4611949cd39c064ce2de1a06bf2a7cd68fc526ef7c41f0c3e4
4
- data.tar.gz: d7c7f3b56c0c247c5f73610e537f6a39a435cade4e67ce93cf29f6a856301968
3
+ metadata.gz: 5cb22feba951a6241ccada849b6d17ae06a4a84c797a49ae139844917d50474c
4
+ data.tar.gz: 910b39ddc0f89d8525439d9d4e74244a62bbf3f4d07cb333306879312588dfda
5
5
  SHA512:
6
- metadata.gz: f70971458fa4e3833058cf3904a070374ced50507a033b3bc619bdbb0f8a0623f9fd61da4ae967c11d71853874296ddf5801f152cf0ec9f18be614cc27d1c961
7
- data.tar.gz: 2f737173b83cc355772c6d66f760b5bc56faead1fbdc63d4d0cb2d63d37a8a1c24eed79e8a69b5dd7e1f3088b2bd3374b8b30316688e06a72b38f76621b208aa
6
+ metadata.gz: 5382c87315fbbbc8bc52ebb5efb605e60373c7f24e9d681a008f5d5c53dc26649df89f7233ca1b3b6962fdd16a891c9072e55577a3c40e655faa54f3ec0dc375
7
+ data.tar.gz: 3570c685cde53a273f70f5d434d1daacbc32b260b0b0500a3e6ef801b18a50fdd007a1970ede0d692a5eee89a87eba46b73ced15019514cfafece65b01c588a8
@@ -27,7 +27,27 @@ ActiveSupport.on_load :active_record do
27
27
  ActiveRecord::Base.include AssociateJsonb::Associations
28
28
 
29
29
  Arel::Nodes.include AssociateJsonb::ArelNodes
30
- Arel::Nodes::Binary.include AssociateJsonb::ArelNodeExtensions::Binary
30
+
31
+ Arel::Nodes::Binary.prepend(
32
+ AssociateJsonb::ArelExtensions::Nodes::Binary
33
+ )
34
+
35
+ Arel::Nodes::TableAlias.prepend(
36
+ AssociateJsonb::ArelExtensions::Nodes::TableAlias
37
+ )
38
+
39
+ Arel::Table.prepend(
40
+ AssociateJsonb::ArelExtensions::Table
41
+ )
42
+
43
+ Arel::Visitors::Visitor.singleton_class.prepend(
44
+ AssociateJsonb::ArelExtensions::Visitors::Visitor
45
+ )
46
+
47
+
48
+ ActiveRecord::Associations::AliasTracker.prepend(
49
+ AssociateJsonb::Associations::AliasTracker
50
+ )
31
51
 
32
52
  ActiveRecord::Associations::Builder::BelongsTo.extend(
33
53
  AssociateJsonb::Associations::Builder::BelongsTo
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module AssociateJsonb
5
+ module ArelExtensions
6
+ module Nodes
7
+ module Binary
8
+ def original_left
9
+ left
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module AssociateJsonb
5
+ module ArelExtensions
6
+ module Nodes
7
+ module TableAlias
8
+ attr_reader :store_tracker
9
+
10
+ def initialize(*args, store_columns: nil)
11
+ @store_columns = store_columns
12
+ super(*args)
13
+ end
14
+
15
+ def with_store_tracker(tracker)
16
+ @store_tracker = tracker
17
+ self
18
+ end
19
+
20
+ def [](name)
21
+ return super unless store_col = store_tracker&.get(name)
22
+
23
+ attr = ::Arel::Nodes::Jsonb::DashArrow.
24
+ new(self, self[store_col[:store]], store_col[:key])
25
+
26
+ if cast_as = (store_col[:cast] && store_col[:cast][:sql_type])
27
+ attr = ::Arel::Nodes::NamedFunction.new(
28
+ "CAST",
29
+ [ attr.as(cast_as) ]
30
+ )
31
+ end
32
+
33
+ Arel::Nodes::Jsonb::Attribute.new(self, name, attr)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module AssociateJsonb
5
+ module ArelExtensions
6
+ module Table
7
+ attr_reader :store_tracker
8
+
9
+ def initialize(*args, store_tracker: nil, **opts)
10
+ @store_tracker = store_tracker
11
+ super(*args, **opts)
12
+ end
13
+
14
+ def alias(...)
15
+ super(...).with_store_tracker(store_tracker)
16
+ end
17
+
18
+ def with_store_tracker(tracker)
19
+ @store_tracker = tracker
20
+ self
21
+ end
22
+
23
+ def [](name)
24
+ return super unless store_col = store_tracker&.get(name)
25
+
26
+ attr = ::Arel::Nodes::Jsonb::DashArrow.
27
+ new(self, self[store_col[:store]], store_col[:key])
28
+
29
+ if cast_as = (store_col[:cast] && store_col[:cast][:sql_type])
30
+ attr = ::Arel::Nodes::NamedFunction.new(
31
+ "CAST",
32
+ [ attr.as(cast_as) ]
33
+ )
34
+ end
35
+
36
+ Arel::Nodes::Jsonb::Attribute.new(self, name, attr)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module AssociateJsonb
5
+ module ArelExtensions
6
+ module Visitors
7
+ module Visitor
8
+ def dispatch_cache
9
+ @dispatch_cache ||= Hash.new do |hash, klass|
10
+ hash[klass] =
11
+ "visit_#{(klass.name || '').
12
+ sub("AssociateJsonb::ArelNodes::SqlCasted", "Arel::Nodes::").
13
+ gsub('::', '_')}"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module AssociateJsonb
5
+ module ArelNodes
6
+ module Jsonb
7
+ class Attribute
8
+ attr_reader :relation, :name, :delegated
9
+
10
+ def initialize(relation, name, delegated)
11
+ @relation = relation,
12
+ @name = name
13
+ @delegated = delegated
14
+ end
15
+
16
+ def lower
17
+ relation.lower self
18
+ end
19
+
20
+ def type_cast_for_database(value)
21
+ relation.type_cast_for_database(name, value)
22
+ end
23
+
24
+ def able_to_type_cast?
25
+ relation.able_to_type_cast?
26
+ end
27
+
28
+ def respond_to_missing?(mthd, include_private = false)
29
+ delegated.respond_to?(mthd, include_private)
30
+ end
31
+
32
+ def method_missing(mthd, *args, **opts, &block)
33
+ delegated.public_send(mthd, *args, **opts, &block)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module AssociateJsonb
5
+ module ArelNodes
6
+ class SqlCastedBinary < ::Arel::Nodes::Binary
7
+ attr_reader :original_left
8
+ def initialize(left, cast_as, right)
9
+ @original_left = left
10
+ super(
11
+ ::Arel::Nodes::NamedFunction.new(
12
+ "CAST",
13
+ [ left.as(cast_as) ]
14
+ ),
15
+ right
16
+ )
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,20 +1,34 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
+ # module AssociateJsonb
5
+ # module ArelNodes
6
+ # class SqlCastedEquality < ::Arel::Nodes::Equality
7
+ # attr_reader :original_left
8
+ # def initialize(left, cast_as, right)
9
+ # @original_left = left
10
+ # super(
11
+ # ::Arel::Nodes::NamedFunction.new(
12
+ # "CAST",
13
+ # [ left.as(cast_as) ]
14
+ # ),
15
+ # right
16
+ # )
17
+ # end
18
+ # end
19
+ # end
20
+ # end
21
+
22
+
23
+ # encoding: utf-8
24
+ # frozen_string_literal: true
25
+
4
26
  module AssociateJsonb
5
27
  module ArelNodes
6
- class SqlCastedEquality < ::Arel::Nodes::Equality
7
- attr_reader :original_left
8
- def initialize(left, cast_as, right)
9
- @original_left = left
10
- super(
11
- ::Arel::Nodes::NamedFunction.new(
12
- "CAST",
13
- [ left.as(cast_as) ]
14
- ),
15
- right
16
- )
17
- end
28
+ class SqlCastedEquality < AssociateJsonb::ArelNodes::SqlCastedBinary
29
+ def operator; :== end
30
+ alias :operand1 :left
31
+ alias :operand2 :right
18
32
  end
19
33
  end
20
34
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/string/conversions"
4
+
5
+ module AssociateJsonb
6
+ module Associations
7
+ module AliasTracker # :nodoc:
8
+ def aliased_table_for(table_name, aliased_name, type_caster, store_tracker = nil)
9
+ super(table_name, aliased_name, type_caster).with_store_tracker(store_tracker)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -4,6 +4,22 @@
4
4
  module AssociateJsonb
5
5
  module Associations
6
6
  module AssociationScope #:nodoc:
7
+
8
+ def get_chain(reflection, association, tracker)
9
+ name = reflection.name
10
+ chain = [ActiveRecord::Reflection::RuntimeReflection.new(reflection, association)]
11
+ reflection.chain.drop(1).each do |refl|
12
+ aliased_table = tracker.aliased_table_for(
13
+ refl.table_name,
14
+ refl.alias_candidate(name),
15
+ refl.klass.type_caster,
16
+ refl.klass.store_column_attribute_tracker
17
+ )
18
+ chain << ActiveRecord::Associations::AssociationScope::ReflectionProxy.new(refl, aliased_table)
19
+ end
20
+ chain
21
+ end
22
+
7
23
  # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
8
24
  def last_chain_scope(scope, owner_reflection, owner)
9
25
  reflection = owner_reflection.instance_variable_get(:@reflection)
@@ -42,23 +58,6 @@ module AssociateJsonb
42
58
  node_klass = Arel::Nodes::Jsonb::DashDoubleArrow
43
59
  end
44
60
 
45
- # scope.where!(
46
- # Arel::Nodes::HashableNamedFunction.new(
47
- # "CAST",
48
- # [
49
- # node_klass.
50
- # new(table, table[jsonb_column], store_key).
51
- # as(sql_type)
52
- # ]
53
- # ).eq(
54
- # Arel::Nodes::BindParam.new(
55
- # ActiveRecord::Relation::QueryAttribute.new(
56
- # store_key, value, type
57
- # )
58
- # )
59
- # )
60
- # )
61
-
62
61
  scope.where!(
63
62
  Arel::Nodes::SqlCastedEquality.new(
64
63
  node_klass.new(table, table[jsonb_column], store_key),
@@ -70,30 +69,6 @@ module AssociateJsonb
70
69
  )
71
70
  )
72
71
  )
73
-
74
- # scope.where!(
75
- # Arel::Nodes::Jsonb::DashDoubleArrow.
76
- # new(table, table[jsonb_column], store_key).
77
- # eq(
78
- # Arel::Nodes::BindParam.new(
79
- # ActiveRecord::Relation::QueryAttribute.new(
80
- # store_key, value, ActiveModel::Type::String.new
81
- # )
82
- # )
83
- # )
84
- # )
85
-
86
- # scope.where!(
87
- # node_klass.new(
88
- # table, table[jsonb_column], store_key
89
- # ).eq(
90
- # Arel::Nodes::BindParam.new(
91
- # ActiveRecord::Relation::QueryAttribute.new(
92
- # store_key, value, type
93
- # )
94
- # )
95
- # )
96
- # )
97
72
  end
98
73
  end
99
74
  end
@@ -33,6 +33,7 @@ module AssociateJsonb
33
33
 
34
34
  opts = {}
35
35
  foreign_type = :integer
36
+ sql_type = "numeric"
36
37
  begin
37
38
  primary_key = reflection.active_record_primary_key.to_s
38
39
  primary_column = reflection.klass.columns.find {|col| col.name == primary_key }
@@ -40,6 +41,7 @@ module AssociateJsonb
40
41
  if primary_column
41
42
  foreign_type = primary_column.type
42
43
  sql_data = primary_column.sql_type_metadata.as_json
44
+ sql_type = sql_data["sql_type"]
43
45
  %i[ limit precision scale ].each do |k|
44
46
  opts[k] = sql_data[k.to_s] if sql_data[k.to_s]
45
47
  end
@@ -50,7 +52,7 @@ module AssociateJsonb
50
52
  end
51
53
 
52
54
  mixin.instance_eval <<-CODE, __FILE__, __LINE__ + 1
53
- store_column_attribute(:#{store}, :#{foreign_key}, :#{foreign_type}, key: "#{key}", **opts)
55
+ store_column_attribute(:#{store}, :#{foreign_key}, foreign_type, sql_type: sql_type, key: "#{key}", **opts)
54
56
  CODE
55
57
  end
56
58
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/string/conversions"
4
+
5
+ module AssociateJsonb
6
+ module Associations
7
+ module JoinDependency # :nodoc:
8
+ private
9
+ def table_aliases_for(parent, node)
10
+ node.reflection.chain.map { |reflection|
11
+ alias_tracker.aliased_table_for(
12
+ reflection.table_name,
13
+ table_alias_for(reflection, parent, reflection != node.reflection),
14
+ reflection.klass.type_caster,
15
+ reflection.klass.store_column_attribute_tracker
16
+ )
17
+ }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -15,6 +15,22 @@ module AssociateJsonb
15
15
  [name, value]
16
16
  }.to_h
17
17
  end
18
+
19
+ private
20
+ def equalities(predicates)
21
+ equalities = []
22
+
23
+ predicates.each do |node|
24
+ case node
25
+ when Arel::Nodes::Equality, Arel::Nodes::SqlCastedEquality
26
+ equalities << node
27
+ when Arel::Nodes::And
28
+ equalities.concat equalities(node.children)
29
+ end
30
+ end
31
+
32
+ equalities
33
+ end
18
34
  end
19
35
  end
20
36
  end
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module AssociateJsonb
5
- VERSION = "0.0.3"
5
+ VERSION = "0.0.4"
6
6
  end
@@ -12,14 +12,25 @@ module AssociateJsonb
12
12
  @names_list ||= {}
13
13
  end
14
14
 
15
- def add_name(name, store, key)
16
- @names_list ||= {}
17
- @names_list[name.to_s.freeze] = { store: store, key: key }
15
+ def add_name(name, store, key, cast)
16
+ names_list[name.to_s.freeze] = { store: store, key: key, cast: cast }
18
17
  end
19
18
 
20
19
  def has_name?(name)
21
20
  names_list.key? name.to_s
22
21
  end
22
+
23
+ def get(name)
24
+ names_list[name.to_s]
25
+ end
26
+
27
+ def store_for(name)
28
+ (get(name) || {})[:store]
29
+ end
30
+
31
+ def key_for(name)
32
+ (get(name) || {})[:key]
33
+ end
23
34
  end
24
35
 
25
36
  included do
@@ -37,6 +48,10 @@ module AssociateJsonb
37
48
  super
38
49
  end
39
50
 
51
+ def arel_table
52
+ super.with_store_tracker(store_column_attribute_tracker)
53
+ end
54
+
40
55
  def initialize_store_column_attribute_tracker
41
56
  @store_column_attribute_tracker = const_set(:StoreColumnAttributeTracker, StoreColumnAttributeTracker.new)
42
57
  private_constant :StoreColumnAttributeTracker
@@ -56,9 +71,9 @@ module AssociateJsonb
56
71
  end
57
72
  end
58
73
 
59
- def add_store_column_attribute_name(name, store, key)
74
+ def add_store_column_attribute_name(name, store, key, cast_opts)
60
75
  store_column_attribute_tracker.synchronize do
61
- store_column_attribute_tracker.add_name(name, store, key)
76
+ store_column_attribute_tracker.add_name(name, store, key, cast_opts)
62
77
  end
63
78
  end
64
79
 
@@ -83,16 +98,16 @@ module AssociateJsonb
83
98
  store_column_attribute :data, *args, **opts
84
99
  end
85
100
 
86
- def store_column_attribute(store, attr, *opts, key: nil, **attribute_opts)
101
+ def store_column_attribute(store, attr, cast_type = ActiveRecord::Type::Value.new, sql_type: nil, key: nil, **attribute_opts)
87
102
  store = store.to_sym
88
103
  attr = attr.to_sym
89
104
  key ||= attr
90
105
  key = key.to_s
91
106
  array = attribute_opts[:array]
92
- attribute attr, *opts, **attribute_opts
107
+ attribute attr, cast_type, **attribute_opts
93
108
 
94
109
  instance_eval <<-CODE, __FILE__, __LINE__ + 1
95
- add_store_column_attribute_name("#{attr}", :#{store}, "#{key}")
110
+ add_store_column_attribute_name("#{attr}", :#{store}, "#{key}", { sql_type: sql_type, type: cast_type, opts: attribute_opts })
96
111
  CODE
97
112
 
98
113
  include WithStoreAttribute::InstanceMethodsOnActivation.new(self, store, attr, key, array)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: associate_jsonb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sampson Crowley
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-14 00:00:00.000000000 Z
11
+ date: 2020-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -122,15 +122,21 @@ files:
122
122
  - README.md
123
123
  - Rakefile
124
124
  - lib/associate_jsonb.rb
125
- - lib/associate_jsonb/arel_node_extensions/binary.rb
125
+ - lib/associate_jsonb/arel_extensions/nodes/binary.rb
126
+ - lib/associate_jsonb/arel_extensions/nodes/table_alias.rb
127
+ - lib/associate_jsonb/arel_extensions/table.rb
128
+ - lib/associate_jsonb/arel_extensions/visitors/visitor.rb
126
129
  - lib/associate_jsonb/arel_nodes/jsonb/at_arrow.rb
130
+ - lib/associate_jsonb/arel_nodes/jsonb/attribute.rb
127
131
  - lib/associate_jsonb/arel_nodes/jsonb/bindable_operator.rb
128
132
  - lib/associate_jsonb/arel_nodes/jsonb/dash_arrow.rb
129
133
  - lib/associate_jsonb/arel_nodes/jsonb/dash_double_arrow.rb
130
134
  - lib/associate_jsonb/arel_nodes/jsonb/double_pipe.rb
131
135
  - lib/associate_jsonb/arel_nodes/jsonb/hash_arrow.rb
132
136
  - lib/associate_jsonb/arel_nodes/jsonb/operator.rb
137
+ - lib/associate_jsonb/arel_nodes/sql_casted_binary.rb
133
138
  - lib/associate_jsonb/arel_nodes/sql_casted_equality.rb
139
+ - lib/associate_jsonb/associations/alias_tracker.rb
134
140
  - lib/associate_jsonb/associations/association.rb
135
141
  - lib/associate_jsonb/associations/association_scope.rb
136
142
  - lib/associate_jsonb/associations/belongs_to_association.rb
@@ -139,6 +145,7 @@ files:
139
145
  - lib/associate_jsonb/associations/builder/has_one.rb
140
146
  - lib/associate_jsonb/associations/conflicting_association.rb
141
147
  - lib/associate_jsonb/associations/has_many_association.rb
148
+ - lib/associate_jsonb/associations/join_dependency.rb
142
149
  - lib/associate_jsonb/associations/preloader/association.rb
143
150
  - lib/associate_jsonb/connection_adapters.rb
144
151
  - lib/associate_jsonb/connection_adapters/reference_definition.rb
@@ -1,12 +0,0 @@
1
- # encoding: utf-8
2
- # frozen_string_literal: true
3
-
4
- module AssociateJsonb
5
- module ArelNodeExtensions
6
- module Binary
7
- def original_left
8
- left
9
- end
10
- end
11
- end
12
- end