simple-file-db 0.7

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: 92b1837a51f599b3a94500c9c3d8c2f2ff3240e9c2d0d8ba80cb92a72fee8336
4
+ data.tar.gz: 59978523a27ac4a810b69c2b8a0c0e31a2d785c00308215c2c852e21aef64953
5
+ SHA512:
6
+ metadata.gz: 76a7e8a5c0cc54df4e3039df4d90bc237f075c67621097fe87f309dff79c0cff9a442f525a007c7087aa876c2fbc5551acdd1984bb131f018ef9673845e0dce3
7
+ data.tar.gz: 53d2d7abd6890f4f80c827a3c7787e1b2a4f1311ac3cd0c2e8bd6f84383fc136491af1b2d4f9772860361f7a370c87bce1c67b11897d35eff34b66b0b69acc03
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .DS_Store
2
+ Gemfile.lock
3
+ *.gem
data/README.md ADDED
@@ -0,0 +1 @@
1
+ FIXME
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'simple-rake-tasks'
data/TODO.txt ADDED
@@ -0,0 +1,18 @@
1
+ - rename to FileDB or SlowDB
2
+
3
+ - make work *only* with files
4
+ - no in-memory database
5
+ - no caching (or optional)
6
+ - #[] reads JSON file, #[]= writes, #delete deletes
7
+ - #keys reads directories/IDs
8
+ - #values parses JSON files
9
+ - #update(item) rewrites item
10
+
11
+ - make include'able, rather than inheritable
12
+ - include Simple::FileDB, include Simple::FileDB::Item
13
+
14
+ - make simpler to-json/from-json converters
15
+ - hash with keys of attributes, values as hash of procs:
16
+ - initialize
17
+ - reader
18
+ - writer (defaults to #to_s unless basic types)
@@ -0,0 +1,55 @@
1
+ module Simple
2
+
3
+ class FileDB
4
+
5
+ class Item
6
+
7
+ attr_accessor :json_file
8
+ attr_accessor :id
9
+ attr_accessor :db
10
+
11
+ include SetParams
12
+
13
+ def dir
14
+ @json_file.dirname
15
+ end
16
+
17
+ def files
18
+ dir.glob('*') - [json_file]
19
+ end
20
+
21
+ def to_h
22
+ {
23
+ id: id,
24
+ }
25
+ end
26
+
27
+ def to_json(*options)
28
+ as_json(*options).to_json(*options)
29
+ end
30
+
31
+ def as_json(*options)
32
+ to_h.compact
33
+ end
34
+
35
+ def to_pretty_json
36
+ JSON.pretty_generate(self)
37
+ end
38
+
39
+ def fields(keys)
40
+ keys.map { |k| send(k) }
41
+ end
42
+
43
+ def <=>(other)
44
+ id <=> other.id
45
+ end
46
+
47
+ def save
48
+ @db.save_item(self)
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+
55
+ end
@@ -0,0 +1,163 @@
1
+ require 'csv'
2
+ require 'json'
3
+ require 'path'
4
+ require 'set_params'
5
+
6
+ require_relative 'simple-file-db/item'
7
+
8
+ module Simple
9
+
10
+ class FileDB
11
+
12
+ class Error < Exception; end
13
+
14
+ attr_accessor :root
15
+
16
+ InfoFileName = 'info.json'
17
+
18
+ def self.item_class
19
+ Item
20
+ end
21
+
22
+ def self.search_fields
23
+ []
24
+ end
25
+
26
+ def self.convert_id(id)
27
+ id
28
+ end
29
+
30
+ def initialize(root:)
31
+ @root = Path.new(root).expand_path
32
+ @items = {}
33
+ if @root.exist?
34
+ @root.glob("*/#{InfoFileName}").each do |info_file|
35
+ raise Error, "Info file does not exist: #{info_file}" unless info_file.exist?
36
+ make_item(**JSON.load(info_file.read))
37
+ end
38
+ # ;;warn "* loaded #{@items.length} items from #{@root}"
39
+ end
40
+ end
41
+
42
+ def items
43
+ @items.values
44
+ end
45
+
46
+ def as_json(...)
47
+ items
48
+ end
49
+
50
+ def to_json(...)
51
+ as_json(...).to_json(...)
52
+ end
53
+
54
+ def to_csv
55
+ csv = []
56
+ items.each_with_index do |item, i|
57
+ hash = item.to_h
58
+ csv << CSV.generate_line(hash.keys) if i == 0
59
+ csv << CSV.generate_line(hash.values)
60
+ end
61
+ csv.join
62
+ end
63
+
64
+ def convert_id(id)
65
+ self.class.convert_id(id)
66
+ end
67
+
68
+ def [](id)
69
+ @items[convert_id(id)]
70
+ end
71
+
72
+ def []=(id, value)
73
+ @items[convert_id(id)] = value
74
+ end
75
+
76
+ def <<(item)
77
+ item.db = self
78
+ self[item.id] = item
79
+ end
80
+
81
+ def make_item(**params)
82
+ item = self.class.item_class.new(**params)
83
+ item.db = self
84
+ item.json_file = json_file_for_id(item.id)
85
+ @items[item.id] = item
86
+ item
87
+ end
88
+
89
+ def find(*selectors)
90
+ selectors = [selectors].compact.flatten
91
+ # warn "searching #{self.class} for: #{selectors.empty? ? 'ALL' : selectors.join(', ')}"
92
+ if selectors.empty?
93
+ @items.values
94
+ else
95
+ selected = Set.new
96
+ selectors.each do |selector|
97
+ if selector.to_i != 0
98
+ selected << convert_id(selector)
99
+ else
100
+ selected += search(selector)
101
+ end
102
+ end
103
+ selected.map { |id| self[id] }.compact.sort
104
+ end
105
+ end
106
+
107
+ def search(query)
108
+ words = [query].flatten.join(' ').tokenize.sort.uniq - ['-']
109
+ words.map do |word|
110
+ regexp = Regexp.new(Regexp.quote(word), true)
111
+ @items.values.select do |item|
112
+ self.class.search_fields.find do |field|
113
+ case (value = item.send(field))
114
+ when Array
115
+ value.find { |v| v.to_s =~ regexp }
116
+ else
117
+ value.to_s =~ regexp
118
+ end
119
+ end
120
+ end
121
+ end.flatten.compact.sort.map(&:id)
122
+ end
123
+
124
+ def json_file_for_id(id)
125
+ @root / id / InfoFileName
126
+ end
127
+
128
+ def save_item(item)
129
+ raise Error, "Item does not have ID" unless item.id
130
+ item.json_file = json_file_for_id(item.id)
131
+ # ;;warn "* saving item to #{item.json_file}"
132
+ item.json_file.dirname.mkpath unless item.json_file.dirname.exist?
133
+ item.json_file.write(item.to_pretty_json)
134
+ self[item.id] ||= item
135
+ end
136
+
137
+ def save_hash(hash)
138
+ raise Error, "Hash does not have ID" unless hash[:id]
139
+ json_file = json_file_for_id(hash[:id])
140
+ # ;;warn "* saving item to #{json_file}"
141
+ json = JSON.pretty_generate(hash)
142
+ json_file.dirname.mkpath unless json_file.dirname.exist?
143
+ json_file.write(json)
144
+ end
145
+
146
+ def has_item?(id)
147
+ @items.has_key?(convert_id(id))
148
+ end
149
+
150
+ def destroy!
151
+ @items = {}
152
+ @root.rmtree if @root.exist?
153
+ end
154
+
155
+ def destroy_item!(item)
156
+ @items.delete(item.id)
157
+ dir = json_file_for_id(item.id).dirname
158
+ dir.rmtree if dir.exist?
159
+ end
160
+
161
+ end
162
+
163
+ end
@@ -0,0 +1,29 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'simple-file-db'
3
+ s.version = '0.7'
4
+ s.summary = 'A database built upon JSON files'
5
+ s.author = 'John Labovitz'
6
+ s.email = 'johnl@johnlabovitz.com'
7
+ s.description = %q{
8
+ Simple::FileDB is a database built upon JSON files.
9
+ }.strip
10
+ s.license = 'MIT'
11
+ s.homepage = 'http://github.com/jslabovitz/simple-file-db'
12
+ s.files = `git ls-files`.split("\n")
13
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
15
+ s.require_path = 'lib'
16
+
17
+ s.add_dependency 'csv', '~> 3.3'
18
+ s.add_dependency 'json', '~> 2.15'
19
+ s.add_dependency 'path', '~> 2.1'
20
+ s.add_dependency 'set_params', '~> 0.3'
21
+
22
+ s.add_development_dependency 'bundler', '~> 2.7'
23
+ s.add_development_dependency 'minitest', '~> 5.26'
24
+ s.add_development_dependency 'minitest-power_assert', '~> 0.3'
25
+ s.add_development_dependency 'rake', '~> 13.3'
26
+ s.add_development_dependency 'simple-rake-tasks', '~> 0.1'
27
+
28
+
29
+ end
data/test/main_test.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/power_assert'
3
+
4
+ require 'simple-file-db'
5
+
6
+ class Test < Minitest::Test
7
+
8
+ def setup
9
+ end
10
+
11
+ def test_simple
12
+ end
13
+
14
+ end
metadata ADDED
@@ -0,0 +1,174 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple-file-db
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.7'
5
+ platform: ruby
6
+ authors:
7
+ - John Labovitz
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: csv
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '3.3'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '3.3'
26
+ - !ruby/object:Gem::Dependency
27
+ name: json
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.15'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2.15'
40
+ - !ruby/object:Gem::Dependency
41
+ name: path
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '2.1'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '2.1'
54
+ - !ruby/object:Gem::Dependency
55
+ name: set_params
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '0.3'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '0.3'
68
+ - !ruby/object:Gem::Dependency
69
+ name: bundler
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '2.7'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '2.7'
82
+ - !ruby/object:Gem::Dependency
83
+ name: minitest
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '5.26'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '5.26'
96
+ - !ruby/object:Gem::Dependency
97
+ name: minitest-power_assert
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.3'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '0.3'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rake
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '13.3'
117
+ type: :development
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '13.3'
124
+ - !ruby/object:Gem::Dependency
125
+ name: simple-rake-tasks
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '0.1'
131
+ type: :development
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '0.1'
138
+ description: Simple::FileDB is a database built upon JSON files.
139
+ email: johnl@johnlabovitz.com
140
+ executables: []
141
+ extensions: []
142
+ extra_rdoc_files: []
143
+ files:
144
+ - ".gitignore"
145
+ - README.md
146
+ - Rakefile
147
+ - TODO.txt
148
+ - lib/simple-file-db.rb
149
+ - lib/simple-file-db/item.rb
150
+ - simple-file-db.gemspec
151
+ - test/main_test.rb
152
+ homepage: http://github.com/jslabovitz/simple-file-db
153
+ licenses:
154
+ - MIT
155
+ metadata: {}
156
+ rdoc_options: []
157
+ require_paths:
158
+ - lib
159
+ required_ruby_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ requirements: []
170
+ rubygems_version: 3.7.2
171
+ specification_version: 4
172
+ summary: A database built upon JSON files
173
+ test_files:
174
+ - test/main_test.rb