geode 0.1.0 → 0.5.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: e9d2e925a8364400b6115a4223c5856f12e2c24b56f1ef8bf1720e4d00e1e4c9
4
- data.tar.gz: 8d6419d449bb81d08ea6eead65910120ec0e157d925b046847e8b191a4adf084
3
+ metadata.gz: 40101d539252b136e868fd1a800b063480f900d2d6950fdb49692b9b46f2d840
4
+ data.tar.gz: c5169f3c0240530b10c7ecf479dec602d6ac4c1edfffb85fa93ba3713a97a6ed
5
5
  SHA512:
6
- metadata.gz: 851f343021aa0a78e16cda8669ccacba8b40a608504352d59e87985287882da06b376de9fd99c918e89d4a0c30ecb61e9c7718a1ceb7ce340721886ba75f5a09
7
- data.tar.gz: 62ab42620321c4e6c5c9c88a422d411732b31b6d01dad4cf9e1415338ad192da2e6870aa2f4826d73c566f3b063082feb42338d4288eb9ca1a47ce8c22024b3c
6
+ metadata.gz: d92a44091dd02cf1c9a406cf642dc6e906b40177d07081b2f898c0a0c3153d2e43850c4391900f4bc8dcd9294c4f9e7c71306c2467ad5a60a0f84855deeee328
7
+ data.tar.gz: a44edfb5d28948066504fa7d65bf9c331a7b6dc2abb19001a96a9bfcb329a48218412262bbf4fb539a01934d0dbcec7b0392421236ab87666e8fe9146bd977f4
@@ -0,0 +1,35 @@
1
+ require 'redis'
2
+
3
+ require_relative '../geode'
4
+
5
+ module Geode
6
+ # A store implemented using Redis.
7
+ class RedisStore < Store
8
+ # Connect to a store held in Redis.
9
+ # @param name [Symbol, String] The name of the store
10
+ # @param connection [Hash, String] Connection parameters passed to `Redis.new`.
11
+ # Defaults to empty hash
12
+ def initialize(name, connection = nil)
13
+ super
14
+ connection ||= {}
15
+ @redis = Redis.new(connection)
16
+ end
17
+
18
+ def open
19
+ table = if @redis.exists? @name
20
+ Marshal.load(@redis.get @name)
21
+ else
22
+ {}
23
+ end
24
+
25
+ (yield table).tap do
26
+ @redis.set @name, Marshal.dump(table)
27
+ end
28
+ end
29
+
30
+ def destroy
31
+ @redis.del @name
32
+ nil
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,48 @@
1
+ require 'sequel'
2
+
3
+ require_relative '../geode'
4
+
5
+ module Geode
6
+ # A store that uses a relational database supported by Sequel instead of Redis.
7
+ # This is mainly useful for Heroku, where persistent Postgres is free, but
8
+ # the same is not true of Redis.
9
+ # Unless you have a similarly good reason to use this class, use `RedisStore` instead.
10
+ class SequelStore < Store
11
+ # Connect to a store held in a relational database supported by Sequel.
12
+ # A table named `geode` will be created and used to store the data.
13
+ # @param name [Symbol, String] The name of the store
14
+ # @param connection [Hash, String] Connection parameters passed to `Sequel.connect`.
15
+ # Defaults to `{ adapter: 'postgres' }`
16
+ def initialize(name, connection = nil)
17
+ super
18
+
19
+ connection ||= { adapter: 'postgres' }
20
+ db = Sequel.connect(connection)
21
+ db.create_table? :geode do
22
+ String :name, primary_key: true
23
+ File :value
24
+ end
25
+
26
+ @db = db[:geode]
27
+ end
28
+
29
+ def open
30
+ store = @db.where(name: @name)
31
+ table = if store.empty?
32
+ store.insert(name: @name, value: '')
33
+ {}
34
+ else
35
+ Marshal.load(store.first[:value])
36
+ end
37
+
38
+ (yield table).tap do
39
+ store.update(value: Sequel.blob(Marshal.dump(table)))
40
+ end
41
+ end
42
+
43
+ def destroy
44
+ @db.where(name: @name).delete
45
+ nil
46
+ end
47
+ end
48
+ end
data/lib/geode.rb CHANGED
@@ -1,57 +1,54 @@
1
- # frozen_string_literal: true
2
-
3
- require 'redis'
4
-
5
- require 'sequel'
6
-
7
1
  module Geode
8
- class RedisStore
9
- def initialize(name)
10
- @name = name
11
- @redis = Redis.new
2
+ # Subclass this to implement your own stores.
3
+ class Store
4
+ # Connect to a store.
5
+ # @param name [Symbol, String] The name of the store
6
+ # @param connection [Hash, String] Connection parameters passed to the DB client
7
+ def initialize(name, connection = nil)
8
+ @name = name.to_s
12
9
  end
13
10
 
14
11
  # "Open" the store for reading and/or writing.
15
- # Returns the result of the block.
12
+ # @yield a block which receives `table` as its sole parameter
13
+ # @yieldparam table [Hash] The store's table. Changes to this Hash will
14
+ # be persisted in the store
15
+ # When in doubt, use this method.
16
+ # @example
17
+ # "store.open { |table| table[:key] = 5 }"
18
+ # @example
19
+ # "store.open { |table| table[:key] } #=> 5"
20
+ # @return [Object] The return value of the block
16
21
  def open
17
- table = if @redis.exists? @name
18
- Marshal.load(@redis.get @name)
19
- else
20
- {}
21
- end
22
-
23
- (yield table).tap do
24
- @redis.set(@name, Marshal.dump(table))
25
- end
22
+ raise 'subclasses must implement #open'
26
23
  end
27
- end
28
-
29
- class PostgresStore
30
- def initialize(name, connection=nil)
31
- @name = name
32
- @db = connection.nil? ? Sequel.postgres : Sequel.connect(connection)
33
- @db.create_table? :geode do
34
- primary_key :id
35
- String :name
36
- File :value
37
- end
38
24
 
25
+ # "Peek" inside the store, returning a copy of its table.
26
+ # Changes to this copy will NOT be persisted in the store.
27
+ # Use this if you simply want to view the store's table.
28
+ # @example
29
+ # "store.peek.key?(:test) #=> false"
30
+ # @return [Hash] A copy of the store's table
31
+ def peek
32
+ open(&:itself)
39
33
  end
40
34
 
41
- def open
42
- geode = @db[:geode]
43
- store = geode.where(name: @name)
44
- table = if store.first.nil?
45
- store.insert(name: @name, value: '')
46
- {}
47
- else
48
- Marshal.load(store.first[:value])
49
- end
35
+ # Retrieve the object at `key` from the store.
36
+ # This is implemented using `#peek` and therefore
37
+ # changes to the object returned by this method will NOT
38
+ # be persisted in the store.
39
+ # Use this if you simply need to fetch a value from the store.
40
+ # @example
41
+ # "store[:key] #=> 5"
42
+ # @param key [Object] The key to look up
43
+ # @return [Object] The object at `key`
44
+ def [](key)
45
+ peek[key]
46
+ end
50
47
 
51
- (yield table).tap do
52
- dumped = Marshal.dump(table)
53
- store.update(value: Sequel.blob(dumped))
54
- end
48
+ # "Destroy" the store, deleting all data.
49
+ # The store can be opened again, recreating it in a blank state.
50
+ def destroy
51
+ raise 'subclasses must implement #destroy'
55
52
  end
56
53
  end
57
54
  end
metadata CHANGED
@@ -1,65 +1,66 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geode
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - biqqles
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-14 00:00:00.000000000 Z
11
+ date: 2021-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: redis
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '4.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '4.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: sequel
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '5.0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '5.0'
55
55
  description:
56
- email:
57
- - biqqles@protonmail.com
56
+ email: biqqles@protonmail.com
58
57
  executables: []
59
58
  extensions: []
60
59
  extra_rdoc_files: []
61
60
  files:
62
61
  - lib/geode.rb
62
+ - lib/geode/redis.rb
63
+ - lib/geode/sequel.rb
63
64
  homepage: https://github.com/biqqles/geode
64
65
  licenses:
65
66
  - MPL-2.0
@@ -75,7 +76,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
75
76
  requirements:
76
77
  - - ">="
77
78
  - !ruby/object:Gem::Version
78
- version: 2.4.0
79
+ version: 2.2.0
79
80
  required_rubygems_version: !ruby/object:Gem::Requirement
80
81
  requirements:
81
82
  - - ">="
@@ -85,5 +86,5 @@ requirements: []
85
86
  rubygems_version: 3.1.2
86
87
  signing_key:
87
88
  specification_version: 4
88
- summary: A simple hierarchical key-store for Ruby
89
+ summary: Store Ruby objects in Redis or Sequel
89
90
  test_files: []