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 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: []