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 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