activerecord-typedstore 0.6.1 → 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,16 +5,18 @@ require 'database_cleaner'
5
5
 
6
6
  require 'simplecov'
7
7
  require 'coveralls'
8
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
8
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
9
9
  SimpleCov::Formatter::HTMLFormatter,
10
10
  Coveralls::SimpleCov::Formatter
11
- ]
11
+ ])
12
12
  SimpleCov.start
13
13
 
14
14
  require 'activerecord-typedstore'
15
15
 
16
16
  Dir[File.expand_path(File.join(File.dirname(__FILE__), 'support', '**', '*.rb'))].each { |f| require f }
17
17
 
18
+ Time.zone = 'UTC'
19
+
18
20
  RSpec.configure do |config|
19
21
  config.order = 'random'
20
22
  end
@@ -40,7 +40,13 @@ def define_columns(t)
40
40
  t.decimal :shipping_cost, precision: 16, scale: 2
41
41
 
42
42
  t.integer :grades, array: true
43
- t.string :tags, array: true, null: false, default: []
43
+
44
+ if t.respond_to?(:name) && t.name =~ /sqlite|mysql/
45
+ # native sqlite cannot automatically cast array to yaml
46
+ t.string :tags, array: true, null: false, default: [].to_yaml
47
+ else
48
+ t.string :tags, array: true, null: false, default: []
49
+ end
44
50
 
45
51
  t.string :nickname, blank: false, default: 'Please enter your nickname'
46
52
  end
@@ -49,6 +55,7 @@ def define_store_columns(t)
49
55
  define_columns(t)
50
56
  t.any :author
51
57
  t.any :source, blank: false, default: 'web'
58
+ t.any :signup, default: {}
52
59
  t.string :country, blank: false, default: 'Canada', accessor: false
53
60
  end
54
61
 
@@ -88,7 +95,9 @@ class CreateAllTables < ActiveRecord::Migration
88
95
  end
89
96
  end
90
97
  ActiveRecord::Migration.verbose = true
91
- CreateAllTables.up
98
+ ActiveRecord::Migration.suppress_messages do
99
+ CreateAllTables.up
100
+ end
92
101
 
93
102
  class ColumnCoder
94
103
 
@@ -144,13 +153,29 @@ if ENV['POSTGRES']
144
153
  end
145
154
 
146
155
  if ENV['POSTGRES_JSON']
147
- class PostgresJsonTypedStoreModel < ActiveRecord::Base
148
- establish_connection ENV['POSTGRES_URL'] || :test_postgresql
149
- store :untyped_settings, accessors: [:title]
150
- typed_store :settings, coder: ColumnCoder.new(AsJson) do |s|
151
- define_store_columns(s)
156
+
157
+ if AR_VERSION >= AR_4_2
158
+
159
+ class PostgresJsonTypedStoreModel < ActiveRecord::Base
160
+ establish_connection ENV['POSTGRES_URL'] || :test_postgresql
161
+ store :untyped_settings, accessors: [:title]
162
+ typed_store :settings, coder: false do |s|
163
+ define_store_columns(s)
164
+ end
152
165
  end
166
+
167
+ else
168
+
169
+ class PostgresJsonTypedStoreModel < ActiveRecord::Base
170
+ establish_connection ENV['POSTGRES_URL'] || :test_postgresql
171
+ store :untyped_settings, accessors: [:title]
172
+ typed_store :settings, coder: ColumnCoder.new(AsJson) do |s|
173
+ define_store_columns(s)
174
+ end
175
+ end
176
+
153
177
  end
178
+
154
179
  end
155
180
 
156
181
  end
@@ -199,7 +224,6 @@ class MarshalTypedStoreModel < ActiveRecord::Base
199
224
  end
200
225
  end
201
226
 
202
-
203
227
  Models = [
204
228
  Sqlite3RegularARModel,
205
229
  YamlTypedStoreModel,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-typedstore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 1.0.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-02 00:00:00.000000000 Z
11
+ date: 2016-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,20 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3.2'
19
+ version: '4.2'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '5'
22
+ version: '5.1'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '3.2'
29
+ version: '4.2'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '5'
32
+ version: '5.1'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: bundler
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -92,56 +92,56 @@ dependencies:
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: '0'
95
+ version: '1'
96
96
  type: :development
97
97
  prerelease: false
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - "~>"
101
101
  - !ruby/object:Gem::Version
102
- version: '0'
102
+ version: '1'
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: pg
105
105
  requirement: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - "~>"
108
108
  - !ruby/object:Gem::Version
109
- version: '0'
109
+ version: '0.18'
110
110
  type: :development
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: '0'
116
+ version: '0.18'
117
117
  - !ruby/object:Gem::Dependency
118
118
  name: mysql2
119
119
  requirement: !ruby/object:Gem::Requirement
120
120
  requirements:
121
- - - "~>"
121
+ - - ">"
122
122
  - !ruby/object:Gem::Version
123
- version: '0'
123
+ version: '0.3'
124
124
  type: :development
125
125
  prerelease: false
126
126
  version_requirements: !ruby/object:Gem::Requirement
127
127
  requirements:
128
- - - "~>"
128
+ - - ">"
129
129
  - !ruby/object:Gem::Version
130
- version: '0'
130
+ version: '0.3'
131
131
  - !ruby/object:Gem::Dependency
132
132
  name: database_cleaner
133
133
  requirement: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: '0'
137
+ version: '1'
138
138
  type: :development
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - "~>"
143
143
  - !ruby/object:Gem::Version
144
- version: '0'
144
+ version: '1'
145
145
  description: ActiveRecord::Store but with type definition
146
146
  email:
147
147
  - jean.boussier@gmail.com
@@ -163,11 +163,10 @@ files:
163
163
  - gemfiles/Gemfile.ar-4.2
164
164
  - gemfiles/Gemfile.ar-edge
165
165
  - lib/active_record/typed_store.rb
166
- - lib/active_record/typed_store/ar_32_fallbacks.rb
167
- - lib/active_record/typed_store/coder.rb
168
- - lib/active_record/typed_store/column.rb
169
166
  - lib/active_record/typed_store/dsl.rb
170
167
  - lib/active_record/typed_store/extension.rb
168
+ - lib/active_record/typed_store/field.rb
169
+ - lib/active_record/typed_store/type.rb
171
170
  - lib/active_record/typed_store/typed_hash.rb
172
171
  - lib/active_record/typed_store/version.rb
173
172
  - lib/activerecord-typedstore.rb
@@ -191,9 +190,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
191
190
  version: '0'
192
191
  required_rubygems_version: !ruby/object:Gem::Requirement
193
192
  requirements:
194
- - - ">="
193
+ - - ">"
195
194
  - !ruby/object:Gem::Version
196
- version: '0'
195
+ version: 1.3.1
197
196
  requirements: []
198
197
  rubyforge_project:
199
198
  rubygems_version: 2.4.6
@@ -1,95 +0,0 @@
1
- class ActiveRecord::Store::IndifferentCoder
2
- # Backport from rails 4.0
3
- def initialize(coder_or_class_name)
4
- @coder =
5
- if coder_or_class_name.respond_to?(:load) && coder_or_class_name.respond_to?(:dump)
6
- coder_or_class_name
7
- else
8
- ActiveRecord::Coders::YAMLColumn.new(coder_or_class_name || Object)
9
- end
10
- end
11
-
12
- def dump(obj)
13
- @coder.dump self.class.as_indifferent_hash(obj)
14
- end
15
-
16
- def load(yaml)
17
- self.class.as_indifferent_hash @coder.load(yaml)
18
- end
19
-
20
- end
21
-
22
- module ActiveRecord::TypedStore
23
-
24
- module AR32Fallbacks
25
- extend ActiveSupport::Concern
26
-
27
- included do
28
- cattr_accessor :virtual_attribute_methods
29
- self.virtual_attribute_methods = []
30
- end
31
-
32
- module ClassMethods
33
-
34
- def typed_store(store_attribute, dsl)
35
- _ar_32_fallback_accessors(store_attribute, dsl.accessors)
36
- end
37
-
38
- protected
39
-
40
- def define_virtual_attribute_method(name)
41
- virtual_attribute_methods << name
42
- define_attribute_method(name)
43
- end
44
-
45
- # ActiveModel override heavilly inspired from the original code
46
- def define_attribute_method(attr_name)
47
- return super unless virtual_attribute_methods.include?(attr_name)
48
-
49
- attribute_method_matchers.each do |matcher|
50
- method_name = matcher.method_name(attr_name)
51
- unless instance_method_already_implemented?(method_name)
52
- define_optimized_call generated_attribute_methods, method_name, matcher.method_missing_target, attr_name.to_s
53
- end
54
- end
55
- attribute_method_matchers_cache.clear
56
- end
57
-
58
- def _ar_32_fallback_accessors(store_attribute, accessors)
59
- accessors.each do |accessor|
60
- _ar_32_fallback_accessor(store_attribute, accessor)
61
- end
62
- end
63
-
64
- def _ar_32_fallback_accessor(store_attribute, key)
65
- define_method("#{key}=") do |value|
66
- write_store_attribute(store_attribute, key, value)
67
- end
68
- define_method(key) do
69
- read_store_attribute(store_attribute, key)
70
- end
71
- end
72
-
73
- end
74
-
75
- private
76
-
77
- def initialize_store_attribute(store_attribute)
78
- send("#{store_attribute}=", {}) unless send(store_attribute).is_a?(Hash)
79
- send(store_attribute)
80
- end
81
-
82
- def read_store_attribute(store_attribute, key)
83
- store = initialize_store_attribute(store_attribute)
84
- store[key]
85
- end
86
-
87
- def write_store_attribute(store_attribute, key, value)
88
- attribute_will_change!(store_attribute.to_s)
89
- send(store_attribute)[key] = value
90
- end
91
-
92
- end
93
-
94
- Extension.send(:include, AR32Fallbacks)
95
- end
@@ -1,28 +0,0 @@
1
- module ActiveRecord::TypedStore
2
-
3
- class Coder < ::ActiveRecord::Store::IndifferentCoder
4
-
5
- class << self
6
-
7
- def create(store_class)
8
- Class.new(self) do
9
- @store_class = store_class
10
- end
11
- end
12
-
13
- def as_indifferent_hash(obj)
14
- return obj if obj.is_a?(@store_class)
15
- @store_class.new(obj)
16
- end
17
-
18
- end
19
-
20
- delegate :as_indifferent_hash, to: 'self.class'
21
-
22
- def dump(obj)
23
- @coder.dump(obj.try(:to_hash) || {})
24
- end
25
-
26
- end
27
-
28
- end
@@ -1,86 +0,0 @@
1
- module ActiveRecord::TypedStore
2
-
3
- class Column < ::ActiveRecord::ConnectionAdapters::Column
4
- attr_reader :array, :blank
5
-
6
- def initialize(name, type, options={})
7
- @name = name
8
- @type = type
9
- @array = options.fetch(:array, false)
10
- @default = extract_default(options.fetch(:default, nil))
11
- @null = options.fetch(:null, true)
12
- @blank = options.fetch(:blank, true)
13
- @accessor = options.fetch(:accessor, true)
14
- @scale = options[:scale]
15
- @limit = options[:limit]
16
- @precision = options[:precision]
17
- end
18
-
19
- def accessor?
20
- @accessor
21
- end
22
-
23
- def cast(value)
24
- casted_value = type_cast(value)
25
- if !blank
26
- casted_value = default if casted_value.blank?
27
- elsif !null
28
- casted_value = default if casted_value.nil?
29
- end
30
- casted_value
31
- end
32
-
33
- def extract_default(value)
34
- return value if (type == :string || type == :text) && value.nil?
35
-
36
- type_cast(value)
37
- end
38
-
39
- def type_cast(value, map=true)
40
- if array && (map || value.is_a?(Array))
41
- return [] if map && !value.is_a?(Array)
42
- return value.map{ |v| type_cast(v, false) }
43
- end
44
-
45
- if type == :string || type == :text
46
- return value.to_s unless value.nil? && (null || array)
47
- end
48
-
49
- if IS_AR_3_2 && type == :datetime && value.is_a?(DateTime)
50
- return super(value.iso8601)
51
- end
52
-
53
- defined?(super) ? super(value) : type_cast_from_database(value)
54
- end
55
-
56
- end
57
-
58
- if defined? ::ActiveRecord::Type
59
- BaseColumn = remove_const(:Column)
60
-
61
- class DecimalType < ::ActiveRecord::Type::Decimal
62
- def type_cast_from_database(value)
63
- value = value.to_s if value.is_a?(Float)
64
- super(value)
65
- end
66
- end
67
-
68
- class Column < BaseColumn
69
- CAST_TYPES = {
70
- boolean: ::ActiveRecord::Type::Boolean,
71
- integer: ::ActiveRecord::Type::Integer,
72
- string: ::ActiveRecord::Type::String,
73
- float: ::ActiveRecord::Type::Float,
74
- date: ::ActiveRecord::Type::Date,
75
- datetime: ::ActiveRecord::Type::DateTime,
76
- decimal: DecimalType,
77
- any: ::ActiveRecord::Type::Value,
78
- }
79
-
80
- def initialize(_, type, options = {})
81
- @cast_type = CAST_TYPES.fetch(type).new(options.slice(:limit, :scale, :precision))
82
- super
83
- end
84
- end
85
- end
86
- end