frozen_record 0.6.0 → 0.7.0

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
  SHA1:
3
- metadata.gz: e3ad807dcab80676636ab54fc06c01f5a20358b9
4
- data.tar.gz: 252b2ef0891b9b62b62616317f1ef5ac4d378abe
3
+ metadata.gz: fdb7686678220892ee4d076e0dd12678eb3b5bb6
4
+ data.tar.gz: 1cb91679f2c40a42ff635b3ae92a28169641b4f8
5
5
  SHA512:
6
- metadata.gz: e7d43b151b30c11aba06de403a8eace5f49c970f7e11c7501d85775ecd2bb9fae194f2569f00d291d0db11e75e5a96deee74aeddcb66bd2e1433fa113cae5247
7
- data.tar.gz: 82e9a979804003d0143c945fa17b71cc7f23614100c95bfa79fa414b7ac7e4ff66091cfbc2f97eec88d3748188efacb291659eed182659c770ed12855e0e1c80
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`.
@@ -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, load_records)
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 count
68
- load_records.size
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|
@@ -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, records)
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
- @results ||= query_results
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
- @results ||= slice_records(matching_records)
145
+ slice_records(matching_records)
147
146
  end
148
147
 
149
148
  def matching_records
150
- @matches ||= sort_records(select_records(@records))
149
+ sort_records(select_records(@klass.load_records))
151
150
  end
152
151
 
153
152
  def select_records(records)
@@ -1,3 +1,3 @@
1
1
  module FrozenRecord
2
- VERSION = '0.6.0'
2
+ VERSION = '0.7.0'
3
3
  end
@@ -4,7 +4,7 @@ describe FrozenRecord::Base do
4
4
 
5
5
  describe '.base_path' do
6
6
 
7
- it 'raise a RuntimeError on first query attempt if not set' do
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.6.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-02 00:00:00.000000000 Z
11
+ date: 2016-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel