fixed_record 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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