active_cabinet 0.1.1 → 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
  SHA256:
3
- metadata.gz: 9adb36f6d291c160a960599e7de79f3f9d08afb3f1536364dfc57c103d81254f
4
- data.tar.gz: 5a4bfd4907203cb963f1b7102b14701dcfbcefe44fb8dc2e7f0d4ab87af2f03b
3
+ metadata.gz: 6d657eb6430a9e6b83a734d786d607b515947e38e435c71e5e7ee4f10e5b7a4b
4
+ data.tar.gz: 425dd03d6a76f31526e9e56b06a2c05971328fdae786516bcb969084367aaa4c
5
5
  SHA512:
6
- metadata.gz: b4df4f37043c8285d3333e21161d4a681f375a8a80e63a57f1c0f797bbd6669617e95d4ccdee653aac9ed7bd488dfe4f10ebe00477c147f0c47c4185415e7a42
7
- data.tar.gz: f76c0f806f6aa0d14c392243cea42585ef108daf8a059659344893a21eee7044d0420bc39045eb39c20effe6ebccdfde9d59b664a5393209598837fa08c7eb45
6
+ metadata.gz: 8218b482cc51bb181224beeda6b8eb24acdcb6ff29eeb5bcae1df67ef22ed2a2c1ca4cf6e9798078034402fdae8d06b498337be4748ebf97fea26b9a7f0bac52
7
+ data.tar.gz: 478f69291f74ea3422771d31cf9ff91d587457293b4d2b5188df8542ff01a8bc2ce06f1faa19922d84d310a653a17a3e96e7557de3aa89122f05550fae652a10
data/README.md CHANGED
@@ -8,7 +8,7 @@ ActiveCabinet
8
8
  ---
9
9
 
10
10
  An ActiveRecord-inspired interface for [HashCabinet], the
11
- file-basd key-object store.
11
+ file-based key-object store.
12
12
 
13
13
  It allows you to create models that are stored in a file-based key-value
14
14
  store, backed by Ruby's built in [SDBM].
@@ -67,8 +67,8 @@ song.update! year: 1988, artist: 'Metallica' # this variant also saves
67
67
 
68
68
  ### Restricting / allowing certain attributes
69
69
 
70
- You may specify required arguments. Records without these attributes will
71
- not be saved. Note that `id` is always required
70
+ You may specify required attributes. Records without these attributes will
71
+ not be saved. Note that `id` is always required.
72
72
 
73
73
  ```ruby
74
74
  class Song < ActiveCabinet
@@ -114,15 +114,31 @@ song.valid? # => false
114
114
  song.error # => "invalid attributes: [:artist]"
115
115
  ```
116
116
 
117
+ ### Declaring default attribute values
118
+
119
+ You may specify default values for some attributes. These attrributes will
120
+ be merged into newly created record instances.
121
+
122
+ ```ruby
123
+ class Song < ActiveCabinet
124
+ required_attributes :title
125
+ default_attributes format: :mp3
126
+ end
127
+
128
+ song = Song.new title: "Moonchild"
129
+ song.format # => :mp3
130
+ ```
131
+
132
+
117
133
  ### Configuring storage path
118
134
 
119
135
  By default, `ActiveCabinet` stores all its files (two files per model) in the
120
136
  `./db` directory. The file name is determined by the name of the class.
121
137
 
122
- You can override both of these values
138
+ You can override both of these values:
123
139
 
124
140
  ```ruby
125
- # Set the based directory for all cabinets
141
+ # Set the base directory for all cabinets
126
142
  ActiveCabinet::Config.dir = "cabinets"
127
143
 
128
144
  # Set the filename of your model
@@ -14,7 +14,7 @@ class ActiveCabinet
14
14
  #
15
15
  # @param [Hash] attributes record attributes
16
16
  def initialize(attributes = {})
17
- @attributes = attributes.transform_keys(&:to_sym)
17
+ @attributes = default_attributes.merge attributes.transform_keys(&:to_sym)
18
18
  end
19
19
 
20
20
  # @!group Attribute Management
@@ -42,6 +42,10 @@ class ActiveCabinet
42
42
  self.class.optional_attributes
43
43
  end
44
44
 
45
+ def default_attributes
46
+ self.class.default_attributes
47
+ end
48
+
45
49
  # Returns +true+ if the object is valid.
46
50
  #
47
51
  # @return [Boolean] +true+ if the record is valid.
@@ -63,6 +67,23 @@ class ActiveCabinet
63
67
  true
64
68
  end
65
69
 
70
+ # @!group Attribute Accessors
71
+
72
+ # Returns the attribute value for the given key.
73
+ #
74
+ # @return [Object] the attribute value.
75
+ def [](key)
76
+ attributes[key]
77
+ end
78
+
79
+ # Sets the attribute value for the given key.
80
+ #
81
+ # @param [Symbol] key the attribute key.
82
+ # @param [Object] value the attribute value.
83
+ def []=(key, value)
84
+ attributes[key] = value
85
+ end
86
+
66
87
  # @!group Dynamic Attribute Accessors
67
88
 
68
89
  # Provides read/write access to {attributes}
@@ -69,18 +69,46 @@ class ActiveCabinet
69
69
  end
70
70
 
71
71
  # Returns an array of records for which the block returns true.
72
+ # When +query+ is provided, it should be a Hash with a single key and
73
+ # value. The result will be records that have a matching attribute.
74
+ #
75
+ # @example Search using a Hash query
76
+ # Song.where artist: "Iron Maiden"
77
+ #
78
+ # @example Search using a block
79
+ # Song.where { |record| record[:artist] == "Iron Maiden" }
72
80
  #
73
81
  # @yieldparam [Object] record all record instances.
74
- def where
75
- all.select { |record| yield record }
82
+ # @return [Array<Object>] record all record instances.
83
+ def where(query = nil)
84
+ if query
85
+ key, value = query.first
86
+ all.select { |record| record[key] == value }
87
+ else
88
+ all.select { |record| yield record }
89
+ end
76
90
  end
77
91
 
78
92
  # Returns the record matching the +id+.
93
+ # When providing a Hash with a single key-value pair, it will return the
94
+ # first matching object from the respective {where} query.
95
+ #
96
+ # @example Retrieve a record by ID
97
+ # Song.find 1
98
+ # Song[1]
99
+ #
100
+ # @example Retrieve a different attributes
101
+ # Song.find artist: "Iron Maiden"
102
+ # Song[artist: "Iron Maiden"]
79
103
  #
80
104
  # @return [Object, nil] the object if found, or +nil+.
81
105
  def find(id)
82
- attributes = cabinet[id]
83
- attributes ? new(attributes) : nil
106
+ if id.is_a? Hash
107
+ where(id).first
108
+ else
109
+ attributes = cabinet[id]
110
+ attributes ? new(attributes) : nil
111
+ end
84
112
  end
85
113
  alias [] find
86
114
 
@@ -101,11 +129,13 @@ class ActiveCabinet
101
129
 
102
130
  # @!group Attribute Management
103
131
 
104
- # Returns an array containing {required_attributes} and {optional_attributes}.
132
+ # Returns an array containing the keys of all allowed attributes as
133
+ # defined by {required_attributes}, {optional_attributes} and
134
+ # {default_attributes}.
105
135
  #
106
136
  # @return [Array<Symbol>] array of required attribute keys.
107
137
  def allowed_attributes
108
- (optional_attributes || []) + required_attributes
138
+ (optional_attributes || []) + required_attributes + default_attributes.keys
109
139
  end
110
140
 
111
141
  # Sets the required record attribute names.
@@ -138,6 +168,18 @@ class ActiveCabinet
138
168
  end
139
169
  end
140
170
 
171
+ # Sets the default record attribute values.
172
+ #
173
+ # @param [Hash<Symbol, Object>] **attributes one or more attribute names and values.
174
+ # @return [Hash<Symbol, Object>] the hash of the default attributes.
175
+ def default_attributes(args = nil)
176
+ if args
177
+ @default_attributes = args
178
+ else
179
+ @default_attributes ||= {}
180
+ end
181
+ end
182
+
141
183
  # @!group Utilities
142
184
 
143
185
  # Returns all records as a hash, with record IDs as the keys.
@@ -1,3 +1,3 @@
1
1
  class ActiveCabinet
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_cabinet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-08 00:00:00.000000000 Z
11
+ date: 2020-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hash_cabinet