frozen_record 0.6.0 → 0.7.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/README.md +13 -0
- data/lib/frozen_record/base.rb +20 -15
- data/lib/frozen_record/scope.rb +5 -6
- data/lib/frozen_record/version.rb +1 -1
- data/spec/frozen_record_spec.rb +41 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fdb7686678220892ee4d076e0dd12678eb3b5bb6
|
4
|
+
data.tar.gz: 1cb91679f2c40a42ff635b3ae92a28169641b4f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a01bb54dc54ca88f5acb7b85c4739002e6e7918345f55f7bd45cd4f97350e1d721c9497f981b909ec57ae217353a881f4c01c36e8f66921353dfc099fa60d760
|
7
|
+
data.tar.gz: de01bdbbb0c09f3d8720711a540c7a7686ba2c7f55d64ddd39296f9e3ba8501da3f84b81259f22b26f30f2fe840e75c80e2610788abe39f98d1634a129cdeafa
|
data/README.md
CHANGED
@@ -110,6 +110,19 @@ Country.republics.part_of_nato.order(id: :desc)
|
|
110
110
|
- average
|
111
111
|
|
112
112
|
|
113
|
+
## Configuration
|
114
|
+
|
115
|
+
### Reloading
|
116
|
+
|
117
|
+
By default the YAML files are parsed once and then cached in memory. But in development you might want changes to be reflected without having to restart your application.
|
118
|
+
|
119
|
+
For such cases you can set `auto_reloading` to `true` either globally or on a model basis:
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
FrozenRecord::Base.auto_reloading = true # Activate reloading for all models
|
123
|
+
Country.auto_reloading # Activate reloading for `Country` only
|
124
|
+
```
|
125
|
+
|
113
126
|
## Contributors
|
114
127
|
|
115
128
|
FrozenRecord is a from scratch reimplementation of a [Shopify](https://github.com/Shopify) project from 2007 named `YamlRecord`.
|
data/lib/frozen_record/base.rb
CHANGED
@@ -19,6 +19,8 @@ module FrozenRecord
|
|
19
19
|
class_attribute :primary_key
|
20
20
|
self.primary_key = :id
|
21
21
|
|
22
|
+
class_attribute :auto_reloading
|
23
|
+
|
22
24
|
attribute_method_suffix '?'
|
23
25
|
|
24
26
|
class ThreadSafeStorage
|
@@ -42,7 +44,7 @@ module FrozenRecord
|
|
42
44
|
class << self
|
43
45
|
|
44
46
|
def current_scope
|
45
|
-
store[:scope] ||= Scope.new(self
|
47
|
+
store[:scope] ||= Scope.new(self)
|
46
48
|
end
|
47
49
|
alias_method :all, :current_scope
|
48
50
|
|
@@ -51,7 +53,7 @@ module FrozenRecord
|
|
51
53
|
end
|
52
54
|
|
53
55
|
delegate :find, :find_by_id, :find_by, :find_by!, :where, :first, :first!, :last, :last!, :pluck, :ids, :order, :limit, :offset,
|
54
|
-
:minimum, :maximum, :average, :sum, to: :current_scope
|
56
|
+
:minimum, :maximum, :average, :sum, :count, to: :current_scope
|
55
57
|
|
56
58
|
def file_path
|
57
59
|
fail ArgumentError, "You must define `#{name}.base_path`" unless base_path
|
@@ -64,12 +66,26 @@ module FrozenRecord
|
|
64
66
|
end
|
65
67
|
end
|
66
68
|
|
67
|
-
def
|
68
|
-
|
69
|
+
def load_records
|
70
|
+
@records = nil if auto_reloading && file_changed?
|
71
|
+
@records ||= begin
|
72
|
+
yml_erb_data = File.read(file_path)
|
73
|
+
yml_data = ERB.new(yml_erb_data).result
|
74
|
+
|
75
|
+
records = YAML.load(yml_data) || []
|
76
|
+
define_attributes!(list_attributes(records))
|
77
|
+
records.map(&method(:new)).freeze
|
78
|
+
end
|
69
79
|
end
|
70
80
|
|
71
81
|
private
|
72
82
|
|
83
|
+
def file_changed?
|
84
|
+
last_mtime = @file_mtime
|
85
|
+
@file_mtime = File.mtime(file_path)
|
86
|
+
last_mtime != @file_mtime
|
87
|
+
end
|
88
|
+
|
73
89
|
def store
|
74
90
|
@store ||= ThreadSafeStorage.new(name)
|
75
91
|
end
|
@@ -86,17 +102,6 @@ module FrozenRecord
|
|
86
102
|
bang ? results.first! : results.first
|
87
103
|
end
|
88
104
|
|
89
|
-
def load_records
|
90
|
-
@records ||= begin
|
91
|
-
yml_erb_data = File.read(file_path)
|
92
|
-
yml_data = ERB.new(yml_erb_data).result
|
93
|
-
|
94
|
-
records = YAML.load(yml_data) || []
|
95
|
-
define_attributes!(list_attributes(records))
|
96
|
-
records.map(&method(:new)).freeze
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
105
|
def list_attributes(records)
|
101
106
|
attributes = Set.new
|
102
107
|
records.each do |record|
|
data/lib/frozen_record/scope.rb
CHANGED
@@ -6,7 +6,7 @@ module FrozenRecord
|
|
6
6
|
:keep_if, :pop, :shift, :delete_at, :compact
|
7
7
|
].to_set
|
8
8
|
|
9
|
-
delegate :first, :last, :length, :collect, :map, :each, :all?, :include?, :to_ary, :to_json, :as_json, to: :to_a
|
9
|
+
delegate :first, :last, :length, :collect, :map, :each, :all?, :include?, :to_ary, :to_json, :as_json, :count, to: :to_a
|
10
10
|
if defined? ActiveModel::Serializers::Xml
|
11
11
|
delegate :to_xml, to: :to_a
|
12
12
|
end
|
@@ -21,9 +21,8 @@ module FrozenRecord
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
def initialize(klass
|
24
|
+
def initialize(klass)
|
25
25
|
@klass = klass
|
26
|
-
@records = records
|
27
26
|
@where_values = []
|
28
27
|
@where_not_values = []
|
29
28
|
@order_values = []
|
@@ -57,7 +56,7 @@ module FrozenRecord
|
|
57
56
|
end
|
58
57
|
|
59
58
|
def to_a
|
60
|
-
|
59
|
+
query_results
|
61
60
|
end
|
62
61
|
|
63
62
|
def pluck(*attributes)
|
@@ -143,11 +142,11 @@ module FrozenRecord
|
|
143
142
|
end
|
144
143
|
|
145
144
|
def query_results
|
146
|
-
|
145
|
+
slice_records(matching_records)
|
147
146
|
end
|
148
147
|
|
149
148
|
def matching_records
|
150
|
-
|
149
|
+
sort_records(select_records(@klass.load_records))
|
151
150
|
end
|
152
151
|
|
153
152
|
def select_records(records)
|
data/spec/frozen_record_spec.rb
CHANGED
@@ -4,7 +4,7 @@ describe FrozenRecord::Base do
|
|
4
4
|
|
5
5
|
describe '.base_path' do
|
6
6
|
|
7
|
-
it 'raise a RuntimeError
|
7
|
+
it 'raise a RuntimeError on first query attempt if not set' do
|
8
8
|
allow(Country).to receive_message_chain(:base_path).and_return(nil)
|
9
9
|
expect {
|
10
10
|
Country.file_path
|
@@ -13,6 +13,46 @@ describe FrozenRecord::Base do
|
|
13
13
|
|
14
14
|
end
|
15
15
|
|
16
|
+
describe '.auto_reloading' do
|
17
|
+
|
18
|
+
context 'when enabled' do
|
19
|
+
|
20
|
+
around do |example|
|
21
|
+
previous_auto_reloading = Country.auto_reloading
|
22
|
+
Country.auto_reloading = true
|
23
|
+
begin
|
24
|
+
example.run
|
25
|
+
ensure
|
26
|
+
Country.auto_reloading = previous_auto_reloading
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'reloads the records if the file mtime changed' do
|
31
|
+
mtime = File.mtime(Country.file_path)
|
32
|
+
expect {
|
33
|
+
File.utime(mtime + 1, mtime + 1, Country.file_path)
|
34
|
+
}.to change { Country.first.object_id }
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'does not reload if the file has not changed' do
|
38
|
+
expect(Country.first.object_id).to be == Country.first.object_id
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when disabled' do
|
44
|
+
|
45
|
+
it 'does not reloads the records if the file mtime changed' do
|
46
|
+
mtime = File.mtime(Country.file_path)
|
47
|
+
expect {
|
48
|
+
File.utime(mtime + 1, mtime + 1, Country.file_path)
|
49
|
+
}.to_not change { Country.first.object_id }
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
16
56
|
describe '#load_records' do
|
17
57
|
|
18
58
|
it 'processes erb' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: frozen_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Boussier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-05-
|
11
|
+
date: 2016-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|