karma 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 56f3714acf48a27fd7815e001ae0db4d3f0620d88b5d56783d0e30f87ba466de
4
+ data.tar.gz: 60fdd49cd456d5600a82aaa78570987dfc8e6daef337e12611d64b1f3b84ca16
5
+ SHA512:
6
+ metadata.gz: 97227f14c1a966fc6d6668202954eb113938072fd38ac30a618c9da126359528ccf89174fc1f7b7f5abaa3622afef98408b45236e757acb018d5ecbfbfff9564
7
+ data.tar.gz: 85c528d67cbdd9b4e19fcd87f76549ced9d8415e8bd1c3fd366e06fb39ff65cbdb1b0253aa0cc1bd9fb981bab7a0e8e8dbfa7187bd3b766b734a50173489e968
data/.rubocop.yml ADDED
@@ -0,0 +1,13 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.6
3
+
4
+ Style/StringLiterals:
5
+ Enabled: true
6
+ EnforcedStyle: double_quotes
7
+
8
+ Style/StringLiteralsInInterpolation:
9
+ Enabled: true
10
+ EnforcedStyle: double_quotes
11
+
12
+ Layout/LineLength:
13
+ Max: 120
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in karma-rb.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "minitest", "~> 5.0"
11
+
12
+ gem "rubocop", "~> 1.21"
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 creadone
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,113 @@
1
+ # Karma
2
+
3
+ Karma is a ~key-value~ key-counter database, you can find it in a separate [repository](https://github.com/creadone/karma). This repo contains straightforward Ruby client for Karma.
4
+
5
+ ## Installation
6
+
7
+ Install the gem and add to the application's Gemfile by executing:
8
+
9
+ $ bundle add karma
10
+
11
+ If bundler is not being used to manage dependencies, install the gem by executing:
12
+
13
+ $ gem install karma
14
+
15
+ ## Configuration
16
+
17
+ ```Ruby
18
+ require 'karma'
19
+
20
+ Karma.configure do |config|
21
+ config.port = 8080
22
+ config.host = "localhost"
23
+ end
24
+
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ The client supports all possible functionality, which means that Karma can be fully managed by commands. Each command returns an execution status in the `success` attribute and an execution result or an error in the `result` attribute. For example:
30
+
31
+ ```Ruby
32
+ # Deletes an existing tree
33
+ Karma.drop('comments')
34
+
35
+ # success: <OpenStruct success=true, response="OK">
36
+ # error: <OpenStruct success=false, response="Tree \"comments\" not exists">
37
+ ```
38
+
39
+ The control commands allow you to maintain the database:
40
+
41
+ ```Ruby
42
+ # Checks the server
43
+ Karma.ping
44
+
45
+ # Creates new tree "comments" or check if exists
46
+ Karma.create('comments')
47
+
48
+ # Get list of trees in the memory
49
+ Karma.trees
50
+
51
+ # Delete tree "comments"
52
+ Karma.drop('comments')
53
+
54
+ # Get list of all dumps
55
+ Karma.dumps
56
+
57
+ # Dumps tree to the backup directory
58
+ Karma.dump('comments')
59
+
60
+ # Make a backup on FS for each tree in memory
61
+ Karma.dump_all
62
+
63
+ # Load a dump of the tree into memory (existing tree will overwrited)
64
+ Karma.load('1688496993_comments.tree')
65
+ ```
66
+
67
+ The tree commands allow you to work with specific tree:
68
+
69
+ ```Ruby
70
+ # Increment the value in the tree for the key
71
+ Karma.tree('comments').increment(key: 12345)
72
+
73
+ # Increment the value in the tree for the key
74
+ Karma.tree('comments').decrement(key: 12345)
75
+
76
+ # Get total value in the tree for the key
77
+ Karma.tree('comments').sum(key: 12345)
78
+
79
+ # Get total value in the tree for the key between dates
80
+ Karma.tree('comments').sum(key: 12345, time_from: 20230601, time_to: 20230629)
81
+
82
+ # Get hash where key is date and value is total for key between dates
83
+ Karma.tree('comments').find(key: 12345, time_from: 20230601, time_to: 20230629)
84
+
85
+ # Get hash where key is key number and value is total over the tree between dates
86
+ Karma.tree('comments').find(time_from: 20230601, time_to: 20230629)
87
+
88
+ # Delete all values for the key between dates
89
+ Karma.tree('comments').delete(key: 12345, time_from: 20230601, time_to: 20230629)
90
+
91
+ # Delete all values over the tree between dates
92
+ Karma.tree('comments').delete(time_from: 20230601, time_to: 20230629)
93
+
94
+ # Delete all values for the key
95
+ Karma.tree('comments').reset(key: 12345)
96
+
97
+ # Delete all values for the tree
98
+ Karma.tree('comments').reset
99
+ ```
100
+
101
+ ## Development
102
+
103
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
104
+
105
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
106
+
107
+ ## Contributing
108
+
109
+ Bug reports and pull requests are welcome on GitHub at https://github.com/creadone/karmarb.
110
+
111
+ ## License
112
+
113
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << "test"
8
+ t.libs << "lib"
9
+ t.test_files = FileList["test/**/test_*.rb"]
10
+ end
11
+
12
+ require "rubocop/rake_task"
13
+
14
+ RuboCop::RakeTask.new
15
+
16
+ task default: %i[test rubocop]
data/karma.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/karma/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "karma"
7
+ spec.version = Karma::VERSION
8
+ spec.authors = ["Sergey Fedorov"]
9
+ spec.email = ["creadone@gmail.com"]
10
+
11
+ spec.summary = "Ruby client for the Karma key-counter database"
12
+ spec.description = "Ruby client for the Karma key-counter database"
13
+ spec.homepage = "https://github.com/creadone/karma-rb"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 2.6.0"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "https://github.com/creadone/karma-rb"
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(__dir__) do
23
+ `git ls-files -z`.split("\x0").reject do |f|
24
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)})
25
+ end
26
+ end
27
+ spec.bindir = "exe"
28
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ["lib"]
30
+
31
+ # Uncomment to register a new dependency of your gem
32
+ # spec.add_dependency "example-gem", "~> 1.0"
33
+
34
+ # For more information and examples about making a new gem, check out our
35
+ # guide at: https://bundler.io/guides/creating_gem.html
36
+ end
@@ -0,0 +1,18 @@
1
+ module Karma
2
+ Config = Struct.new(:host, :port) do
3
+ def initialize
4
+ self.port = 8080
5
+ self.host = 'localhost'
6
+ end
7
+ end
8
+
9
+ def self.configure
10
+ @config = Config.new
11
+ yield(@config) if block_given?
12
+ @config
13
+ end
14
+
15
+ def self.config
16
+ @config || configure
17
+ end
18
+ end
@@ -0,0 +1,58 @@
1
+ module Karma
2
+ class Connection
3
+ def initialize
4
+ @port = Karma.config.port
5
+ @host = Karma.config.host
6
+ @maxlen = 4096
7
+
8
+ establish_connection!
9
+ end
10
+
11
+ def send_and_read(request)
12
+ send(request)
13
+ read
14
+ end
15
+
16
+ private
17
+
18
+ def connect
19
+ begin
20
+ yield @socket
21
+ rescue => e
22
+ establish_connection!
23
+ retry
24
+ end
25
+ end
26
+
27
+ def send(message)
28
+ message = message.to_json
29
+ connect do |conn|
30
+ conn.send("#{message}\r\n", 0)
31
+ conn.flush
32
+ end
33
+ end
34
+
35
+ def read
36
+ connect do |conn|
37
+ response = conn.recv(@maxlen)
38
+ begin
39
+ OpenStruct.new(JSON.parse(response))
40
+ rescue => e
41
+ return OpenStruct.new({
42
+ "success" => false,
43
+ "response" => e.message
44
+ })
45
+ end
46
+ end
47
+ end
48
+
49
+ def establish_connection!
50
+ @socket = TCPSocket.new(
51
+ @host,
52
+ @port,
53
+ connect_timeout: 0.5
54
+ )
55
+ end
56
+
57
+ end
58
+ end
data/lib/karma/tree.rb ADDED
@@ -0,0 +1,121 @@
1
+ module Karma
2
+ class Tree
3
+ def initialize
4
+ @connection = Connection.new
5
+ @tree_name = nil
6
+ end
7
+
8
+ def tree(name)
9
+ @tree_name = name
10
+ self
11
+ end
12
+
13
+ def ping
14
+ request = {
15
+ command: 'ping'
16
+ }
17
+ @connection.send_and_read(request)
18
+ end
19
+
20
+ def trees
21
+ request = {
22
+ command: 'trees'
23
+ }
24
+ @connection.send_and_read(request)
25
+ end
26
+
27
+ def create(name)
28
+ request = {
29
+ command: 'create',
30
+ tree_name: name
31
+ }
32
+ @connection.send_and_read(request)
33
+ end
34
+
35
+ def drop(name)
36
+ request = {
37
+ command: 'drop',
38
+ tree_name: name
39
+ }
40
+ @connection.send_and_read(request)
41
+ end
42
+
43
+ def dump(name)
44
+ request = {
45
+ command: 'dump',
46
+ tree_name: name
47
+ }
48
+ @connection.send_and_read(request)
49
+ end
50
+
51
+ def dump_all
52
+ request = {
53
+ command: 'dump_all'
54
+ }
55
+ @connection.send_and_read(request)
56
+ end
57
+
58
+ def dumps
59
+ request = {
60
+ command: 'dumps'
61
+ }
62
+ @connection.send_and_read(request)
63
+ end
64
+
65
+ def load(name)
66
+ request = {
67
+ command: 'load',
68
+ tree_name: name
69
+ }
70
+ @connection.send_and_read(request)
71
+ end
72
+
73
+ def increment(**args)
74
+ request = {
75
+ command: 'increment',
76
+ tree_name: @tree_name
77
+ }.merge!(args)
78
+ @connection.send_and_read(request)
79
+ end
80
+
81
+ def decrement(**args)
82
+ request = {
83
+ command: 'decrement',
84
+ tree_name: @tree_name
85
+ }.merge!(args)
86
+ @connection.send_and_read(request)
87
+ end
88
+
89
+ def sum(**args)
90
+ request = {
91
+ command: 'sum',
92
+ tree_name: @tree_name
93
+ }.merge!(args)
94
+ @connection.send_and_read(request)
95
+ end
96
+
97
+ def find(**args)
98
+ request = {
99
+ command: 'find',
100
+ tree_name: @tree_name
101
+ }.merge!(args)
102
+ @connection.send_and_read(request)
103
+ end
104
+
105
+ def reset(**args)
106
+ request = {
107
+ command: 'reset',
108
+ tree_name: @tree_name,
109
+ }.merge!(args)
110
+ @connection.send_and_read(request)
111
+ end
112
+
113
+ def delete(**args)
114
+ request = {
115
+ command: 'delete',
116
+ tree_name: @tree_name,
117
+ }.merge!(args)
118
+ @connection.send_and_read(request)
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Karma
4
+ VERSION = "0.1.0"
5
+ end
data/lib/karma.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'json'
2
+ require 'socket'
3
+ require 'ostruct'
4
+
5
+ require 'karma/version'
6
+ require 'karma/config'
7
+ require 'karma/connection'
8
+ require 'karma/tree'
9
+
10
+ module Karma
11
+ TREE = Tree.new
12
+
13
+ def self.method_missing(m, *args, &block)
14
+ TREE.send(m, *args, &block)
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: karma
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sergey Fedorov
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-07-04 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Ruby client for the Karma key-counter database
14
+ email:
15
+ - creadone@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".rubocop.yml"
21
+ - Gemfile
22
+ - LICENSE.txt
23
+ - README.md
24
+ - Rakefile
25
+ - karma.gemspec
26
+ - lib/karma.rb
27
+ - lib/karma/config.rb
28
+ - lib/karma/connection.rb
29
+ - lib/karma/tree.rb
30
+ - lib/karma/version.rb
31
+ homepage: https://github.com/creadone/karma-rb
32
+ licenses:
33
+ - MIT
34
+ metadata:
35
+ homepage_uri: https://github.com/creadone/karma-rb
36
+ source_code_uri: https://github.com/creadone/karma-rb
37
+ post_install_message:
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: 2.6.0
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubygems_version: 3.3.7
53
+ signing_key:
54
+ specification_version: 4
55
+ summary: Ruby client for the Karma key-counter database
56
+ test_files: []