fixed_record 0.3.0 → 0.4.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/CHANGELOG.md +3 -0
- data/Gemfile.lock +1 -1
- data/README.md +31 -0
- data/lib/fixed_record.rb +87 -57
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 07420f9a6931182806b5ee82f717a1a99d48ffa2cbca75c6c0c7e2b535ee72e2
         | 
| 4 | 
            +
              data.tar.gz: 902a5a02d643c65a60f597f4fbc26018d2a3c0546d1d5977a9adef114283dc21
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: a11fa7c40a495fc4e64744b3a7da437e15dc8f95a12a1b914f14fa1b4a7c8e49a6e41695d4b977131208c5a7f071fb8bfda2cd581760859b8a8d15d6a7eae438
         | 
| 7 | 
            +
              data.tar.gz: 86e95dd06779296de7c9c929500bcdf562cdbc6e0270462f7b08c464e633a5735ad1e51d07371fe10f0b2baa20557060ee134f19e4be238d56c619d8edbf309b
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -134,6 +134,37 @@ puts MyWebPages.count | |
| 134 134 |  | 
| 135 135 | 
             
            The declared class will also include all the methods from the `Enumerable` module.
         | 
| 136 136 |  | 
| 137 | 
            +
            ### Singleton Record
         | 
| 138 | 
            +
             | 
| 139 | 
            +
            Create a YAML file `site_settingss.yml` defining a single records like this:
         | 
| 140 | 
            +
             | 
| 141 | 
            +
            ```yaml
         | 
| 142 | 
            +
             | 
| 143 | 
            +
            sessionExpiry: 3600
         | 
| 144 | 
            +
            phone: +1.613.555.1212
         | 
| 145 | 
            +
            address: 500 Main Street, Anytown, Antartica
         | 
| 146 | 
            +
             | 
| 147 | 
            +
            ```
         | 
| 148 | 
            +
             | 
| 149 | 
            +
            Then to load these, create a class
         | 
| 150 | 
            +
             | 
| 151 | 
            +
            ```ruby
         | 
| 152 | 
            +
            require 'fixed_record'
         | 
| 153 | 
            +
             | 
| 154 | 
            +
            class SiteSettings < FixedRecord
         | 
| 155 | 
            +
                data "#{Rails.root}/data/site_settings.yml", singleton: true
         | 
| 156 | 
            +
             | 
| 157 | 
            +
            end
         | 
| 158 | 
            +
            ```
         | 
| 159 | 
            +
             | 
| 160 | 
            +
            The values can be accessed by index:
         | 
| 161 | 
            +
             | 
| 162 | 
            +
            ```ruby
         | 
| 163 | 
            +
            SiteSettings['phone'] # '+1.613.555.1212'
         | 
| 164 | 
            +
            SiteSettings['address'] # '500 Main Street, Anytown, Antartica'
         | 
| 165 | 
            +
            SiteSettings[:phone] # This works too
         | 
| 166 | 
            +
            ```
         | 
| 167 | 
            +
            The `required` and `optional` arguments can be used to check for inadvertent errors being introduced into the YAML file. An ArgumentError will be raised if the name is not defined in the file and is not declared as optional. 
         | 
| 137 168 |  | 
| 138 169 |  | 
| 139 170 | 
             
            ## Error Checking
         | 
    
        data/lib/fixed_record.rb
    CHANGED
    
    | @@ -3,11 +3,11 @@ require 'yaml' | |
| 3 3 | 
             
            require 'set'
         | 
| 4 4 |  | 
| 5 5 | 
             
            class FixedRecord
         | 
| 6 | 
            -
              VERSION = "0. | 
| 6 | 
            +
              VERSION = "0.4.0"
         | 
| 7 7 |  | 
| 8 8 | 
             
              # Lazy load data from given filename 
         | 
| 9 9 | 
             
              # creating accessors for top level attributes
         | 
| 10 | 
            -
              def self.data( filename, required: [], optional: [] ) 
         | 
| 10 | 
            +
              def self.data( filename, required: [], optional: [], singleton: false ) 
         | 
| 11 11 | 
             
                required = required.map( &:to_s )
         | 
| 12 12 | 
             
                optional = optional.map( &:to_s )
         | 
| 13 13 | 
             
                throw ArgumentError, "Required and Optional names overlap" unless (required & optional).empty?
         | 
| @@ -20,54 +20,83 @@ class FixedRecord | |
| 20 20 | 
             
                self.class_variable_set( :@@required_keys, required_keys )
         | 
| 21 21 | 
             
                self.class_variable_set( :@@valid_keys, valid_keys )
         | 
| 22 22 | 
             
                self.class_variable_set( :@@items, nil )
         | 
| 23 | 
            +
                self.class_variable_set( :@@singleton, singleton )
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                if singleton 
         | 
| 26 | 
            +
                  class_eval %Q{
         | 
| 27 | 
            +
                    def self.[](k)
         | 
| 28 | 
            +
                      load!
         | 
| 29 | 
            +
                      k = k.to_s
         | 
| 30 | 
            +
                      raise ArgumentError, "\#{k} is not a valid key" unless @@valid_keys.member?(k)
         | 
| 31 | 
            +
                      @@items[k]
         | 
| 32 | 
            +
                    end
         | 
| 33 | 
            +
                  }
         | 
| 34 | 
            +
                else
         | 
| 35 | 
            +
                  class_eval %Q{
         | 
| 36 | 
            +
                    class << self
         | 
| 37 | 
            +
                      include Enumerable
         | 
| 38 | 
            +
                    end
         | 
| 23 39 |  | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 40 | 
            +
                    def self.all 
         | 
| 41 | 
            +
                      load!
         | 
| 42 | 
            +
                      @@items
         | 
| 43 | 
            +
                    end
         | 
| 28 44 |  | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 45 | 
            +
                    def self.each( &block )
         | 
| 46 | 
            +
                      load!
         | 
| 47 | 
            +
                      @@items.each(&block)
         | 
| 48 | 
            +
                    end
         | 
| 32 49 |  | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 50 | 
            +
                    def self.count
         | 
| 51 | 
            +
                      load!
         | 
| 52 | 
            +
                      @@items.length
         | 
| 53 | 
            +
                    end
         | 
| 37 54 |  | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 55 | 
            +
                    def self.[]( k )
         | 
| 56 | 
            +
                      if all.is_a?(Hash)
         | 
| 57 | 
            +
                        all[k.to_s]
         | 
| 58 | 
            +
                      else
         | 
| 59 | 
            +
                        nil
         | 
| 60 | 
            +
                      end
         | 
| 61 | 
            +
                    end
         | 
| 41 62 |  | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 63 | 
            +
                    def self.has_key?( k )
         | 
| 64 | 
            +
                      if all.is_a?(Hash)
         | 
| 65 | 
            +
                        all.has_key?( k )
         | 
| 66 | 
            +
                      else
         | 
| 67 | 
            +
                        false
         | 
| 68 | 
            +
                      end
         | 
| 69 | 
            +
                    end 
         | 
| 45 70 |  | 
| 46 | 
            -
                   | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
                     | 
| 71 | 
            +
                  }
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                class_eval %Q{
         | 
| 75 | 
            +
                  def self.filename
         | 
| 76 | 
            +
                    @@filename
         | 
| 52 77 | 
             
                  end
         | 
| 53 78 |  | 
| 54 | 
            -
                  def self.has_key?( k )
         | 
| 55 | 
            -
                    if all.is_a?(Hash)
         | 
| 56 | 
            -
                      all.has_key?( k )
         | 
| 57 | 
            -
                    else
         | 
| 58 | 
            -
                      false
         | 
| 59 | 
            -
                    end
         | 
| 60 | 
            -
                  end 
         | 
| 61 79 |  | 
| 62 80 | 
             
                  def self.load!
         | 
| 63 81 | 
             
                    if @@items.nil?
         | 
| 64 | 
            -
                      y = YAML.load_file( filename )
         | 
| 65 | 
            -
                      validate_structure( y )
         | 
| 66 | 
            -
                      if  | 
| 67 | 
            -
                         | 
| 82 | 
            +
                      y = YAML.load_file( @@filename )
         | 
| 83 | 
            +
                      validate_structure( y, @@singleton, @@filename )
         | 
| 84 | 
            +
                      if @@valid_keys.empty? 
         | 
| 85 | 
            +
                        # Grab keys from file
         | 
| 86 | 
            +
                        if @@singleton
         | 
| 87 | 
            +
                          @@valid_keys = y.keys
         | 
| 88 | 
            +
                        elsif y.is_a?(Array)
         | 
| 68 89 | 
             
                          @@valid_keys = y.first.keys
         | 
| 90 | 
            +
                          @@required_keys = @@valid_keys       
         | 
| 91 | 
            +
                        elsif y.is_a?(Hash)
         | 
| 92 | 
            +
                          @@valid_keys = y[y.keys.first].keys
         | 
| 69 93 | 
             
                          @@required_keys = @@valid_keys
         | 
| 70 94 | 
             
                        end
         | 
| 95 | 
            +
                      end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                      if @@singleton
         | 
| 98 | 
            +
                        @@items = y
         | 
| 99 | 
            +
                      elsif y.is_a?(Array)
         | 
| 71 100 | 
             
                        @@items = y.map.with_index do |values,i|
         | 
| 72 101 | 
             
                          validate_item( @@valid_keys, @@required_keys, values, i )
         | 
| 73 102 | 
             
                          r = new
         | 
| @@ -78,11 +107,6 @@ class FixedRecord | |
| 78 107 | 
             
                        @@items = Hash.new
         | 
| 79 108 | 
             
                        add_key = !@@valid_keys.member?('key')
         | 
| 80 109 | 
             
                        y.each do |k,values|
         | 
| 81 | 
            -
                          if @@valid_keys.empty?
         | 
| 82 | 
            -
                            @@required_keys.merge( values.keys )
         | 
| 83 | 
            -
                            @@valid_keys.merge( values.keys )
         | 
| 84 | 
            -
                            add_key = !@@valid_keys.member?('key')
         | 
| 85 | 
            -
                          end
         | 
| 86 110 | 
             
                          validate_item( @@valid_keys, @@required_keys, values, k )
         | 
| 87 111 | 
             
                          values['key'] = k if add_key
         | 
| 88 112 | 
             
                          r = new
         | 
| @@ -114,25 +138,31 @@ private | |
| 114 138 | 
             
              end
         | 
| 115 139 |  | 
| 116 140 | 
             
              # Validate the top level of the data structure returned 
         | 
| 117 | 
            -
               | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 122 | 
            -
                  if y.any?{ |i| !i.is_a?(Hash)}
         | 
| 123 | 
            -
                    throw ArgumentError.new "#{filename} does not contain an array of items (hashes)"
         | 
| 124 | 
            -
                  end
         | 
| 125 | 
            -
                elsif y.is_a?(Hash)
         | 
| 126 | 
            -
                  if y.count <= 0
         | 
| 127 | 
            -
                     throw ArgumentError.new "#{filename} contain an empty hash"
         | 
| 128 | 
            -
                  end
         | 
| 129 | 
            -
                  if y.any?{ |k,v| !v.is_a?(Hash) }
         | 
| 130 | 
            -
                    throw ArgumentError.new "#{filename} does not contain an array of items (hashes)"
         | 
| 141 | 
            +
              # Validate the top level of the data structure returned 
         | 
| 142 | 
            +
              def self.validate_structure( y, singleton, filename )
         | 
| 143 | 
            +
                if singleton
         | 
| 144 | 
            +
                  if !y.is_a?(Hash)
         | 
| 145 | 
            +
                    raise ArgumentError, "#{filename} does not contain a hash of values or an array of items"
         | 
| 131 146 | 
             
                  end
         | 
| 132 147 | 
             
                else
         | 
| 133 | 
            -
                   | 
| 148 | 
            +
                  if y.is_a?(Array)
         | 
| 149 | 
            +
                    if y.length <= 0
         | 
| 150 | 
            +
                      raise ArgumentError, "#{filename} contain a zero length array"
         | 
| 151 | 
            +
                    end
         | 
| 152 | 
            +
                    if y.any?{ |i| !i.is_a?(Hash)}
         | 
| 153 | 
            +
                      raise ArgumentError, "#{filename} does not contain an array of items (hashes)"
         | 
| 154 | 
            +
                    end
         | 
| 155 | 
            +
                  elsif y.is_a?(Hash)
         | 
| 156 | 
            +
                    if y.count <= 0
         | 
| 157 | 
            +
                       raise ArgumentError, "#{filename} contain an empty hash"
         | 
| 158 | 
            +
                    end
         | 
| 159 | 
            +
                    if y.any?{ |k,v| !v.is_a?(Hash) }
         | 
| 160 | 
            +
                      raise ArgumentError, "#{filename} does not contain an array of items (hashes)"
         | 
| 161 | 
            +
                    end
         | 
| 162 | 
            +
                  else
         | 
| 163 | 
            +
                    raise ArgumentError, "#{filename} does not contain a hash of items or an array of items"
         | 
| 164 | 
            +
                  end
         | 
| 134 165 | 
             
                end
         | 
| 135 | 
            -
             | 
| 136 166 | 
             
              end
         | 
| 137 167 |  | 
| 138 168 | 
             
              # Validate a values of name -> value
         | 
    
        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. | 
| 4 | 
            +
              version: 0.4.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- | 
| 11 | 
            +
            date: 2020-02-28 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         |