active_cabinet 0.1.0 → 0.2.3

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
  SHA256:
3
- metadata.gz: 774c19d270fc5767611ad0b42eaa06f7b98c3bae2bdfa2e4f8f0e382629daf59
4
- data.tar.gz: 4d48778ba0cd2294b047d0292c87e963c4c16823a1effe6f93a207afeb182713
3
+ metadata.gz: c0e758ab665623b4914ee47333fc31eed359da51fe9b1739c221fec4ed76a5c7
4
+ data.tar.gz: 4c41f042136643bc66014e4c55b7276c8cdeb1ecffebbe021ab34b9ea70e8d61
5
5
  SHA512:
6
- metadata.gz: 9e9e84e8ae733967cee88489b45020c68609ef67172d5a0c8b9e3540d946d8a0a9d32e139362f95a3d0aa3f545c1a612c1993f3a4327f67559506d98c3ab8620
7
- data.tar.gz: 3a9a02b9f0c0df27479db9ba4f6ae8c6e17cd3f10caad24fe00e669c7402f19b3dddc4461553d25e9b7cf61588b4bf668cf9b194bbf3cce27a319de7c2bb297f
6
+ metadata.gz: e294347a1f3dfa3148c93220734eaacb8d800a42a53f0c1cf15e6e5c41628cb643d087672c7a29944a1364bdd5aaec6bed7b9f1e612f70ffd93322643672600a
7
+ data.tar.gz: '0492f1da68709b7c72a8f329b049fa53a24a2ae44639d34594cc72471ae9df478a3713574a0980bcbfc4b8672a765cdcb5714b1b65c1b18c44aa2375a3f4ae4a'
data/README.md CHANGED
@@ -1,14 +1,20 @@
1
1
  ActiveCabinet
2
2
  ==================================================
3
3
 
4
+ [![Gem Version](https://badge.fury.io/rb/active_cabinet.svg)](https://badge.fury.io/rb/active_cabinet)
5
+ [![Build Status](https://github.com/DannyBen/active_cabinet/workflows/Test/badge.svg)](https://github.com/DannyBen/active_cabinet/actions?query=workflow%3ATest)
6
+ [![Maintainability](https://api.codeclimate.com/v1/badges/a4302349baf2d20e2af8/maintainability)](https://codeclimate.com/github/DannyBen/active_cabinet/maintainability)
7
+
4
8
  ---
5
9
 
6
- ActiveCabinet is an ActiveRecord-inspired interface for HashCabinet, the
7
- file-basd key-object store.
10
+ An ActiveRecord-inspired interface for [HashCabinet], the
11
+ file-based key-object store.
8
12
 
9
13
  It allows you to create models that are stored in a file-based key-value
10
14
  store, backed by Ruby's built in [SDBM].
11
15
 
16
+ ActiveCabinet is a tiny library, with only [HashCabinet] as a dependency.
17
+
12
18
  ---
13
19
 
14
20
  Installation
@@ -61,8 +67,8 @@ song.update! year: 1988, artist: 'Metallica' # this variant also saves
61
67
 
62
68
  ### Restricting / allowing certain attributes
63
69
 
64
- You may specify required arguments. Records without these attributes will
65
- 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.
66
72
 
67
73
  ```ruby
68
74
  class Song < ActiveCabinet
@@ -83,7 +89,7 @@ song.valid? # => true
83
89
 
84
90
  You can also restrict the allowed optional attributes
85
91
 
86
- ```
92
+ ```ruby
87
93
  class Song < ActiveCabinet
88
94
  required_attributes :title
89
95
  optional_attributes :artist
@@ -108,15 +114,31 @@ song.valid? # => false
108
114
  song.error # => "invalid attributes: [:artist]"
109
115
  ```
110
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
+
111
133
  ### Configuring storage path
112
134
 
113
135
  By default, `ActiveCabinet` stores all its files (two files per model) in the
114
136
  `./db` directory. The file name is determined by the name of the class.
115
137
 
116
- You can override both of these values
138
+ You can override both of these values:
117
139
 
118
140
  ```ruby
119
- # Set the based directory for all cabinets
141
+ # Set the base directory for all cabinets
120
142
  ActiveCabinet::Config.dir = "cabinets"
121
143
 
122
144
  # Set the filename of your model
@@ -125,12 +147,18 @@ class Song < ActiveCabinet
125
147
  end
126
148
  ```
127
149
 
128
- For the full documentation, see the [Documentation on RubyDoc][docs]
150
+ ## Documentation
129
151
 
152
+ [Documentation on RubyDoc][docs]
130
153
 
131
- [SDBM]: https://ruby-doc.org/stdlib-2.6.3/libdoc/sdbm/rdoc/SDBM.html
132
- [docs]: https://rubydoc.info/gems/active_cabinet
154
+ ## Contributing / Support
155
+
156
+ If you experience any issue, have a question or a suggestion, or if you wish
157
+ to contribute, feel free to [open an issue][issues].
133
158
 
134
159
  ---
135
160
 
136
- [SDBM]: https://ruby-doc.org/stdlib-2.7.1/libdoc/sdbm/rdoc/SDBM.html
161
+ [SDBM]: https://ruby-doc.org/stdlib-2.7.1/libdoc/sdbm/rdoc/SDBM.html
162
+ [docs]: https://rubydoc.info/gems/active_cabinet
163
+ [issues]: https://github.com/DannyBen/active_cabinet/issues
164
+ [HashCabinet]: https://github.com/DannyBen/hash_cabinet
@@ -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}
@@ -138,7 +159,7 @@ class ActiveCabinet
138
159
  #
139
160
  # @param [Hash] new_attributes record attributes
140
161
  def update(new_attributes)
141
- @attributes = attributes.merge new_attributes
162
+ @attributes = attributes.merge(new_attributes.transform_keys &:to_sym)
142
163
  end
143
164
 
144
165
  # Update the record with new or modified attributes, and save.
@@ -69,24 +69,82 @@ 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
 
115
+ # Yields each record to the given block.
116
+ #
117
+ # @yieldparam [Object] record all record instances.
118
+ def each
119
+ cabinet.each_value do |attributes|
120
+ yield new(attributes)
121
+ end
122
+ end
123
+
124
+ # Returns the first record.
125
+ #
126
+ # @return [Object] the record.
127
+ def first
128
+ find keys.first
129
+ end
130
+
131
+ # Returns the last record.
132
+ #
133
+ # @return [Object] the record.
134
+ def last
135
+ find keys.last
136
+ end
137
+
138
+ # Returns a random racord.
139
+ #
140
+ # @return [Object] the record.
141
+ def random
142
+ find keys.sample
143
+ end
144
+
87
145
  # @!group Deleting Records
88
146
 
89
- # Deletes a record matching the +id+
147
+ # Deletes a record matching the +id+.
90
148
  #
91
149
  # @param [String] id the record ID.
92
150
  # @return [Boolean] +true+ on success, +false+ otherwise.
@@ -101,11 +159,13 @@ class ActiveCabinet
101
159
 
102
160
  # @!group Attribute Management
103
161
 
104
- # Returns an array containing {required_attributes} and {optional_attributes}.
162
+ # Returns an array containing the keys of all allowed attributes as
163
+ # defined by {required_attributes}, {optional_attributes} and
164
+ # {default_attributes}.
105
165
  #
106
166
  # @return [Array<Symbol>] array of required attribute keys.
107
167
  def allowed_attributes
108
- (optional_attributes || []) + required_attributes
168
+ (optional_attributes || []) + required_attributes + default_attributes.keys
109
169
  end
110
170
 
111
171
  # Sets the required record attribute names.
@@ -138,6 +198,18 @@ class ActiveCabinet
138
198
  end
139
199
  end
140
200
 
201
+ # Sets the default record attribute values.
202
+ #
203
+ # @param [Hash<Symbol, Object>] **attributes one or more attribute names and values.
204
+ # @return [Hash<Symbol, Object>] the hash of the default attributes.
205
+ def default_attributes(args = nil)
206
+ if args
207
+ @default_attributes = args
208
+ else
209
+ @default_attributes ||= {}
210
+ end
211
+ end
212
+
141
213
  # @!group Utilities
142
214
 
143
215
  # Returns all records as a hash, with record IDs as the keys.
@@ -1,3 +1,3 @@
1
1
  class ActiveCabinet
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.3"
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.0
4
+ version: 0.2.3
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-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hash_cabinet
@@ -17,6 +17,9 @@ dependencies:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.1'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.1.3
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -24,6 +27,9 @@ dependencies:
24
27
  - - "~>"
25
28
  - !ruby/object:Gem::Version
26
29
  version: '0.1'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.1.3
27
33
  description: ActiveRecord-inspired interface for HashCabinet, the file-basd key-object
28
34
  store.
29
35
  email: db@dannyben.com
@@ -39,7 +45,10 @@ files:
39
45
  homepage: https://github.com/dannyben/active_cabinet
40
46
  licenses:
41
47
  - MIT
42
- metadata: {}
48
+ metadata:
49
+ bug_tracker_uri: https://github.com/DannyBen/active_cabinet/issues
50
+ documentation_uri: https://rubydoc.info/gems/active_cabinet
51
+ source_code_uri: https://github.com/dannyben/active_cabinet
43
52
  post_install_message:
44
53
  rdoc_options: []
45
54
  require_paths:
@@ -55,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
64
  - !ruby/object:Gem::Version
56
65
  version: '0'
57
66
  requirements: []
58
- rubygems_version: 3.1.2
67
+ rubygems_version: 3.2.3
59
68
  signing_key:
60
69
  specification_version: 4
61
70
  summary: Database-like interface for HashCabinet