superstore 2.4.4 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +4 -6
  3. data/Gemfile +2 -3
  4. data/{Gemfile-rails4.2 → Gemfile.rails6} +2 -3
  5. data/README.md +4 -34
  6. data/lib/superstore.rb +17 -18
  7. data/lib/superstore/adapters/abstract_adapter.rb +1 -27
  8. data/lib/superstore/adapters/jsonb_adapter.rb +4 -132
  9. data/lib/superstore/associations.rb +6 -1
  10. data/lib/superstore/associations/association.rb +6 -0
  11. data/lib/superstore/associations/association_scope.rb +20 -0
  12. data/lib/superstore/associations/belongs_to.rb +3 -1
  13. data/lib/superstore/associations/has_many.rb +15 -2
  14. data/lib/superstore/associations/reflection.rb +8 -2
  15. data/lib/superstore/attribute_assignment.rb +7 -0
  16. data/lib/superstore/attribute_methods.rb +1 -109
  17. data/lib/superstore/attribute_methods/primary_key.rb +20 -11
  18. data/lib/superstore/attributes.rb +13 -0
  19. data/lib/superstore/base.rb +8 -33
  20. data/lib/superstore/core.rb +7 -65
  21. data/lib/superstore/model_schema.rb +35 -0
  22. data/lib/superstore/persistence.rb +31 -115
  23. data/lib/superstore/railtie.rb +3 -11
  24. data/lib/superstore/relation/scrolling.rb +48 -0
  25. data/lib/superstore/timestamp.rb +13 -0
  26. data/lib/superstore/types.rb +11 -9
  27. data/lib/superstore/types/array_type.rb +3 -7
  28. data/lib/superstore/types/boolean_type.rb +7 -12
  29. data/lib/superstore/types/date_range_type.rb +7 -0
  30. data/lib/superstore/types/date_type.rb +7 -10
  31. data/lib/superstore/types/float_type.rb +3 -11
  32. data/lib/superstore/types/geo_point_type.rb +30 -0
  33. data/lib/superstore/types/integer_range_type.rb +19 -0
  34. data/lib/superstore/types/integer_type.rb +8 -14
  35. data/lib/superstore/types/json_type.rb +1 -1
  36. data/lib/superstore/types/range_type.rb +51 -0
  37. data/lib/superstore/types/string_type.rb +4 -4
  38. data/lib/superstore/types/time_type.rb +10 -8
  39. data/superstore.gemspec +4 -3
  40. data/test/support/jsonb.rb +3 -1
  41. data/test/support/models.rb +8 -5
  42. data/test/test_helper.rb +6 -2
  43. data/test/unit/adapters/adapter_test.rb +1 -3
  44. data/test/unit/associations/belongs_to_test.rb +1 -1
  45. data/test/unit/associations/has_many_test.rb +10 -2
  46. data/test/unit/attribute_methods/dirty_test.rb +8 -19
  47. data/test/unit/attribute_methods/primary_key_test.rb +1 -1
  48. data/test/unit/attribute_methods_test.rb +10 -22
  49. data/test/unit/{attribute_methods/typecasting_test.rb → attributes_test.rb} +13 -39
  50. data/test/unit/base_test.rb +4 -0
  51. data/test/unit/caching_test.rb +1 -1
  52. data/test/unit/callbacks_test.rb +4 -4
  53. data/test/unit/core_test.rb +9 -19
  54. data/test/unit/persistence_test.rb +17 -54
  55. data/test/unit/{scope/batches_test.rb → relation/scrolling_test.rb} +9 -5
  56. data/test/unit/serialization_test.rb +10 -2
  57. data/test/unit/{timestamps_test.rb → timestamp_test.rb} +5 -5
  58. data/test/unit/types/array_type_test.rb +3 -18
  59. data/test/unit/types/boolean_type_test.rb +7 -21
  60. data/test/unit/types/date_range_type_test.rb +28 -0
  61. data/test/unit/types/date_type_test.rb +15 -6
  62. data/test/unit/types/float_type_test.rb +4 -19
  63. data/test/unit/types/geo_point_type_test.rb +24 -0
  64. data/test/unit/types/integer_range_type_test.rb +28 -0
  65. data/test/unit/types/integer_type_test.rb +7 -16
  66. data/test/unit/types/string_type_test.rb +9 -13
  67. data/test/unit/types/time_type_test.rb +17 -11
  68. data/test/unit/validations_test.rb +2 -2
  69. metadata +39 -39
  70. data/lib/superstore/attribute_methods/definition.rb +0 -17
  71. data/lib/superstore/attribute_methods/dirty.rb +0 -52
  72. data/lib/superstore/attribute_methods/typecasting.rb +0 -53
  73. data/lib/superstore/caching.rb +0 -13
  74. data/lib/superstore/callbacks.rb +0 -29
  75. data/lib/superstore/connection.rb +0 -24
  76. data/lib/superstore/errors.rb +0 -10
  77. data/lib/superstore/inspect.rb +0 -25
  78. data/lib/superstore/model.rb +0 -38
  79. data/lib/superstore/schema.rb +0 -20
  80. data/lib/superstore/scope.rb +0 -73
  81. data/lib/superstore/scope/batches.rb +0 -27
  82. data/lib/superstore/scope/finder_methods.rb +0 -51
  83. data/lib/superstore/scope/query_methods.rb +0 -52
  84. data/lib/superstore/scoping.rb +0 -30
  85. data/lib/superstore/timestamps.rb +0 -19
  86. data/lib/superstore/type.rb +0 -16
  87. data/lib/superstore/types/base_type.rb +0 -23
  88. data/lib/superstore/validations.rb +0 -44
  89. data/test/unit/attribute_methods/definition_test.rb +0 -16
  90. data/test/unit/inspect_test.rb +0 -26
  91. data/test/unit/schema_test.rb +0 -15
  92. data/test/unit/scope/finder_methods_test.rb +0 -62
  93. data/test/unit/scope/query_methods_test.rb +0 -37
  94. data/test/unit/scoping_test.rb +0 -7
  95. data/test/unit/types/base_type_test.rb +0 -11
@@ -1,13 +0,0 @@
1
- module Superstore
2
- module Caching
3
- extend ActiveSupport::Concern
4
-
5
- def cache_key
6
- if new_record?
7
- "#{self.class.model_name.cache_key}/new"
8
- else
9
- "#{self.class.model_name.cache_key}/#{id}-#{updated_at.utc.to_s(:nsec)}"
10
- end
11
- end
12
- end
13
- end
@@ -1,29 +0,0 @@
1
- module Superstore
2
- module Callbacks
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- extend ActiveModel::Callbacks
7
- include ActiveModel::Validations::Callbacks
8
-
9
- define_model_callbacks :save, :create, :update, :destroy
10
- end
11
-
12
- def destroy #:nodoc:
13
- run_callbacks(:destroy) { super }
14
- end
15
-
16
- private
17
- def write(*args) #:nodoc:
18
- run_callbacks(:save) { super }
19
- end
20
-
21
- def create_self #:nodoc:
22
- run_callbacks(:create) { super }
23
- end
24
-
25
- def update_self(*) #:nodoc:
26
- run_callbacks(:update) { super }
27
- end
28
- end
29
- end
@@ -1,24 +0,0 @@
1
- module Superstore
2
- module Connection
3
- extend ActiveSupport::Concern
4
-
5
- module ClassMethods
6
- def adapter
7
- @adapter ||= adapter_class.new(config)
8
- end
9
-
10
- def adapter_class
11
- case config[:adapter]
12
- when nil, 'jsonb'
13
- Superstore::Adapters::JsonbAdapter
14
- else
15
- raise "Unknown adapter #{config[:adapter]}"
16
- end
17
- end
18
-
19
- def connection
20
- adapter.connection
21
- end
22
- end
23
- end
24
- end
@@ -1,10 +0,0 @@
1
- module Superstore
2
- class CasssandraObjectError < StandardError
3
- end
4
-
5
- class RecordNotSaved < CasssandraObjectError
6
- end
7
-
8
- class RecordNotFound < CasssandraObjectError
9
- end
10
- end
@@ -1,25 +0,0 @@
1
- module Superstore
2
- module Inspect
3
- def inspect
4
- inspection = ["#{self.class.primary_key}: #{id.inspect}"]
5
-
6
- @attributes.each do |attribute, value|
7
- if value.present?
8
- inspection << "#{attribute}: #{attribute_for_inspect(value)}"
9
- end
10
- end
11
-
12
- "#<#{self.class} #{inspection * ', '}>"
13
- end
14
-
15
- def attribute_for_inspect(value)
16
- if value.is_a?(String) && value.length > 50
17
- "#{value[0..50]}...".inspect
18
- elsif value.is_a?(Date) || value.is_a?(Time)
19
- %("#{value.to_s(:db)}")
20
- else
21
- value.inspect
22
- end
23
- end
24
- end
25
- end
@@ -1,38 +0,0 @@
1
- module Superstore
2
- module Model
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- class_attribute :symbolized_config
7
- self.symbolized_config = {}
8
- end
9
-
10
- module ClassMethods
11
- def base_class
12
- class_of_active_record_descendant(self)
13
- end
14
-
15
- def config=(config)
16
- self.symbolized_config = config.deep_symbolize_keys
17
- end
18
-
19
- def config
20
- symbolized_config
21
- end
22
-
23
- private
24
-
25
- # Returns the class descending directly from ActiveRecord::Base or an
26
- # abstract class, if any, in the inheritance hierarchy.
27
- def class_of_active_record_descendant(klass)
28
- if klass == Base || klass.superclass == Base
29
- klass
30
- elsif klass.superclass.nil?
31
- raise "#{name} doesn't belong in a hierarchy descending from Superstore"
32
- else
33
- class_of_active_record_descendant(klass.superclass)
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,20 +0,0 @@
1
- module Superstore
2
- class Schema
3
- class << self
4
- def create_table(table_name, options = {})
5
- adapter.create_table table_name, options
6
- end
7
-
8
- def drop_table(table_name)
9
- adapter.drop_table table_name
10
- end
11
-
12
- private
13
-
14
- def adapter
15
- Superstore::Base.adapter
16
- end
17
-
18
- end
19
- end
20
- end
@@ -1,73 +0,0 @@
1
- require 'superstore/scope/batches'
2
- require 'superstore/scope/finder_methods'
3
- require 'superstore/scope/query_methods'
4
-
5
- module Superstore
6
- class Scope
7
- include Batches, FinderMethods, QueryMethods
8
-
9
- attr_accessor :klass
10
- attr_accessor :limit_value, :select_values, :where_values, :id_values, :order_values
11
-
12
- def initialize(klass)
13
- @klass = klass
14
-
15
- @limit_value = nil
16
- @select_values = []
17
- @where_values = []
18
- @order_values = []
19
- @id_values = []
20
-
21
- reset
22
- end
23
-
24
- def initialize_copy(other)
25
- @limit_value = @limit_value.dup if @limit_value
26
- @select_values = @select_values.dup
27
- @where_values = @where_values.dup
28
- @order_values = @order_values.dup
29
- @id_values = @id_values.dup
30
- reset
31
- end
32
-
33
- def reset
34
- @records = nil
35
- @loaded = false
36
- end
37
-
38
- private
39
-
40
- def scoping
41
- previous, klass.current_scope = klass.current_scope, self
42
- yield
43
- ensure
44
- klass.current_scope = previous
45
- end
46
-
47
- def method_missing(method_name, *args, &block)
48
- if klass.respond_to?(method_name)
49
- scoping { klass.send(method_name, *args, &block) }
50
- elsif Array.method_defined?(method_name)
51
- to_a.send(method_name, *args, &block)
52
- else
53
- super
54
- end
55
- end
56
-
57
- def to_a
58
- unless @loaded
59
- @records = select_records
60
- @loaded = true
61
- end
62
- @records
63
- end
64
-
65
- def select_records
66
- results = []
67
- klass.adapter.select(self) do |key, attributes|
68
- results << klass.instantiate(key, attributes)
69
- end
70
- results
71
- end
72
- end
73
- end
@@ -1,27 +0,0 @@
1
- module Superstore
2
- module Batches
3
- def find_each(options = {})
4
- batch_size = options[:batch_size] || 1000
5
-
6
- klass.adapter.scroll(self, batch_size) do |key, attributes|
7
- yield klass.instantiate(key, attributes)
8
- end
9
- end
10
-
11
- def find_in_batches(options = {})
12
- batch_size = options[:batch_size] || 1000
13
- batch = []
14
-
15
- find_each(options) do |record|
16
- batch << record
17
-
18
- if batch.size == batch_size
19
- yield batch
20
- batch = []
21
- end
22
- end
23
-
24
- yield(batch) if batch.any?
25
- end
26
- end
27
- end
@@ -1,51 +0,0 @@
1
- module Superstore
2
- module FinderMethods
3
- def find(ids)
4
- if ids.is_a?(Array)
5
- find_some(ids)
6
- else
7
- find_one(ids)
8
- end
9
- end
10
-
11
- def find_by_id(ids)
12
- find(ids)
13
- rescue Superstore::RecordNotFound
14
- nil
15
- end
16
-
17
- def all
18
- clone
19
- end
20
-
21
- def first
22
- limit(1).to_a.first
23
- end
24
-
25
- def to_ids
26
- klass.adapter.to_ids self
27
- end
28
-
29
- private
30
-
31
- def find_one(id)
32
- if id.blank?
33
- raise Superstore::RecordNotFound, "Couldn't find #{self.name} with key #{id.inspect}"
34
- elsif record = where_ids(id).first
35
- record
36
- else
37
- raise Superstore::RecordNotFound
38
- end
39
- end
40
-
41
- def find_some(ids)
42
- ids = ids.flatten
43
- ids.compact!
44
- return [] if ids.empty?
45
-
46
- ids = ids.map(&:to_s).uniq
47
-
48
- where_ids(ids).to_a
49
- end
50
- end
51
- end
@@ -1,52 +0,0 @@
1
- module Superstore
2
- module QueryMethods
3
- def select!(*values)
4
- self.select_values += values.flatten
5
- self
6
- end
7
-
8
- def select(*values, &block)
9
- if block_given?
10
- to_a.select(&block)
11
- else
12
- clone.select!(*values)
13
- end
14
- end
15
-
16
- def where!(*values)
17
- self.where_values += values.flatten
18
- self
19
- end
20
-
21
- def where(*values)
22
- clone.where! values
23
- end
24
-
25
- def where_ids!(*ids)
26
- self.id_values += ids.flatten
27
- self
28
- end
29
-
30
- def where_ids(*ids)
31
- clone.where_ids! ids
32
- end
33
-
34
- def limit!(value)
35
- self.limit_value = value
36
- self
37
- end
38
-
39
- def limit(value)
40
- clone.limit! value
41
- end
42
-
43
- def order!(*values)
44
- self.order_values = values.flatten
45
- self
46
- end
47
-
48
- def order(*values)
49
- clone.order! values
50
- end
51
- end
52
- end
@@ -1,30 +0,0 @@
1
- module Superstore
2
- module Scoping
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- singleton_class.class_eval do
7
- delegate :find, :find_by_id, :first, :all, :to_ids, to: :scope
8
- delegate :find_each, :find_in_batches, to: :scope
9
- delegate :select, :where, :where_ids, to: :scope
10
- end
11
-
12
- class_attribute :default_scopes, instance_writer: false, instance_predicate: false
13
- self.default_scopes = []
14
- end
15
-
16
- module ClassMethods
17
- def scope
18
- self.current_scope ||= Scope.new(self)
19
- end
20
-
21
- def current_scope
22
- Thread.current["#{self}_current_scope"]
23
- end
24
-
25
- def current_scope=(new_scope)
26
- Thread.current["#{self}_current_scope"] = new_scope
27
- end
28
- end
29
- end
30
- end
@@ -1,19 +0,0 @@
1
- module Superstore
2
- module Timestamps
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- attribute :created_at, type: :time
7
- attribute :updated_at, type: :time
8
-
9
- before_create do
10
- self.created_at ||= Time.current
11
- self.updated_at ||= Time.current
12
- end
13
-
14
- before_update if: :changed? do
15
- self.updated_at = Time.current unless self.changed_attributes.key?("updated_at")
16
- end
17
- end
18
- end
19
- end
@@ -1,16 +0,0 @@
1
- module Superstore
2
- class Type
3
- cattr_accessor :attribute_types
4
- self.attribute_types = {}.with_indifferent_access
5
-
6
- class << self
7
- def register(name, type)
8
- attribute_types[name] = type
9
- end
10
-
11
- def get_type_class(name)
12
- attribute_types[name]
13
- end
14
- end
15
- end
16
- end