fixed_record 0.1.2 → 0.2.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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/README.md +70 -14
  4. data/lib/fixed_record.rb +74 -21
  5. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 517a804c21cbd7ebe17493341ae42ddef70193953f5d3a40026907f470088eeb
4
- data.tar.gz: 8d7f1d298b25419ef38b457b0a6284dcf6c3b385dfa20b272d98a09f3281b607
3
+ metadata.gz: 0eea6e2937878d931df67a139cff38882002163f62f43e9f6b4e9440c84bbc60
4
+ data.tar.gz: 8d51b0834f97783271b77fd8762289efad419c463aa3a6f705affded0a07de2e
5
5
  SHA512:
6
- metadata.gz: ac9c2c0ba7632aa0edf97a49f5a4e95377f99f5aa46ed28ec4de7a91560f0aa4e96e1edbbbaf203f9623711c5baaf57ce3ac4d7a99f8d55876a2435954dd091f
7
- data.tar.gz: 4e76dc6a252b5e71c6932d423ab2c274bdb9d975004879d97409a421ea5baeabee15dc101cd321c754576bbef126eaa70f6017cd262d125a892d3c4735d31208
6
+ metadata.gz: 39687e91690bd8426119d2c41b77298dc3a48c2da4000a57bc6160f14ea2eb021d4495eac2ca27d50189fa5fcedbb2196c4c543bda44ff936aba2cf27d4f9b42
7
+ data.tar.gz: '0697f532ce75a0e808fefe5a94a9fa42b9fa00e346c7e6dda1288066aab857ab36d196a57473134d04d66ad4aa0b4b91a4db57a8197284a5c49ff9cfaf18b432'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fixed_record (0.1.0)
4
+ fixed_record (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -4,13 +4,11 @@ FixedRecord provides ActiveRecord-like read-only access to a set of records
4
4
  described in a YAML file.
5
5
 
6
6
  Why is this useful? Occasionally you have tabular data which hardly ever
7
- changes and can easily be edited by hand. Although this code could be placed in a database, it's not worth the overheads (loading a database, maintaining database code).
8
-
9
- It's quicker and simpler to implement this as an array of objects in a YAML file.
10
-
11
- See the Usage section below
7
+ changes and can easily be edited by hand. Although this data could be placed in a database, it may not be worth the overhead involved (loading a database, maintaining database code, etc.).
12
8
 
9
+ It may be quicker and simpler to implement this as an array or hash of objects in a YAML file, and use this gem to provide access to the data.
13
10
 
11
+ See the Usage section below.
14
12
 
15
13
  ## Installation
16
14
 
@@ -30,6 +28,8 @@ Or install it yourself as:
30
28
 
31
29
  ## Usage
32
30
 
31
+ ### Array of Records
32
+
33
33
  Create a YAML file defining an array of records like this:
34
34
 
35
35
  ```yaml
@@ -45,7 +45,7 @@ Create a YAML file defining an array of records like this:
45
45
  Then to load these, create a class
46
46
 
47
47
  ```ruby
48
- require 'FixedRecord'
48
+ require 'fixed_record'
49
49
 
50
50
  class MyFavoriteWebsite < FixedRecord
51
51
  data "#{Rails.root}/data/my_favorite_websites.yml"
@@ -68,19 +68,78 @@ end
68
68
  Or can be accessed as an array:
69
69
 
70
70
  ```ruby
71
- MyFavoriteWebiste.all
71
+ MyFavoriteWebsite.all.is_a?(Array) # true
72
+ ```
73
+ A count of the number of records is available:
74
+
75
+ ```ruby
76
+ puts MyFavoriteWebsite.count
77
+ ```
78
+
79
+ The declared class will also include all the methods from the `Enumerable` module.
80
+
81
+ ### Hash of Records
82
+
83
+ Create a YAML file `my_web_pages.yml` defining a hash of records like this:
84
+
85
+ ```yaml
86
+ StaticPage#first:
87
+ title: First Page
88
+ description: Welcome to the First Page
89
+
90
+ StaticPage#last:
91
+ title: Last Page
92
+ description: Welcome to the Last Page
93
+
94
+ ```
95
+
96
+ Then to load these, create a class
97
+
98
+ ```ruby
99
+ require 'fixed_record'
100
+
101
+ class MyWebPages < FixedRecord
102
+ data "#{Rails.root}/data/my_web_pages.yml"
103
+
104
+ end
105
+ ```
106
+
107
+ The collection can be accessed by index:
108
+
109
+ ```ruby
110
+ MyWebPages['StaticPage#first'].title # First Page
111
+ MyWebPages['StaticPage#last'].description # Welcome to he Last page
112
+ MyWebPages['StaticPage#first'].key # StaticPage#fifst
113
+ ```
114
+
115
+ The collection can then be enumerated as required:
116
+
117
+ ```ruby
118
+ MyWebPages.each do |k,v|
119
+ puts k
120
+ puts v.title
121
+ end
122
+ ```
123
+ Or can be accessed as an hash:
124
+
125
+ ```ruby
126
+ MyWebPages.all.is_a?(Hash) # true
72
127
  ```
73
128
  A count of the number of records is available:
74
129
 
75
130
  ```ruby
76
- puts MyFavoriteWebiste.count
131
+ puts MyWebPages.count
77
132
  ```
78
133
 
79
- The class also includes the `Enumerable` module.
134
+ The declared class will also include all the methods from the `Enumerable` module.
135
+
136
+
137
+
138
+ ## Error Checking
80
139
 
81
140
  Some basic sanity checks are performed on the YAML file to catch common errors:
82
141
 
83
- * It must define a non-empty array of records
142
+ * It must define a non-empty array or hash of records
84
143
  * All records must have the same set of attributes
85
144
 
86
145
  An `ArgumentError` exception will be thrown if any errors are detected.
@@ -89,9 +148,6 @@ Additional validations can be performed by overriding the `validate_yaml` and
89
148
  `validate_item` class functions.
90
149
 
91
150
 
92
-
93
-
94
-
95
151
  ## Development
96
152
 
97
153
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -100,4 +156,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
100
156
 
101
157
  ## Contributing
102
158
 
103
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/fixed_record.
159
+ Bug reports and pull requests are welcome on GitHub at https://github.com/m-z-b/fixed_record.
data/lib/fixed_record.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  require 'yaml'
3
3
 
4
4
  class FixedRecord
5
- VERSION = "0.1.2"
5
+ VERSION = "0.2.0"
6
6
 
7
7
  # Lazy load data from given filename
8
8
  # creating accessors for top level attributes
@@ -28,43 +28,96 @@ class FixedRecord
28
28
  end
29
29
 
30
30
  def self.count
31
- all.count
31
+ all.length
32
32
  end
33
33
 
34
+ def self.[]( k )
35
+ if all.is_a?(Hash)
36
+ all[k]
37
+ else
38
+ nil
39
+ end
40
+ end
41
+
42
+ def self.has_key?( k )
43
+ if all.is_a?(Hash)
44
+ all.has_key?( k )
45
+ else
46
+ false
47
+ end
48
+ end
49
+
34
50
  def self.load!
35
51
  if @@items.nil?
36
52
  y = YAML.load_file( filename )
37
53
  validate_yaml( y )
38
- valid_keys = y.first.keys
39
- valid_keys.each do |k|
40
- define_method( k.to_sym) { @values[k] }
41
- end
42
-
43
- @@items = y.map.with_index do |values,i|
44
- validate_item( valid_keys, values, i )
45
- r = new
46
- r.instance_variable_set( :@values, values )
47
- r
54
+ valid_keys = nil
55
+ if y.is_a?(Array)
56
+ valid_keys = y.first.keys
57
+ @@items = y.map.with_index do |values,i|
58
+ validate_item( valid_keys, values, i )
59
+ r = new
60
+ r.instance_variable_set( :@values, values )
61
+ r
62
+ end
63
+ elsif y.is_a?(Hash)
64
+ @@items = Hash.new
65
+ add_key = true
66
+ y.each do |k,values|
67
+ if valid_keys.nil?
68
+ valid_keys = values.keys
69
+ add_key = !values.has_key?('key')
70
+ end
71
+ validate_item( valid_keys, values, k )
72
+ values['key'] = k if add_key
73
+ r = new
74
+ r.instance_variable_set( :@values, values )
75
+ @@items[k] = r
76
+ end
77
+ valid_keys << 'key' if add_key
48
78
  end
79
+ create_methods( valid_keys )
49
80
  end
50
81
  end
51
82
  }
52
83
  end
53
84
 
85
+ # Create access methods for each of valid_keys
86
+ def self.create_methods( valid_keys )
87
+ valid_keys.each do |k|
88
+ define_method( k.to_sym) { @values[k] }
89
+ end
90
+ end
91
+
54
92
  # Validate the top level of the data structure returned
55
93
  def self.validate_yaml( y )
56
- unless y.is_a?(Array) && y.length > 0
57
- throw ArgumentError.new "#{filename} does not contain an array of items"
94
+ if y.is_a?(Array)
95
+ if y.length <= 0
96
+ throw ArgumentError.new "#{filename} contain a zero length array"
97
+ end
98
+ if y.any?{ |i| !i.is_a?(Hash)}
99
+ throw ArgumentError.new "#{filename} does not contain an array of items (hashes)"
100
+ end
101
+ elsif y.is_a?(Hash)
102
+ if y.count <= 0
103
+ throw ArgumentError.new "#{filename} contain an empty hash"
104
+ end
105
+ if y.any?{ |k,v| !v.is_a?(Hash) }
106
+ throw ArgumentError.new "#{filename} does not contain an array of items (hashes)"
107
+ end
108
+ else
109
+ throw ArgumentError.new "#{filename} does not contain a hash of items or an array of items"
58
110
  end
111
+
59
112
  end
60
113
 
61
- # Validate a hash of name -> value
62
- def self.validate_item( keys, hash, index )
63
- raise ArgumentError, "#{filename} item #{index+1} should be name value pairs" unless hash.is_a?(Hash)
64
- raise ArgumentError, "#{filename} item #{index+1} has wrong number of values" if keys.count != hash.count
65
- keys.each do |name|
66
- unless hash.has_key? name
67
- raise ArgumentError, "#{filename} item #{index+1} is missing value for '#{name}'"
114
+ # Validate a values of name -> value
115
+ def self.validate_item( valid_keys, values, index )
116
+ raise ArgumentError, "#{filename} item #{index} should be name value pairs" unless values.is_a?(Hash)
117
+ raise ArgumentError, "#{filename} item #{index} has wrong number of values" if valid_keys.length != values.length
118
+ valid_keys.each do |name|
119
+ unless values.has_key? name
120
+ raise ArgumentError, "#{filename} item #{index} is missing value for '#{name}'"
68
121
  end
69
122
  end
70
123
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fixed_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Bell
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-19 00:00:00.000000000 Z
11
+ date: 2020-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -91,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
91
  - !ruby/object:Gem::Version
92
92
  version: '0'
93
93
  requirements: []
94
- rubygems_version: 3.0.3
94
+ rubygems_version: 3.1.2
95
95
  signing_key:
96
96
  specification_version: 4
97
97
  summary: Provide ActiveRecord like read-only access to a small dataset stored in a