yaml_b_sides 0.1.2 → 0.2.0

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