seeds-db 1.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 +7 -0
- data/README.md +0 -0
- data/bin/seeds +105 -0
- data/lib/crud.rb +98 -0
- data/lib/leaf.rb +68 -0
- data/lib/response.rb +26 -0
- data/lib/seeds.rb +60 -0
- metadata +91 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a48cfacca9e8e53f2c37e749c3f1432c9dd955e8
|
4
|
+
data.tar.gz: ab99a9ebbbf753067f71d5b7e955fa8e01c5c61a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ec0170ffd24cc746a74ebec07d167f2c8ebd0d23cb5f3e9aea08a125ba6c25beea038a472d38215acbee69065da61e66f755e177f9adaa8750a78f522108816d
|
7
|
+
data.tar.gz: f04632e1a226a59b1b1325561485bbfa905f5c9f5460a44bf069384940645fca7ca9e33ffdf023371ee0b0ebc4c6e8974684d81b779cd114ef4d5d181db5023e
|
data/README.md
ADDED
File without changes
|
data/bin/seeds
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'seeds'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
options = {}
|
7
|
+
begin
|
8
|
+
OptionParser.new do |opts|
|
9
|
+
opts.banner = 'Usage: seeds [-options]'
|
10
|
+
|
11
|
+
opts.on('-d', '-d directory', 'Sets seeds directory if directory is not ./seeds') do |arg|
|
12
|
+
options[:dir] = arg
|
13
|
+
end
|
14
|
+
|
15
|
+
opts.on('-c', '-c create', 'Creates an entry in specified seed') do |arg|
|
16
|
+
options[:action] = 'c' if options[:action].nil?
|
17
|
+
options[:seed] = arg
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on('-r', '-r read', 'Displays all entries in seeds directory') do |arg|
|
21
|
+
options[:action] = 'r' if options[:action].nil?
|
22
|
+
options[:seed] = arg
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on('-u', '-u update', 'Updates an entry/entries in specified seed') do |arg|
|
26
|
+
options[:action] = 'u' if options[:action].nil?
|
27
|
+
options[:seed] = arg
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on('-d', '-d create', 'Deletes an entry/entries in specified seed') do |arg|
|
31
|
+
options[:action] = 'd' if options[:action].nil?
|
32
|
+
options[:seed] = arg
|
33
|
+
end
|
34
|
+
|
35
|
+
opts.on('-n', '-n create', 'Creates a seed with specified name') do |arg|
|
36
|
+
options[:action] = 'n' if options[:action].nil?
|
37
|
+
options[:seed] = arg
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on('-m', '-m delete', 'Deletes a seed with specified name') do |arg|
|
41
|
+
options[:action] = 'm' if options[:action].nil?
|
42
|
+
options[:seed] = arg
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on('-w', '-w with data', 'Data to create/update leaf with') do |arg|
|
46
|
+
data = {}
|
47
|
+
split = arg.split(',')
|
48
|
+
split.each do |s|
|
49
|
+
key, value = s.split('=')
|
50
|
+
data[key.to_sym] = value
|
51
|
+
end
|
52
|
+
options[:with] = data
|
53
|
+
end
|
54
|
+
|
55
|
+
opts.on('-k', '-k constraints', 'Constraints for read/update/deletes') do |arg|
|
56
|
+
data = {}
|
57
|
+
split = arg.split(',')
|
58
|
+
split.each do |s|
|
59
|
+
key, value = s.split('=')
|
60
|
+
data[key.to_sym] = value
|
61
|
+
end
|
62
|
+
options[:con] = data
|
63
|
+
end
|
64
|
+
end.parse!
|
65
|
+
rescue
|
66
|
+
puts 'No actions were specified. See a list of options with -h'
|
67
|
+
end
|
68
|
+
|
69
|
+
seeds = options[:dir].nil? ? Seeds.new : Seeds.new(options[:dir])
|
70
|
+
|
71
|
+
case options[:action]
|
72
|
+
when 'c'
|
73
|
+
response = options[:with].nil? ? seeds.create(options[:seed]) : seeds.create(options[:seed], options[:with])
|
74
|
+
puts response
|
75
|
+
when 'r'
|
76
|
+
if options[:seed] == 'all'
|
77
|
+
Dir.foreach './seeds' do |seed|
|
78
|
+
next if seed == '.' || seed == '..'
|
79
|
+
response = seeds.read(seed.split('.seed')[0])
|
80
|
+
puts "\n#{seed} ------------------------------------------------------------------------"
|
81
|
+
puts response[:results]
|
82
|
+
end
|
83
|
+
else
|
84
|
+
response = seeds.read(options[:seed])[:results]
|
85
|
+
puts "#{options[:seed]} was not found" if response.nil?
|
86
|
+
puts response unless response.nil?
|
87
|
+
end
|
88
|
+
when 'u'
|
89
|
+
seed_name = options[:seed]
|
90
|
+
with_opts = options[:with]
|
91
|
+
|
92
|
+
response = options[:con].nil? ? seeds.update(seed_name, with_opts) : seeds.update(seed_name, with_opts, options[:con])
|
93
|
+
puts response
|
94
|
+
when 'd'
|
95
|
+
response = options[:con].nil? ? seeds.delete(options[:seed]) : seeds.delete(options[:seed], options[:con])
|
96
|
+
puts response
|
97
|
+
when 'n'
|
98
|
+
response = seeds.create_seed(options[:seed])
|
99
|
+
puts response
|
100
|
+
when 'm'
|
101
|
+
response = seeds.delete_seed(options[:seed])
|
102
|
+
puts response
|
103
|
+
else
|
104
|
+
puts 'No actions were specified. See a list of options with -h'
|
105
|
+
end
|
data/lib/crud.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'lru_redux'
|
2
|
+
require_relative './response'
|
3
|
+
require_relative './leaf'
|
4
|
+
|
5
|
+
class CRUD
|
6
|
+
def initialize(path)
|
7
|
+
@dir = path
|
8
|
+
@cache = LruRedux::Cache.new(10)
|
9
|
+
end
|
10
|
+
|
11
|
+
def create(seed_name, data)
|
12
|
+
seed = get_seed(seed_name)
|
13
|
+
seed = construct_seed(seed_name) if seed.nil?
|
14
|
+
success = Leaf.create_leaf(seed, data)
|
15
|
+
|
16
|
+
@cache[seed_name.to_sym] = seed
|
17
|
+
update_file(seed, seed_name)
|
18
|
+
|
19
|
+
return Response.create_response(false, 'Unable to create leaf') unless success
|
20
|
+
Response.create_response(true, "Success leaf was created and added to #{seed_name}")
|
21
|
+
end
|
22
|
+
|
23
|
+
def read(seed_name, rules)
|
24
|
+
seed = get_seed(seed_name)
|
25
|
+
return Response.create_response(false, "#{seed_name} seed was not found") if seed.nil?
|
26
|
+
response = Leaf.read_leaf(seed[:leaves], rules)
|
27
|
+
|
28
|
+
return Response.create_response(false, 'No leaves found containing specified rules') if response.empty?
|
29
|
+
Response.create_response(true, 'Success', results: response)
|
30
|
+
end
|
31
|
+
|
32
|
+
def update(seed_name, data, rules)
|
33
|
+
seed = get_seed(seed_name)
|
34
|
+
return Response.create_response(false, "#{seed_name} seed was not found") if seed.nil?
|
35
|
+
success = Leaf.update_leaf(seed[:leaves], data, rules)
|
36
|
+
|
37
|
+
@cache[seed_name.to_sym] = seed
|
38
|
+
update_file(seed, seed_name)
|
39
|
+
|
40
|
+
return Response.create_response(false, 'No leaves found containing specified rules') unless success
|
41
|
+
Response.create_response(true, "Success leaves were updated in #{seed_name}")
|
42
|
+
end
|
43
|
+
|
44
|
+
def delete(seed_name, rules)
|
45
|
+
seed = get_seed(seed_name)
|
46
|
+
return Response.create_response(false, "#{seed_name} seed was not found") if seed.nil?
|
47
|
+
success = Leaf.delete_leaf(seed[:leaves], rules)
|
48
|
+
|
49
|
+
@cache[seed_name.to_sym] = seed
|
50
|
+
update_file(seed, seed_name)
|
51
|
+
|
52
|
+
return Response.create_response(false, 'No leaves found containing specified rules') unless success
|
53
|
+
Response.create_response(true, "Success leaves were deleted in #{seed_name}")
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_seed(seed)
|
57
|
+
return Response.create_response(false, 'Seed already exists') if File.exist? "#{@dir}/#{seed}.seed"
|
58
|
+
seed = construct_seed(seed)
|
59
|
+
|
60
|
+
Response.create_response(true, "Success #{seed} was created as a seed")
|
61
|
+
end
|
62
|
+
|
63
|
+
def delete_seed(seed)
|
64
|
+
return Response.create_response(false, 'Seed did not exist') unless File.exist? "#{@dir}/#{seed}.seed"
|
65
|
+
File.delete "#{@dir}/#{seed}.seed"
|
66
|
+
Response.create_response(true, 'Success seed was delete')
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def get_seed_path(seed)
|
72
|
+
@dir + "/#{seed}.seed"
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_seed(seed)
|
76
|
+
seed_path = get_seed_path(seed)
|
77
|
+
return @cache[seed.to_sym] unless @cache[seed.to_sym].nil?
|
78
|
+
loaded_seed = Marshal.load(File.open(seed_path)) if File.exist? seed_path
|
79
|
+
@cache[seed.to_sym] = loaded_seed
|
80
|
+
loaded_seed
|
81
|
+
end
|
82
|
+
|
83
|
+
def construct_seed(seed)
|
84
|
+
seed_path = get_seed_path(seed)
|
85
|
+
seed_template = {
|
86
|
+
name: seed,
|
87
|
+
creation_date: Time.now.strftime('%d/%m/%Y %H:%M'),
|
88
|
+
leaves: []
|
89
|
+
}
|
90
|
+
|
91
|
+
File.open(seed_path, 'w') { |file| file.write(Marshal.dump(seed_template)) }
|
92
|
+
seed_template
|
93
|
+
end
|
94
|
+
|
95
|
+
def update_file(seed, seed_name)
|
96
|
+
File.open(get_seed_path(seed_name), 'w') { |file| file.write(Marshal.dump(seed)) }
|
97
|
+
end
|
98
|
+
end
|
data/lib/leaf.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module Leaf
|
4
|
+
def self.create_leaf(seed, data)
|
5
|
+
leaf_template = {
|
6
|
+
uid: SecureRandom.hex,
|
7
|
+
creation_date: Time.now.strftime('%d/%m/%Y %H:%M')
|
8
|
+
}
|
9
|
+
|
10
|
+
seed[:leaves] << if data.length >= 1
|
11
|
+
add_data(leaf_template, data)
|
12
|
+
else
|
13
|
+
leaf_template
|
14
|
+
end
|
15
|
+
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.read_leaf(leaves, rules)
|
20
|
+
return leaves unless rules.length >= 1
|
21
|
+
search_for_leaves(leaves, rules.to_a)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.update_leaf(leaves, data, rules)
|
25
|
+
results = rules.length >= 1 ? search_for_leaves(leaves, rules.to_a) : leaves
|
26
|
+
false unless results.length >= 1
|
27
|
+
|
28
|
+
results.length.times do |i|
|
29
|
+
add_data(leaves[i], data, true)
|
30
|
+
end
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.delete_leaf(leaves, rules)
|
35
|
+
unless rules.length >= 1
|
36
|
+
leaves.clear
|
37
|
+
return true
|
38
|
+
end
|
39
|
+
|
40
|
+
results = search_for_leaves(leaves, rules.to_a)
|
41
|
+
false unless results.length >= 1
|
42
|
+
|
43
|
+
results.each do |leaf|
|
44
|
+
leaves.delete(leaf)
|
45
|
+
end
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
# Private methods
|
50
|
+
|
51
|
+
def self.search_for_leaves(leaves, rules)
|
52
|
+
rule = rules.pop
|
53
|
+
results = leaves.select { |leaf| leaf[rule[0]] == rule[1] }
|
54
|
+
|
55
|
+
return search_for_leaves(results, rules) unless rules.empty? || results.empty?
|
56
|
+
results
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.add_data(template, data, overwrite = false)
|
60
|
+
data.each do |key, value|
|
61
|
+
template[key] = value unless (template.key? key) && !overwrite
|
62
|
+
end
|
63
|
+
template
|
64
|
+
end
|
65
|
+
|
66
|
+
private_class_method :search_for_leaves
|
67
|
+
private_class_method :add_data
|
68
|
+
end
|
data/lib/response.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Response
|
2
|
+
def self.failure(err)
|
3
|
+
{
|
4
|
+
success: false,
|
5
|
+
error: err
|
6
|
+
}
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.success(success, opts)
|
10
|
+
response = {
|
11
|
+
success: true,
|
12
|
+
msg: success
|
13
|
+
}
|
14
|
+
|
15
|
+
return response unless opts.length >= 1
|
16
|
+
opts.each do |key, value|
|
17
|
+
response[key] = value unless response.key? key
|
18
|
+
end
|
19
|
+
response
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.create_response(bool, msg, opts = {})
|
23
|
+
return failure(msg) unless bool
|
24
|
+
success(msg, opts)
|
25
|
+
end
|
26
|
+
end
|
data/lib/seeds.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# Dir[File.expand_path('../*', __FILE__)].each { |path| $LOAD_PATH.unshift path }
|
2
|
+
require_relative './response'
|
3
|
+
require_relative './crud'
|
4
|
+
|
5
|
+
class Seeds
|
6
|
+
def initialize(path = Dir.pwd)
|
7
|
+
@dir_path = path << '/seeds'
|
8
|
+
Dir.mkdir @dir_path unless Dir.exist? @dir_path
|
9
|
+
@crud = CRUD.new(@dir_path)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Creates a new leaf in the specified seed, seed will be created if it doesn't exist.
|
13
|
+
# @param seed [String] name of the seed to create in
|
14
|
+
# @param data [Hash] OPTIONAL: Specifies data to be added to the new leaf
|
15
|
+
# @return response [Hash] indicates success/failure
|
16
|
+
def create(seed, data = {})
|
17
|
+
return Response.create_response(false, 'data was not of type Hash') unless data.is_a? Hash
|
18
|
+
@crud.create(seed, data)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Reads a leaf in the specified seed and returns it.
|
22
|
+
# @param seed [String] name of the seed to read from
|
23
|
+
# @param rules [Hash] OPTIONAL: Specifies rules for the read
|
24
|
+
# @return response [Hash] indicates success/failure, contains results from read if success
|
25
|
+
def read(seed, rules = {})
|
26
|
+
@crud.read(seed, rules)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Updates a leaf in the specified seed.
|
30
|
+
# @param seed [String] name of the seed to update in
|
31
|
+
# @param data [Hash] updates leaves with data, will overwrite existing data
|
32
|
+
# @param rules [Hash] OPTIONAL: Specifies rules for the update
|
33
|
+
# @return response [Hash] indicates success/failure
|
34
|
+
def update(seed, data, rules = {})
|
35
|
+
return Response.create_response(false, 'data was not of type Hash') unless data.is_a? Hash
|
36
|
+
@crud.update(seed, data, rules)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Deletes a leaf in the specified seed.
|
40
|
+
# @param seed [String] name of the seed to read from
|
41
|
+
# @param rules [Hash] OPTIONAL: Specifies rules for the update, if no rules specified all leaves will be deleted
|
42
|
+
# @return response [Hash] indicates success/failure
|
43
|
+
def delete(seed, rules = {})
|
44
|
+
@crud.delete(seed, rules)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Creates a new seed.
|
48
|
+
# @param seed [String] name of the seed to create
|
49
|
+
# @return response [Hash] indicates success/failure
|
50
|
+
def create_seed(seed)
|
51
|
+
@crud.create_seed(seed)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Deletes a seed.
|
55
|
+
# @param seed [String] name of the seed to delete
|
56
|
+
# @return response [Hash] indicates success/failure
|
57
|
+
def delete_seed(seed)
|
58
|
+
@crud.delete_seed(seed)
|
59
|
+
end
|
60
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: seeds-db
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Isaiah Soung
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: lru_redux
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rubocop
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.41.1
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.41.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.5.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.5.0
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
executables:
|
58
|
+
- seeds
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- README.md
|
63
|
+
- bin/seeds
|
64
|
+
- lib/crud.rb
|
65
|
+
- lib/leaf.rb
|
66
|
+
- lib/response.rb
|
67
|
+
- lib/seeds.rb
|
68
|
+
homepage: https://github.com/Isoung/seeds
|
69
|
+
licenses: []
|
70
|
+
metadata: {}
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 2.5.2
|
88
|
+
signing_key:
|
89
|
+
specification_version: 4
|
90
|
+
summary: Seeds is a plug&play persistent storage for Ruby
|
91
|
+
test_files: []
|