active_cabinet 0.1.0 → 0.2.3

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: 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