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 +4 -4
- data/README.md +39 -11
- data/lib/active_cabinet.rb +23 -2
- data/lib/active_cabinet/metaclass.rb +79 -7
- data/lib/active_cabinet/version.rb +1 -1
- metadata +13 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0e758ab665623b4914ee47333fc31eed359da51fe9b1739c221fec4ed76a5c7
|
4
|
+
data.tar.gz: 4c41f042136643bc66014e4c55b7276c8cdeb1ecffebbe021ab34b9ea70e8d61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
+
[](https://badge.fury.io/rb/active_cabinet)
|
5
|
+
[](https://github.com/DannyBen/active_cabinet/actions?query=workflow%3ATest)
|
6
|
+
[](https://codeclimate.com/github/DannyBen/active_cabinet/maintainability)
|
7
|
+
|
4
8
|
---
|
5
9
|
|
6
|
-
|
7
|
-
file-
|
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
|
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
|
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
|
-
|
150
|
+
## Documentation
|
129
151
|
|
152
|
+
[Documentation on RubyDoc][docs]
|
130
153
|
|
131
|
-
|
132
|
-
|
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
|
data/lib/active_cabinet.rb
CHANGED
@@ -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
|
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
|
-
|
75
|
-
|
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
|
-
|
83
|
-
|
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
|
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.
|
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.
|
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-
|
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.
|
67
|
+
rubygems_version: 3.2.3
|
59
68
|
signing_key:
|
60
69
|
specification_version: 4
|
61
70
|
summary: Database-like interface for HashCabinet
|