superstore 1.2.0 → 2.0.0
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 +4 -4
- data/.travis.yml +6 -13
- data/CHANGELOG.md +16 -0
- data/Gemfile +0 -5
- data/README.md +15 -33
- data/lib/superstore/adapters/jsonb_adapter.rb +245 -0
- data/lib/superstore/associations/association.rb +38 -0
- data/lib/superstore/associations/belongs_to.rb +35 -0
- data/lib/superstore/associations/builder/association.rb +38 -0
- data/lib/superstore/associations/builder/belongs_to.rb +7 -0
- data/lib/superstore/associations/builder/has_many.rb +7 -0
- data/lib/superstore/associations/builder/has_one.rb +7 -0
- data/lib/superstore/associations/has_many.rb +26 -0
- data/lib/superstore/associations/has_one.rb +24 -0
- data/lib/superstore/associations/reflection.rb +65 -0
- data/lib/superstore/associations.rb +72 -0
- data/lib/superstore/attribute_methods/definition.rb +5 -10
- data/lib/superstore/attribute_methods/dirty.rb +12 -2
- data/lib/superstore/attribute_methods/typecasting.rb +6 -12
- data/lib/superstore/base.rb +3 -4
- data/lib/superstore/connection.rb +3 -5
- data/lib/superstore/core.rb +0 -5
- data/lib/superstore/model.rb +32 -33
- data/lib/superstore/persistence.rb +4 -10
- data/lib/superstore/railtie.rb +2 -20
- data/lib/superstore/scope/batches.rb +17 -22
- data/lib/superstore/scope/finder_methods.rb +33 -35
- data/lib/superstore/scope/query_methods.rb +38 -44
- data/lib/superstore/scope.rb +24 -0
- data/lib/superstore/type.rb +3 -3
- data/lib/superstore/types/array_type.rb +2 -9
- data/lib/superstore/types/base_type.rb +4 -7
- data/lib/superstore/types/boolean_type.rb +2 -1
- data/lib/superstore/types/float_type.rb +6 -5
- data/lib/superstore/types/integer_type.rb +3 -3
- data/lib/superstore/types/json_type.rb +0 -21
- data/lib/superstore.rb +16 -5
- data/superstore.gemspec +2 -1
- data/test/support/jsonb.rb +8 -0
- data/test/support/{issue.rb → models.rb} +9 -0
- data/test/support/pg.rb +11 -15
- data/test/test_helper.rb +7 -6
- data/test/unit/{belongs_to_test.rb → associations/belongs_to_test.rb} +1 -10
- data/test/unit/associations/has_many_test.rb +13 -0
- data/test/unit/associations/has_one_test.rb +14 -0
- data/test/unit/{belongs_to → associations}/reflection_test.rb +2 -2
- data/test/unit/attribute_methods/definition_test.rb +6 -3
- data/test/unit/attribute_methods/dirty_test.rb +17 -14
- data/test/unit/attribute_methods/typecasting_test.rb +0 -14
- data/test/unit/base_test.rb +3 -3
- data/test/unit/connection_test.rb +0 -4
- data/test/unit/persistence_test.rb +4 -4
- data/test/unit/schema_test.rb +9 -17
- data/test/unit/scope/query_methods_test.rb +10 -1
- data/test/unit/types/array_type_test.rb +12 -10
- data/test/unit/types/base_type_test.rb +2 -10
- data/test/unit/types/boolean_type_test.rb +15 -13
- data/test/unit/types/date_type_test.rb +3 -3
- data/test/unit/types/float_type_test.rb +14 -7
- data/test/unit/types/integer_type_test.rb +11 -9
- data/test/unit/types/json_type_test.rb +0 -23
- data/test/unit/types/string_type_test.rb +6 -6
- data/test/unit/types/time_type_test.rb +7 -7
- metadata +35 -26
- data/CHANGELOG +0 -0
- data/lib/superstore/adapters/cassandra_adapter.rb +0 -203
- data/lib/superstore/adapters/hstore_adapter.rb +0 -170
- data/lib/superstore/belongs_to/association.rb +0 -65
- data/lib/superstore/belongs_to/builder.rb +0 -40
- data/lib/superstore/belongs_to/reflection.rb +0 -38
- data/lib/superstore/belongs_to.rb +0 -63
- data/lib/superstore/cassandra_schema/statements.rb +0 -52
- data/lib/superstore/cassandra_schema/tasks.rb +0 -47
- data/lib/superstore/cassandra_schema.rb +0 -9
- data/lib/superstore/log_subscriber.rb +0 -44
- data/lib/superstore/railties/controller_runtime.rb +0 -45
- data/lib/superstore/tasks/ks.rake +0 -59
- data/test/support/cassandra.rb +0 -46
- data/test/support/hstore.rb +0 -24
- data/test/support/user.rb +0 -2
- data/test/unit/cassandra_schema/statements_test.rb +0 -47
- data/test/unit/cassandra_schema/tasks_test.rb +0 -31
- data/test/unit/log_subscriber_test.rb +0 -26
- data/test/unit/railties/controller_runtime_test.rb +0 -48
@@ -0,0 +1,72 @@
|
|
1
|
+
module Superstore
|
2
|
+
module Associations
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
class_attribute :association_reflections
|
7
|
+
self.association_reflections = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
# === Options
|
12
|
+
# [:class_name]
|
13
|
+
# Use if the class cannot be inferred from the association
|
14
|
+
# [:polymorphic]
|
15
|
+
# Specify if the association is polymorphic
|
16
|
+
# Example:
|
17
|
+
# class Driver < Superstore::Base
|
18
|
+
# end
|
19
|
+
# class Truck < Superstore::Base
|
20
|
+
# end
|
21
|
+
def belongs_to(name, options = {})
|
22
|
+
Superstore::Associations::Builder::BelongsTo.build(self, name, options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_many(name, options = {})
|
26
|
+
Superstore::Associations::Builder::HasMany.build(self, name, options)
|
27
|
+
end
|
28
|
+
|
29
|
+
def has_one(name, options = {})
|
30
|
+
Superstore::Associations::Builder::HasOne.build(self, name, options)
|
31
|
+
end
|
32
|
+
|
33
|
+
def generated_association_methods
|
34
|
+
@generated_association_methods ||= begin
|
35
|
+
mod = const_set(:GeneratedAssociationMethods, Module.new)
|
36
|
+
include mod
|
37
|
+
mod
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns the belongs_to instance for the given name, instantiating it if it doesn't already exist
|
43
|
+
def association(name)
|
44
|
+
instance = association_instance_get(name)
|
45
|
+
|
46
|
+
if instance.nil?
|
47
|
+
reflection = association_reflections[name]
|
48
|
+
instance = reflection.association_class.new(self, reflection)
|
49
|
+
association_instance_set(name, instance)
|
50
|
+
end
|
51
|
+
|
52
|
+
instance
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
def clear_associations_cache
|
57
|
+
associations_cache.clear if persisted?
|
58
|
+
end
|
59
|
+
|
60
|
+
def associations_cache
|
61
|
+
@associations_cache ||= {}
|
62
|
+
end
|
63
|
+
|
64
|
+
def association_instance_get(name)
|
65
|
+
associations_cache[name.to_sym]
|
66
|
+
end
|
67
|
+
|
68
|
+
def association_instance_set(name, association)
|
69
|
+
associations_cache[name.to_sym] = association
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -1,21 +1,16 @@
|
|
1
1
|
module Superstore
|
2
2
|
module AttributeMethods
|
3
3
|
class Definition
|
4
|
-
attr_reader :name, :
|
5
|
-
def initialize(name,
|
6
|
-
@name
|
7
|
-
@
|
8
|
-
end
|
9
|
-
|
10
|
-
def default
|
11
|
-
coder.default
|
4
|
+
attr_reader :name, :type
|
5
|
+
def initialize(model, name, type_class, options)
|
6
|
+
@name = name.to_s
|
7
|
+
@type = type_class.new(model, options)
|
12
8
|
end
|
13
9
|
|
14
10
|
def instantiate(value)
|
15
|
-
value = value.nil? ? coder.default : value
|
16
11
|
return if value.nil?
|
17
12
|
|
18
|
-
value.kind_of?(String) ?
|
13
|
+
value.kind_of?(String) ? type.decode(value) : type.typecast(value)
|
19
14
|
end
|
20
15
|
end
|
21
16
|
end
|
@@ -27,13 +27,23 @@ module Superstore
|
|
27
27
|
result
|
28
28
|
end
|
29
29
|
|
30
|
+
def old_attribute_value(attr)
|
31
|
+
if attribute_changed?(attr)
|
32
|
+
changed_attributes[attr]
|
33
|
+
else
|
34
|
+
read_attribute attr
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
30
38
|
def write_attribute(name, value)
|
31
39
|
name = name.to_s
|
32
|
-
old =
|
40
|
+
old = old_attribute_value(name)
|
33
41
|
|
34
42
|
super
|
35
43
|
|
36
|
-
|
44
|
+
if old == read_attribute(name)
|
45
|
+
changed_attributes.delete(name)
|
46
|
+
else
|
37
47
|
changed_attributes[name] = old
|
38
48
|
end
|
39
49
|
end
|
@@ -27,19 +27,13 @@ module Superstore
|
|
27
27
|
|
28
28
|
#
|
29
29
|
# attribute :name, type: :string
|
30
|
-
# attribute :ammo, type:
|
30
|
+
# attribute :ammo, type: :integer
|
31
31
|
#
|
32
32
|
def attribute(name, options)
|
33
|
-
|
34
|
-
|
33
|
+
type_name = options[:type]
|
34
|
+
type_class = Superstore::Type.get_type_class(type_name) || (raise "Unknown type #{type_name}")
|
35
35
|
|
36
|
-
|
37
|
-
coder = Superstore::Type.get_coder(type) || (raise "Unknown type #{type}")
|
38
|
-
elsif coder.nil?
|
39
|
-
raise "Must supply a :coder for #{name}"
|
40
|
-
end
|
41
|
-
|
42
|
-
attribute_definitions[name.to_s] = AttributeMethods::Definition.new(name, coder, options)
|
36
|
+
attribute_definitions[name.to_s] = AttributeMethods::Definition.new(self, name, type_class, options)
|
43
37
|
end
|
44
38
|
|
45
39
|
def typecast_attribute(name, value)
|
@@ -50,8 +44,8 @@ module Superstore
|
|
50
44
|
end
|
51
45
|
end
|
52
46
|
|
53
|
-
def
|
54
|
-
attribute_definitions[attribute.to_s].
|
47
|
+
def type_for(attribute)
|
48
|
+
attribute_definitions[attribute.to_s].type
|
55
49
|
end
|
56
50
|
end
|
57
51
|
end
|
data/lib/superstore/base.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'set'
|
2
2
|
|
3
|
-
require 'superstore/log_subscriber'
|
4
3
|
require 'superstore/types'
|
5
4
|
|
6
5
|
module Superstore
|
@@ -12,6 +11,8 @@ module Superstore
|
|
12
11
|
include ActiveModel::Serializers::JSON
|
13
12
|
include GlobalID::Identification
|
14
13
|
|
14
|
+
include Model
|
15
|
+
include Core
|
15
16
|
include Connection
|
16
17
|
include Identity
|
17
18
|
include Inspect
|
@@ -21,13 +22,11 @@ module Superstore
|
|
21
22
|
include AttributeMethods::Dirty
|
22
23
|
include AttributeMethods::PrimaryKey
|
23
24
|
include AttributeMethods::Typecasting
|
24
|
-
include
|
25
|
+
include Associations
|
25
26
|
include Callbacks
|
26
27
|
include Timestamps
|
27
28
|
include Scoping
|
28
|
-
include Core
|
29
29
|
include Caching
|
30
|
-
extend Model
|
31
30
|
|
32
31
|
end
|
33
32
|
end
|
@@ -4,15 +4,13 @@ module Superstore
|
|
4
4
|
|
5
5
|
module ClassMethods
|
6
6
|
def adapter
|
7
|
-
|
7
|
+
@adapter ||= adapter_class.new(config)
|
8
8
|
end
|
9
9
|
|
10
10
|
def adapter_class
|
11
11
|
case config[:adapter]
|
12
|
-
when '
|
13
|
-
Superstore::Adapters::
|
14
|
-
when nil, 'cassandra'
|
15
|
-
Superstore::Adapters::CassandraAdapter
|
12
|
+
when nil, 'jsonb'
|
13
|
+
Superstore::Adapters::JsonbAdapter
|
16
14
|
else
|
17
15
|
raise "Unknown adapter #{config[:adapter]}"
|
18
16
|
end
|
data/lib/superstore/core.rb
CHANGED
@@ -7,11 +7,6 @@ module Superstore
|
|
7
7
|
@destroyed = false
|
8
8
|
@attributes = {}
|
9
9
|
self.attributes = attributes || {}
|
10
|
-
attribute_definitions.each_value do |definition|
|
11
|
-
unless definition.default.nil? || attribute_exists?(definition.name)
|
12
|
-
@attributes[definition.name] = definition.default
|
13
|
-
end
|
14
|
-
end
|
15
10
|
|
16
11
|
yield self if block_given?
|
17
12
|
end
|
data/lib/superstore/model.rb
CHANGED
@@ -1,46 +1,45 @@
|
|
1
1
|
module Superstore
|
2
2
|
module Model
|
3
|
-
|
4
|
-
@table_name = table_name
|
5
|
-
end
|
3
|
+
extend ActiveSupport::Concern
|
6
4
|
|
7
|
-
|
8
|
-
|
5
|
+
included do
|
6
|
+
class_attribute :symbolized_config
|
7
|
+
self.symbolized_config = {}
|
9
8
|
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
module ClassMethods
|
11
|
+
def table_name=(table_name)
|
12
|
+
@table_name = table_name
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
15
|
+
def table_name
|
16
|
+
@table_name ||= base_class.model_name.plural
|
17
|
+
end
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
def base_class
|
20
|
+
class_of_active_record_descendant(self)
|
21
|
+
end
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
def config=(config)
|
24
|
+
self.symbolized_config = config.deep_symbolize_keys
|
25
|
+
end
|
28
26
|
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
def config
|
28
|
+
symbolized_config
|
29
|
+
end
|
32
30
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
31
|
+
private
|
32
|
+
|
33
|
+
# Returns the class descending directly from ActiveRecord::Base or an
|
34
|
+
# abstract class, if any, in the inheritance hierarchy.
|
35
|
+
def class_of_active_record_descendant(klass)
|
36
|
+
if klass == Base || klass.superclass == Base
|
37
|
+
klass
|
38
|
+
elsif klass.superclass.nil?
|
39
|
+
raise "#{name} doesn't belong in a hierarchy descending from Superstore"
|
40
|
+
else
|
41
|
+
class_of_active_record_descendant(klass.superclass)
|
42
|
+
end
|
44
43
|
end
|
45
44
|
end
|
46
45
|
end
|
@@ -7,7 +7,7 @@ module Superstore
|
|
7
7
|
end
|
8
8
|
|
9
9
|
module ClassMethods
|
10
|
-
def
|
10
|
+
def delete(ids)
|
11
11
|
adapter.delete table_name, ids
|
12
12
|
end
|
13
13
|
|
@@ -52,7 +52,7 @@ module Superstore
|
|
52
52
|
if value.nil?
|
53
53
|
encoded[column_name] = nil
|
54
54
|
else
|
55
|
-
encoded[column_name] = attribute_definitions[column_name].
|
55
|
+
encoded[column_name] = attribute_definitions[column_name].type.encode(value)
|
56
56
|
end
|
57
57
|
end
|
58
58
|
encoded
|
@@ -73,12 +73,6 @@ module Superstore
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
-
attribute_definitions.each_value do |definition|
|
77
|
-
unless definition.default.nil? || result.has_key?(definition.name)
|
78
|
-
result[definition.name] = definition.default
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
76
|
result
|
83
77
|
end
|
84
78
|
end
|
@@ -100,7 +94,7 @@ module Superstore
|
|
100
94
|
end
|
101
95
|
|
102
96
|
def destroy
|
103
|
-
self.class.
|
97
|
+
self.class.delete(id)
|
104
98
|
@destroyed = true
|
105
99
|
end
|
106
100
|
|
@@ -133,7 +127,7 @@ module Superstore
|
|
133
127
|
end
|
134
128
|
|
135
129
|
def reload
|
136
|
-
|
130
|
+
clear_associations_cache
|
137
131
|
@attributes = self.class.find(id).instance_variable_get('@attributes')
|
138
132
|
self
|
139
133
|
end
|
data/lib/superstore/railtie.rb
CHANGED
@@ -1,19 +1,9 @@
|
|
1
1
|
module Superstore
|
2
2
|
class Railtie < Rails::Railtie
|
3
|
-
rake_tasks do
|
4
|
-
load 'superstore/tasks/ks.rake'
|
5
|
-
end
|
6
|
-
|
7
3
|
initializer "superstore.config" do |app|
|
8
4
|
ActiveSupport.on_load :superstore do
|
9
|
-
|
10
|
-
if pathname
|
11
|
-
if pathname.basename.to_s == 'cassandra.yml'
|
12
|
-
warn "***********************"
|
13
|
-
warn "config/cassandra.yml is deprecated. Use config/superstore.yml"
|
14
|
-
warn "***********************"
|
15
|
-
end
|
16
|
-
|
5
|
+
pathname = Rails.root.join('config', 'superstore.yml')
|
6
|
+
if pathname.exist?
|
17
7
|
config = ERB.new(pathname.read).result
|
18
8
|
config = YAML.load(config)
|
19
9
|
|
@@ -25,13 +15,5 @@ module Superstore
|
|
25
15
|
end
|
26
16
|
end
|
27
17
|
end
|
28
|
-
|
29
|
-
# Expose database runtime to controller for logging.
|
30
|
-
initializer "superstore.log_runtime" do |app|
|
31
|
-
require "superstore/railties/controller_runtime"
|
32
|
-
ActiveSupport.on_load(:action_controller) do
|
33
|
-
include Superstore::Railties::ControllerRuntime
|
34
|
-
end
|
35
|
-
end
|
36
18
|
end
|
37
19
|
end
|
@@ -1,32 +1,27 @@
|
|
1
1
|
module Superstore
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
find_in_batches(options) do |records|
|
6
|
-
records.each { |record| yield record }
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
def find_in_batches(options = {})
|
11
|
-
batch_size = options.delete(:batch_size) || 1000
|
12
|
-
start_key = nil
|
2
|
+
module Batches
|
3
|
+
def find_each(options = {})
|
4
|
+
batch_size = options[:batch_size] || 1000
|
13
5
|
|
14
|
-
|
15
|
-
|
6
|
+
klass.adapter.scroll(self, batch_size) do |key, attributes|
|
7
|
+
yield klass.instantiate(key, attributes)
|
8
|
+
end
|
9
|
+
end
|
16
10
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
else
|
21
|
-
next_record = nil
|
22
|
-
end
|
11
|
+
def find_in_batches(options = {})
|
12
|
+
batch_size = options[:batch_size] || 1000
|
13
|
+
batch = []
|
23
14
|
|
24
|
-
|
25
|
-
|
15
|
+
find_each(options) do |record|
|
16
|
+
batch << record
|
26
17
|
|
27
|
-
|
18
|
+
if batch.size == batch_size
|
19
|
+
yield batch
|
20
|
+
batch = []
|
28
21
|
end
|
29
22
|
end
|
23
|
+
|
24
|
+
yield(batch) if batch.any?
|
30
25
|
end
|
31
26
|
end
|
32
27
|
end
|
@@ -1,48 +1,46 @@
|
|
1
1
|
module Superstore
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
find_one(ids)
|
9
|
-
end
|
2
|
+
module FinderMethods
|
3
|
+
def find(ids)
|
4
|
+
if ids.is_a?(Array)
|
5
|
+
find_some(ids)
|
6
|
+
else
|
7
|
+
find_one(ids)
|
10
8
|
end
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
def find_by_id(ids)
|
12
|
+
find(ids)
|
13
|
+
rescue Superstore::RecordNotFound
|
14
|
+
nil
|
15
|
+
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
def all
|
18
|
+
clone
|
19
|
+
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
def first
|
22
|
+
limit(1).to_a.first
|
23
|
+
end
|
25
24
|
|
26
|
-
|
25
|
+
private
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
27
|
+
def find_one(id)
|
28
|
+
if id.blank?
|
29
|
+
raise Superstore::RecordNotFound, "Couldn't find #{self.name} with key #{id.inspect}"
|
30
|
+
elsif record = where_ids(id).first
|
31
|
+
record
|
32
|
+
else
|
33
|
+
raise Superstore::RecordNotFound
|
36
34
|
end
|
35
|
+
end
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
def find_some(ids)
|
38
|
+
ids = ids.flatten
|
39
|
+
return [] if ids.empty?
|
41
40
|
|
42
|
-
|
41
|
+
ids = ids.compact.map(&:to_s).uniq
|
43
42
|
|
44
|
-
|
45
|
-
|
46
|
-
end
|
43
|
+
where_ids(ids).to_a
|
44
|
+
end
|
47
45
|
end
|
48
46
|
end
|
@@ -1,58 +1,52 @@
|
|
1
1
|
module Superstore
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
8
|
-
|
9
|
-
def select(*values, &block)
|
10
|
-
if block_given?
|
11
|
-
to_a.select(&block)
|
12
|
-
else
|
13
|
-
clone.select! *values
|
14
|
-
end
|
15
|
-
end
|
2
|
+
module QueryMethods
|
3
|
+
def select!(*values)
|
4
|
+
self.select_values += values.flatten
|
5
|
+
self
|
6
|
+
end
|
16
7
|
|
17
|
-
|
18
|
-
|
19
|
-
|
8
|
+
def select(*values, &block)
|
9
|
+
if block_given?
|
10
|
+
to_a.select(&block)
|
11
|
+
else
|
12
|
+
clone.select! *values
|
20
13
|
end
|
14
|
+
end
|
21
15
|
|
22
|
-
|
23
|
-
|
24
|
-
|
16
|
+
def where!(*values)
|
17
|
+
self.where_values += values.flatten
|
18
|
+
self
|
19
|
+
end
|
25
20
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
21
|
+
def where(*values)
|
22
|
+
clone.where! values
|
23
|
+
end
|
30
24
|
|
31
|
-
|
32
|
-
|
33
|
-
|
25
|
+
def where_ids!(*ids)
|
26
|
+
self.id_values += ids.flatten
|
27
|
+
self
|
28
|
+
end
|
34
29
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
30
|
+
def where_ids(*ids)
|
31
|
+
clone.where_ids! ids
|
32
|
+
end
|
39
33
|
|
40
|
-
|
41
|
-
|
42
|
-
|
34
|
+
def limit!(value)
|
35
|
+
self.limit_value = value
|
36
|
+
self
|
37
|
+
end
|
43
38
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
39
|
+
def limit(value)
|
40
|
+
clone.limit! value
|
41
|
+
end
|
48
42
|
|
49
|
-
|
50
|
-
|
51
|
-
|
43
|
+
def order!(*values)
|
44
|
+
self.order_values = values.flatten
|
45
|
+
self
|
46
|
+
end
|
52
47
|
|
53
|
-
|
54
|
-
|
55
|
-
end
|
48
|
+
def order(*values)
|
49
|
+
clone.order! values
|
56
50
|
end
|
57
51
|
end
|
58
52
|
end
|
data/lib/superstore/scope.rb
CHANGED
@@ -17,6 +17,22 @@ module Superstore
|
|
17
17
|
@where_values = []
|
18
18
|
@order_values = []
|
19
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
|
20
36
|
end
|
21
37
|
|
22
38
|
private
|
@@ -38,6 +54,14 @@ module Superstore
|
|
38
54
|
end
|
39
55
|
end
|
40
56
|
|
57
|
+
def to_a
|
58
|
+
unless @loaded
|
59
|
+
@records = select_records
|
60
|
+
@loaded = true
|
61
|
+
end
|
62
|
+
@records
|
63
|
+
end
|
64
|
+
|
41
65
|
def select_records
|
42
66
|
results = []
|
43
67
|
klass.adapter.select(self) do |key, attributes|
|
data/lib/superstore/type.rb
CHANGED
@@ -4,11 +4,11 @@ module Superstore
|
|
4
4
|
self.attribute_types = {}.with_indifferent_access
|
5
5
|
|
6
6
|
class << self
|
7
|
-
def register(name,
|
8
|
-
attribute_types[name] =
|
7
|
+
def register(name, type)
|
8
|
+
attribute_types[name] = type
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
11
|
+
def get_type_class(name)
|
12
12
|
attribute_types[name]
|
13
13
|
end
|
14
14
|
end
|