yaml_b_sides 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 34f0e2100b8e81fce8b87d1dba72fcb86f9fb793
4
- data.tar.gz: 5bc09894491c3d319201395b7e2b8db587bf41bc
3
+ metadata.gz: 74424ddac245862a30ea744f4287c97c172890fb
4
+ data.tar.gz: 42c2edbd0cf88620f71b22405604c4c80a8a28d7
5
5
  SHA512:
6
- metadata.gz: 1eac6dbbeab847afcc4a1e8b13928b136eea401944cc4cd6e5565d2a4e498e318eb91088adb9c361a8c45564c0704a3e9c395ee2e58691fc5150ed8113873819
7
- data.tar.gz: fb58598b0988436f4a87c745e113465d08a745ce0b6d8fcd2bad47629b089c69a0f84057150ece185daf133a7ee8d864e446aa40642ba5ee653fd328dcf5a545
6
+ metadata.gz: cc05aaea7469a14f9cd9e8cdc06eeb3359337a340ef72396684ed5bc573a9fe07f2175c452c0ad238aa0c2c4bf6dd8593d51d7dd908e72a4e21637dcf6d0110e
7
+ data.tar.gz: 5726358d0660a9b48e479f23c747beb51e14a4999ab662613bf169c454862c1b4307159409af3b69721c72b05f9036f0f9d44b32012e5251529854fee7bf17ec
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
- # YamlBSides
1
+ # Yaml B-Sides
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/yaml_b_sides`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ `YamlBSides` is a simple read-only implementation of [YamlRecord](https://github.com/nicotaing/yaml_record). It's designed for users whose data is perfectly static and is stored in yaml files.
6
4
 
7
5
  ## Installation
8
6
 
@@ -22,7 +20,73 @@ Or install it yourself as:
22
20
 
23
21
  ## Usage
24
22
 
25
- TODO: Write usage instructions here
23
+ `Yaml B-Sides` acts very mich like active record. You set up your base class like you would an ActiveRecord class:
24
+
25
+ ```ruby
26
+ class Person < YamlBSides::Base
27
+ ```
28
+
29
+ and your `#{FIXTURES_PATH}/people.yml` (see [Setup](#setup) for fixtures path setup):
30
+
31
+ ```yml
32
+ greg:
33
+ name: Greg Orlov
34
+ url_slug: greg
35
+ bio: |
36
+ I do stuff
37
+
38
+ john:
39
+ name: John Doe
40
+ # ... etc
41
+ ```
42
+
43
+ and you're in business. Your `Person` objects will now respond to the *present* fields as methods. (see [Properties](#property-definitions) for setting defaults)
44
+
45
+ Note: `Yaml B-Sides` expects your class names to match the fixture names (e.g. `Person` will want a `people.yml` file)
46
+
47
+ Your `Person` class now responds to
48
+
49
+ ### Query Methods
50
+
51
+ * `all` : will give you all of the records in the table
52
+ * `first` : wil return the first record in the table
53
+ * `find( id )` : will find a single record with the specified yaml key
54
+ * `find_by( properties = {} )` : will find all the recored that match all the proerties in the hash
55
+
56
+ ### Indexing
57
+
58
+ * `index( field )` : will add an index on that field, for faster searching
59
+
60
+ ### Property definitions
61
+
62
+ These are completely optional, but if you have a yaml file that's not uniform, and want to have some defaults, you can use
63
+
64
+ * `property( name, defaul= nil )` : will set a single field. will set defaul value to nil if omitted
65
+ * `properties( props = {})` : takes a hash; will set many defaults at once
66
+
67
+ ### Example
68
+
69
+ To use the `People` class from earlier, a fully fleshed out model would look something like:
70
+
71
+ ```ruby
72
+ class Person < YamlBSides::Base
73
+ property :name, ""
74
+ properties url_slug: "",
75
+ bio: ""
76
+
77
+ index :name
78
+ index :url_slug
79
+ end
80
+ ```
81
+
82
+ ## Setup
83
+
84
+ The setup is pretty straightforward. Yaml B-Sides wants a logger and a base dir to look for files in. An example config for a Rails app would look like:
85
+
86
+ ```ruby
87
+ YamlBSides::Base.logger = Rails.logger
88
+ YamlBSides::Base.root_path = Rails.root.join 'db', 'fixtures'
89
+ ```
26
90
 
27
91
  ## Development
28
92
 
@@ -3,6 +3,7 @@ module YamlBSides
3
3
  include ActiveModel::Model
4
4
  include Cacheable
5
5
  include Propertiable
6
+ include Indexable
6
7
  include Instanceable
7
8
  include Queriable
8
9
 
@@ -12,7 +13,6 @@ module YamlBSides
12
13
  class << self
13
14
 
14
15
  def load!
15
- puts data_file
16
16
  @data = YAML.load_file( data_file ).with_indifferent_access
17
17
  idify_data!
18
18
  puts "#{self} successfully loaded data"
@@ -0,0 +1,16 @@
1
+ module YamlBSides
2
+ class Index
3
+ def initialize(field, data)
4
+ @indexed_data = {}
5
+ data.each do |id, datum|
6
+ key = datum[field]
7
+
8
+ @indexed_data[key] = Array(@indexed_data[key]) + [id]
9
+ end
10
+ end
11
+
12
+ def find(value)
13
+ @indexed_data[value]
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,35 @@
1
+ module YamlBSides
2
+ module Indexable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ class_attribute :__indices
7
+ self.__indices = {}
8
+
9
+ class << self
10
+ def index(field)
11
+ self.__indices = __indices.merge( { field => Index.new(field, @data) } )
12
+ end
13
+
14
+ def find_in_index(field, value)
15
+ keys = Array(index_for(field).find(value))
16
+
17
+ keys.map do |id|
18
+ find(id)
19
+ end
20
+ end
21
+
22
+ def indexed?(field)
23
+ __indices[field].present?
24
+ end
25
+
26
+ protected
27
+
28
+ def index_for(field)
29
+ __indices[field]
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
@@ -4,10 +4,6 @@ module YamlBSides
4
4
  included do
5
5
  include ActiveModel::Model
6
6
 
7
- def initialize( attrs = {} )
8
- @attributes = self.class.__properties.merge( attrs ).with_indifferent_access
9
- end
10
-
11
7
  def method_missing( method, *args, &block )
12
8
  if @attributes.has_key? method
13
9
  method = @attributes[method]
@@ -16,8 +12,11 @@ module YamlBSides
16
12
  end
17
13
  end
18
14
 
19
- def to_param
20
- id
15
+ protected
16
+
17
+ # public init really doesn't make sense for a read-only interface
18
+ def initialize( attrs = {} )
19
+ @attributes = self.class.__properties.merge( attrs ).with_indifferent_access
21
20
  end
22
21
  end
23
22
  end
@@ -9,6 +9,26 @@ module YamlBSides
9
9
  end
10
10
 
11
11
  def find_by(params = {})
12
+ if all_indexed?(params.keys)
13
+ find_by_indexed(params)
14
+ else
15
+ find_by_scan(params)
16
+ end
17
+ end
18
+
19
+ def all
20
+ @data.values.map do |obj|
21
+ new obj
22
+ end
23
+ end
24
+
25
+ def first
26
+ new @data.values.first
27
+ end
28
+
29
+ private
30
+
31
+ def find_by_scan(params)
12
32
  result = @data.values.find do |datum|
13
33
  params.all? do |param, expcted_value|
14
34
  datum[param] == expcted_value
@@ -17,9 +37,25 @@ module YamlBSides
17
37
  result ? new(result) : nil
18
38
  end
19
39
 
20
- def all
21
- @data.values.map do |obj|
22
- new obj
40
+ def find_by_indexed(params)
41
+ sets = []
42
+ params.each do |index, value|
43
+ sets << find_in_index(index, value)
44
+ end
45
+
46
+ # find the intersection of all the sets
47
+ sets.inject( sets.first ) do |result, subset|
48
+ result & subset
49
+ end
50
+ end
51
+
52
+ def all_indexed?(fields)
53
+ fields.all? do |field|
54
+ indexed = indexed? field
55
+ unless indexed
56
+ logger.warn "You are running a query on #{self}.#{field} which is not indexed. This will perform a table scan."
57
+ end
58
+ indexed
23
59
  end
24
60
  end
25
61
  end
@@ -1,3 +1,3 @@
1
1
  module YamlBSides
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/yaml_b_sides.rb CHANGED
@@ -11,6 +11,8 @@ module YamlBSides
11
11
  autoload :Base, 'yaml_b_sides/base'
12
12
  autoload :Cacheable, 'yaml_b_sides/cacheable'
13
13
  autoload :Instanceable, 'yaml_b_sides/instanceable'
14
+ autoload :Index, 'yaml_b_sides/index'
15
+ autoload :Indexable, 'yaml_b_sides/indexable'
14
16
  autoload :Propertiable, 'yaml_b_sides/propertiable'
15
17
  autoload :Queriable, 'yaml_b_sides/queriable'
16
18
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yaml_b_sides
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
  - Greg Orlov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-09-01 00:00:00.000000000 Z
11
+ date: 2016-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -99,6 +99,8 @@ files:
99
99
  - lib/yaml_b_sides.rb
100
100
  - lib/yaml_b_sides/base.rb
101
101
  - lib/yaml_b_sides/cacheable.rb
102
+ - lib/yaml_b_sides/index.rb
103
+ - lib/yaml_b_sides/indexable.rb
102
104
  - lib/yaml_b_sides/instanceable.rb
103
105
  - lib/yaml_b_sides/propertiable.rb
104
106
  - lib/yaml_b_sides/queriable.rb
@@ -129,3 +131,4 @@ signing_key:
129
131
  specification_version: 4
130
132
  summary: A light AcriveRecord like wrapper for flat YAML files
131
133
  test_files: []
134
+ has_rdoc: