basket 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +10 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +14 -13
- data/README.md +56 -0
- data/SECURITY.md +16 -0
- data/lib/basket/backend_adapter/memory_backend.rb +11 -0
- data/lib/basket/backend_adapter/redis_backend.rb +12 -1
- data/lib/basket/element.rb +38 -0
- data/lib/basket/error.rb +4 -0
- data/lib/basket/queue_collection.rb +31 -2
- data/lib/basket/version.rb +1 -1
- data/lib/basket.rb +15 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ac7e6fe22a043a420bf43a2dddcf0a9eee9f9fc647624e6aeecadb0f6ffb0e6
|
4
|
+
data.tar.gz: 043aa8c1033f8b58cf28ca41609397eb7872846ef139e9fb10654700ef61cefc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8075bdd1180e9a58b5debec7a9925b1b1a08c1fdec6935e36fba4f1442cb6372c21b5d4ea02215a78a5710d87787c4cfe826ed2f8a0cd0328f25bdab08f93b52
|
7
|
+
data.tar.gz: a91e1571c99a3a20432186464eaeb4f57068cda33aeddbc912b5e358c83106a11c698fa902e20b1c4dc2809558d1d650381982d61464c900750caf15380c44ab
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# Contributing to Basket
|
2
|
+
|
3
|
+
This is a small project. We welcome ideas, contributions, thoughts, issues, bug reports, questions and any other thing you might like to add.
|
4
|
+
|
5
|
+
If you do want to add something, open and issue and we will respond! Our current list of issues is sort of short hand between to the two authors, but we'd be happy to clarify anything if you are so interested.
|
6
|
+
|
7
|
+
We use `standardrb` for linting.
|
8
|
+
We use `rspec`.
|
9
|
+
|
10
|
+
If this is your first contribution to any open source project, we'd be happy to help you get something merged! If you have an idea or question and are new to Ruby, we would love to help you!
|
data/Gemfile
CHANGED
@@ -5,6 +5,7 @@ source "https://rubygems.org"
|
|
5
5
|
# Specify your gem's dependencies in basket.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
+
gem "pry"
|
8
9
|
gem "guard"
|
9
10
|
gem "guard-rspec", require: false
|
10
11
|
gem "guard-standardrb", require: false
|
@@ -13,4 +14,4 @@ gem "rake", "~> 13.0"
|
|
13
14
|
gem "rspec", "~> 3.0"
|
14
15
|
gem "simplecov", require: false, group: :test
|
15
16
|
gem "simplecov-json", require: false, group: :test
|
16
|
-
gem "standard", "~> 1.
|
17
|
+
gem "standard", "~> 1.27"
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
basket (0.0.
|
4
|
+
basket (0.0.7)
|
5
5
|
redis
|
6
6
|
redis-namespace
|
7
7
|
|
@@ -47,8 +47,8 @@ GEM
|
|
47
47
|
notiffany (0.1.3)
|
48
48
|
nenv (~> 0.1)
|
49
49
|
shellany (~> 0.0)
|
50
|
-
parallel (1.
|
51
|
-
parser (3.2.
|
50
|
+
parallel (1.23.0)
|
51
|
+
parser (3.2.2.0)
|
52
52
|
ast (~> 2.4.1)
|
53
53
|
pry (0.14.2)
|
54
54
|
coderay (~> 1.1)
|
@@ -64,7 +64,7 @@ GEM
|
|
64
64
|
connection_pool
|
65
65
|
redis-namespace (1.10.0)
|
66
66
|
redis (>= 4)
|
67
|
-
regexp_parser (2.
|
67
|
+
regexp_parser (2.8.0)
|
68
68
|
rexml (3.2.5)
|
69
69
|
rspec (3.12.0)
|
70
70
|
rspec-core (~> 3.12.0)
|
@@ -79,22 +79,22 @@ GEM
|
|
79
79
|
diff-lcs (>= 1.2.0, < 2.0)
|
80
80
|
rspec-support (~> 3.12.0)
|
81
81
|
rspec-support (3.12.0)
|
82
|
-
rubocop (1.
|
82
|
+
rubocop (1.50.2)
|
83
83
|
json (~> 2.3)
|
84
84
|
parallel (~> 1.10)
|
85
85
|
parser (>= 3.2.0.0)
|
86
86
|
rainbow (>= 2.2.2, < 4.0)
|
87
87
|
regexp_parser (>= 1.8, < 3.0)
|
88
88
|
rexml (>= 3.2.5, < 4.0)
|
89
|
-
rubocop-ast (>= 1.
|
89
|
+
rubocop-ast (>= 1.28.0, < 2.0)
|
90
90
|
ruby-progressbar (~> 1.7)
|
91
91
|
unicode-display_width (>= 2.4.0, < 3.0)
|
92
|
-
rubocop-ast (1.
|
92
|
+
rubocop-ast (1.28.0)
|
93
93
|
parser (>= 3.2.1.0)
|
94
|
-
rubocop-performance (1.
|
94
|
+
rubocop-performance (1.16.0)
|
95
95
|
rubocop (>= 1.7.0, < 2.0)
|
96
96
|
rubocop-ast (>= 0.4.0)
|
97
|
-
ruby-progressbar (1.
|
97
|
+
ruby-progressbar (1.13.0)
|
98
98
|
ruby2_keywords (0.0.5)
|
99
99
|
shellany (0.0.1)
|
100
100
|
simplecov (0.22.0)
|
@@ -106,10 +106,10 @@ GEM
|
|
106
106
|
json
|
107
107
|
simplecov
|
108
108
|
simplecov_json_formatter (0.1.4)
|
109
|
-
standard (1.
|
109
|
+
standard (1.27.0)
|
110
110
|
language_server-protocol (~> 3.17.0.2)
|
111
|
-
rubocop (
|
112
|
-
rubocop-performance (
|
111
|
+
rubocop (~> 1.50.2)
|
112
|
+
rubocop-performance (~> 1.16.0)
|
113
113
|
standardrb (1.0.1)
|
114
114
|
standard
|
115
115
|
thor (1.2.1)
|
@@ -128,11 +128,12 @@ DEPENDENCIES
|
|
128
128
|
guard-standardrb
|
129
129
|
mock_redis
|
130
130
|
mocktail
|
131
|
+
pry
|
131
132
|
rake (~> 13.0)
|
132
133
|
rspec (~> 3.0)
|
133
134
|
simplecov
|
134
135
|
simplecov-json
|
135
|
-
standard (~> 1.
|
136
|
+
standard (~> 1.27)
|
136
137
|
|
137
138
|
BUNDLED WITH
|
138
139
|
2.4.6
|
data/README.md
CHANGED
@@ -22,6 +22,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
22
22
|
$ gem install basket
|
23
23
|
|
24
24
|
## Usage
|
25
|
+
### Adding
|
25
26
|
|
26
27
|
Add items to your basket as they come along. They might come along quickly, or there might be a delay between them. Regardless, you want to collect items into your basket before going and doing something with them.
|
27
28
|
|
@@ -34,6 +35,10 @@ end
|
|
34
35
|
|
35
36
|
The item added to the basket can be any data you want! If you are using the in memory Queue, it is fine to store Ruby objects, but if you have a different backend, must be JSON serializable via `to_json`.
|
36
37
|
|
38
|
+
### Your basket
|
39
|
+
|
40
|
+
When a basket has become full after you have added a bunch of things to it, it performs actions! See below for the full definition of a basket.
|
41
|
+
|
37
42
|
```ruby
|
38
43
|
class QuicheBasket
|
39
44
|
# Include the Basket::Batcher
|
@@ -84,6 +89,51 @@ The `on_failure` use of `batch` of course may not have a full batch as the error
|
|
84
89
|
|
85
90
|
Defining `on_add`, `on_failure`, and `on_success` is optional.
|
86
91
|
|
92
|
+
### Search
|
93
|
+
|
94
|
+
You may search through your basket, if for example, you need to see if you've accidentally collected a robin egg and not a chicken egg!
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
search_results = Basket.search("QuicheBasket") do |egg|
|
98
|
+
egg.color == "blue"
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
The block you pass will match against the objects in your basket. If you have ruby objects in your basket, you can match against their properties just as if you were accessing them one at a time. If you have json objects in your basket, you will be searching through a hash thusly:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
search_results = Basket.search("PlaylistBasket") do |song|
|
106
|
+
song[:artist] == "Vansire"
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
The search results will be a fully qualified basket element which will contain an id attribute and a data attribute. In the case of using the MemoryBackend, you might see something like this:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
# ...continued from above
|
114
|
+
search_results.first #=> #<Basket::Element:0x00000001075d9c80
|
115
|
+
# @data=#<Egg color="blue", size="smol">
|
116
|
+
# @id="5fe3df9e-4063-4b67-a08f-e36b847087c7">
|
117
|
+
```
|
118
|
+
|
119
|
+
You'll note that the result of a search is an array of basket elements. An element consists of the data that you put in and ID. What is the id for? Glad you asked.
|
120
|
+
|
121
|
+
### Remove
|
122
|
+
|
123
|
+
You can also remove something from your basket. Perhaps it is deleted in the database and no longer contains a valid reference to data? Perhaps you found that robin egg and don't actually want to use it to make a quiche, because who would? Either way, removing the element is easy!
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
# ...continued from above
|
127
|
+
element_id_to_remove = search_results.first
|
128
|
+
removed_egg = Basket.remove('Quiche', element_id_to_remove)
|
129
|
+
removed_egg #=> #<Egg color="blue", size="smol">
|
130
|
+
```
|
131
|
+
|
132
|
+
Voila!
|
133
|
+
|
134
|
+
### A Note of Warning
|
135
|
+
|
136
|
+
Searching for and removing elements from your basket is an inherently tricky process as your basket may fill up and execute the `perform` action while searching and removing.
|
87
137
|
## Configuration
|
88
138
|
|
89
139
|
In an initializer, or somewhere equally appropriate, you might put something like this:
|
@@ -132,5 +182,11 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
132
182
|
|
133
183
|
Everyone interacting in the Basket project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/nicholalexander/basket/blob/main/CODE_OF_CONDUCT.md).
|
134
184
|
|
185
|
+
## Thanks
|
186
|
+
|
187
|
+
This project has been a fun and educational use of Growth Time at [Test Double](https://testdouble.com/) where consultants are given 4hrs per week to grow their skills and work on projects that further the mission of building software, better.
|
135
188
|
|
189
|
+
## Authors
|
136
190
|
|
191
|
+
* [Nichol Alexander](https://github.com/nicholalexander/)
|
192
|
+
* [Alec Clarke](https://github.com/alecclarke)
|
data/SECURITY.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Security Policy
|
2
|
+
|
3
|
+
## Supported Versions
|
4
|
+
|
5
|
+
We support Ruby versions as below:
|
6
|
+
|
7
|
+
| Version | Supported |
|
8
|
+
| ------- | ------------------ |
|
9
|
+
| 3.2.2 | :white_check_mark: |
|
10
|
+
| 3.1.4 | :white_check_mark: |
|
11
|
+
| 3.0.6 | :white_check_mark: |
|
12
|
+
| < 4.0 | :x: |
|
13
|
+
|
14
|
+
## Reporting a Vulnerability
|
15
|
+
|
16
|
+
If you discover a security related bug, please don't file an issue for it and instead let us know directly!
|
@@ -22,6 +22,17 @@ module Basket
|
|
22
22
|
@data[queue]
|
23
23
|
end
|
24
24
|
|
25
|
+
def search(queue, &block)
|
26
|
+
@data[queue].select { |element| block.call(element.data) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove(queue, id)
|
30
|
+
index_of_element_to_delete = @data[queue].index { |element| element.id == id }
|
31
|
+
@data[queue].delete_at(index_of_element_to_delete)
|
32
|
+
rescue
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
|
25
36
|
def clear(queue)
|
26
37
|
@data[queue] = []
|
27
38
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require "redis-namespace"
|
2
|
-
require "json"
|
3
2
|
|
4
3
|
module Basket
|
5
4
|
class BackendAdapter
|
@@ -25,6 +24,18 @@ module Basket
|
|
25
24
|
response
|
26
25
|
end
|
27
26
|
|
27
|
+
def search(queue, &block)
|
28
|
+
deserialized_queue_data(queue).select { |raw_element| block.call(raw_element["data"]) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def remove(queue, element_id)
|
32
|
+
element = deserialized_queue_data(queue).find { |raw_element| raw_element["id"] == element_id }
|
33
|
+
|
34
|
+
@client.lrem(queue, 1, element.to_json)
|
35
|
+
|
36
|
+
element
|
37
|
+
end
|
38
|
+
|
28
39
|
def push(queue, data)
|
29
40
|
@client.lpush(queue, serialize_data(data))
|
30
41
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "securerandom"
|
2
|
+
|
3
|
+
module Basket
|
4
|
+
class Element
|
5
|
+
class InvalidElement < StandardError; end
|
6
|
+
|
7
|
+
attr_reader :data, :id
|
8
|
+
|
9
|
+
def self.from_queue(element)
|
10
|
+
if element.is_a?(Element)
|
11
|
+
element
|
12
|
+
elsif element.is_a?(Hash)
|
13
|
+
new(element["data"], element["id"])
|
14
|
+
else
|
15
|
+
raise InvalidElement, "element must be a hash or a Basket::Element"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(data, id = SecureRandom.uuid)
|
20
|
+
raise InvalidElement, "both data and id must be present" unless data && id
|
21
|
+
|
22
|
+
@data = data
|
23
|
+
@id = id
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_h
|
27
|
+
{data: data, id: id}
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_json(*)
|
31
|
+
to_h.to_json
|
32
|
+
end
|
33
|
+
|
34
|
+
def ==(other)
|
35
|
+
to_h == other.to_h
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/basket/error.rb
CHANGED
@@ -5,7 +5,7 @@ module Basket
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def push(queue, data)
|
8
|
-
@backend.push(queue, data)
|
8
|
+
@backend.push(queue, Element.new(data))
|
9
9
|
length(queue)
|
10
10
|
end
|
11
11
|
|
@@ -14,7 +14,22 @@ module Basket
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def read(queue)
|
17
|
-
|
17
|
+
check_for_basket(queue)
|
18
|
+
raw_queue = @backend.read(queue)
|
19
|
+
raw_queue.map { |element| Element.from_queue(element).data }
|
20
|
+
end
|
21
|
+
|
22
|
+
def search(queue, query)
|
23
|
+
check_for_basket(queue)
|
24
|
+
check_for_zero_length(queue)
|
25
|
+
raw_search_results = @backend.search(queue, &query)
|
26
|
+
raw_search_results.map { |raw_search_result| Element.from_queue(raw_search_result) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove(queue, id)
|
30
|
+
raw_removed_element = @backend.remove(queue, id)
|
31
|
+
check_for_raw_removed_element(raw_removed_element)
|
32
|
+
Element.from_queue(raw_removed_element).data
|
18
33
|
end
|
19
34
|
|
20
35
|
def clear(queue)
|
@@ -28,5 +43,19 @@ module Basket
|
|
28
43
|
def reset_backend
|
29
44
|
@backend = Basket.config.backend.new
|
30
45
|
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def check_for_basket(queue)
|
50
|
+
raise Basket::BasketNotFoundError unless Object.const_defined?(queue)
|
51
|
+
end
|
52
|
+
|
53
|
+
def check_for_zero_length(queue)
|
54
|
+
raise Basket::EmptyBasketError, "The basket #{queue} is empty." if length(queue).zero?
|
55
|
+
end
|
56
|
+
|
57
|
+
def check_for_raw_removed_element(raw_removed_element)
|
58
|
+
raise Basket::ElementNotFoundError if raw_removed_element.nil?
|
59
|
+
end
|
31
60
|
end
|
32
61
|
end
|
data/lib/basket/version.rb
CHANGED
data/lib/basket.rb
CHANGED
@@ -5,11 +5,14 @@ require_relative "basket/backend_adapter/memory_backend"
|
|
5
5
|
require_relative "basket/backend_adapter/redis_backend"
|
6
6
|
require_relative "basket/batcher"
|
7
7
|
require_relative "basket/configuration"
|
8
|
+
require_relative "basket/element"
|
8
9
|
require_relative "basket/error"
|
9
10
|
require_relative "basket/handle_add"
|
10
11
|
require_relative "basket/queue_collection"
|
11
12
|
require_relative "basket/version"
|
12
13
|
|
14
|
+
require "json"
|
15
|
+
|
13
16
|
module Basket
|
14
17
|
class Error < StandardError; end
|
15
18
|
|
@@ -25,6 +28,10 @@ module Basket
|
|
25
28
|
@queue_collection.data
|
26
29
|
end
|
27
30
|
|
31
|
+
def self.peek(queue)
|
32
|
+
queue_collection.read(queue)
|
33
|
+
end
|
34
|
+
|
28
35
|
def self.queue_collection
|
29
36
|
@queue_collection ||= Basket::QueueCollection.new
|
30
37
|
end
|
@@ -33,6 +40,14 @@ module Basket
|
|
33
40
|
HandleAdd.call(queue, data)
|
34
41
|
end
|
35
42
|
|
43
|
+
def self.search(queue, &query)
|
44
|
+
queue_collection.search(queue, query)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.remove(queue, id)
|
48
|
+
queue_collection.remove(queue, id)
|
49
|
+
end
|
50
|
+
|
36
51
|
def self.clear_all
|
37
52
|
queue_collection.reset_backend
|
38
53
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: basket
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nichol alexander
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-04-
|
12
|
+
date: 2023-04-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
@@ -66,12 +66,14 @@ files:
|
|
66
66
|
- ".standard.yml"
|
67
67
|
- CHANGELOG.md
|
68
68
|
- CODE_OF_CONDUCT.md
|
69
|
+
- CONTRIBUTING.md
|
69
70
|
- Gemfile
|
70
71
|
- Gemfile.lock
|
71
72
|
- Guardfile
|
72
73
|
- LICENSE.txt
|
73
74
|
- README.md
|
74
75
|
- Rakefile
|
76
|
+
- SECURITY.md
|
75
77
|
- basket.gemspec
|
76
78
|
- lib/basket.rb
|
77
79
|
- lib/basket/backend_adapter.rb
|
@@ -79,6 +81,7 @@ files:
|
|
79
81
|
- lib/basket/backend_adapter/redis_backend.rb
|
80
82
|
- lib/basket/batcher.rb
|
81
83
|
- lib/basket/configuration.rb
|
84
|
+
- lib/basket/element.rb
|
82
85
|
- lib/basket/error.rb
|
83
86
|
- lib/basket/handle_add.rb
|
84
87
|
- lib/basket/queue_collection.rb
|