file_db 0.7.0 → 1.0.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 +4 -4
- data/README.md +57 -7
- data/lib/file_db/configuration.rb +0 -1
- data/lib/file_db/data.rb +6 -21
- data/lib/file_db/database_manager.rb +20 -0
- data/lib/file_db/model.rb +2 -1
- data/lib/file_db/query.rb +10 -32
- data/lib/file_db/system/database.rb +67 -0
- data/lib/file_db/system/table.rb +113 -0
- data/lib/file_db/table.rb +10 -0
- data/lib/file_db/version.rb +1 -1
- data/lib/file_db.rb +4 -4
- metadata +5 -5
- data/lib/file_db/convert.rb +0 -11
- data/lib/file_db/database.rb +0 -84
- data/lib/file_db/system/check.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 08faf66085096d47a2174f7b9a830ffefab7a0c9
|
4
|
+
data.tar.gz: e04c84ba4d2b326abb841fde573d4aec1a71f420
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a320df01f983701a6d0d714705a87979484bbd0a8ccffb1e5ff77cfb72f78c9e8f7e5509d1434673251feaa119f4fa547a7af958811f4f49209fd23bac1ae6a5
|
7
|
+
data.tar.gz: 4a4cf440242030a75fb4f1aebd504b66d2d8e425ece1589706b0327556ce6af3c73c4a8fa71f57a6ae95bf487fd9ef96904bdd464569a932ca8f469bb8cc3fa1
|
data/README.md
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# FileDb
|
2
2
|
|
3
|
-
|
3
|
+
FileDb is a small type of database. It stores all data for a model into CSV files and create accessor for you.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
7
|
hm, yeah. just add this to your Gemfile:
|
8
8
|
|
9
9
|
```ruby
|
10
|
-
gem 'file_db', '~> 0.
|
10
|
+
gem 'file_db', '~> 1.0.0'
|
11
11
|
```
|
12
12
|
|
13
13
|
And then execute:
|
@@ -21,6 +21,60 @@ Or install it yourself as:
|
|
21
21
|
|
22
22
|
Huh, ready to use!
|
23
23
|
|
24
|
+
## Differences to Version 0.7.0
|
25
|
+
|
26
|
+
Fieldnames are now in the first line of the table file.
|
27
|
+
|
28
|
+
And:
|
29
|
+
|
30
|
+
### Performance
|
31
|
+
|
32
|
+
#### 0.7.0 with 1000 Entries
|
33
|
+
|
34
|
+
| Action | Time in Milliseconds |
|
35
|
+
|---|---|
|
36
|
+
|getting the first|29.194|
|
37
|
+
|update record|39.226|
|
38
|
+
|create record|74.994|
|
39
|
+
|using where with 1 parameter|8.700|
|
40
|
+
|using where with 2 parameter|9.775|
|
41
|
+
|find |9.507|
|
42
|
+
|
43
|
+
#### 1.0.0 with 1000 Entries
|
44
|
+
|
45
|
+
| Action | Time in Milliseconds |
|
46
|
+
|---|---|
|
47
|
+
|getting the first|8.184|
|
48
|
+
|update record|4.629|
|
49
|
+
|create record|3.673|
|
50
|
+
|using where with 1 parameter|0.535|
|
51
|
+
|using where with 2 parameter|0.337|
|
52
|
+
|find |0.030|
|
53
|
+
|
54
|
+
#### 0.7.0 with 5000 Entries
|
55
|
+
|
56
|
+
| Action | Time in Milliseconds |
|
57
|
+
|---|---|
|
58
|
+
|getting the first|88.852|
|
59
|
+
|update record|122.662|
|
60
|
+
|create record|284.086|
|
61
|
+
|using where with 1 parameter|35.795|
|
62
|
+
|using where with 2 parameter|35.125|
|
63
|
+
|find |35.881|
|
64
|
+
|
65
|
+
#### 1.0.0 with 5000 Entries
|
66
|
+
|
67
|
+
| Action | Time in Milliseconds |
|
68
|
+
|---|---|
|
69
|
+
|getting the first|27.343|
|
70
|
+
|update record|14.405|
|
71
|
+
|create record|9.705|
|
72
|
+
|using where with 1 parameter|1.846|
|
73
|
+
|using where with 2 parameter|2.027|
|
74
|
+
|find |0.019|
|
75
|
+
|
76
|
+
|
77
|
+
|
24
78
|
## Usage
|
25
79
|
|
26
80
|
### Configuration
|
@@ -30,12 +84,8 @@ First configure the storage directory:
|
|
30
84
|
```ruby
|
31
85
|
FileDb::Configuration.configure data_directory: 'data'
|
32
86
|
```
|
33
|
-
Subdirectory is the default for storing the tables. If you change the configuration, the `FileDb` will be automaticly create a new database.
|
87
|
+
Subdirectory is the default for storing the tables. If you change the configuration, the `FileDb` will be automaticly create a new database directory and table files if needed.
|
34
88
|
|
35
|
-
If you running a clean instance with no configuration changes so make sure, the storage directory exists or use the build in check for checking and creating the data directory:
|
36
|
-
```ruby
|
37
|
-
FileDb::System::Check.run!
|
38
|
-
```
|
39
89
|
|
40
90
|
Let's start with creating a model called `User`.
|
41
91
|
|
data/lib/file_db/data.rb
CHANGED
@@ -5,37 +5,22 @@ module FileDb
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def delete
|
8
|
-
|
8
|
+
table.delete(id)
|
9
9
|
end
|
10
10
|
|
11
11
|
def save
|
12
|
-
|
13
|
-
Database.instance.update_record self
|
14
|
-
else
|
15
|
-
self.id = next_id #Time.now.to_i
|
16
|
-
Database.instance.add_record self
|
17
|
-
end
|
12
|
+
table.update_record self
|
18
13
|
end
|
19
14
|
|
20
15
|
def persisted?
|
21
|
-
id
|
16
|
+
table.hashed_by_id[id.to_s]
|
22
17
|
end
|
23
18
|
|
24
|
-
|
25
|
-
|
26
|
-
def next_id
|
27
|
-
return 1 unless current_id
|
28
|
-
current_id + 1
|
19
|
+
def table
|
20
|
+
self.class.table
|
29
21
|
end
|
30
22
|
|
31
|
-
|
32
|
-
return unless last_record
|
33
|
-
last_record.id.to_i
|
34
|
-
end
|
35
|
-
|
36
|
-
def last_record
|
37
|
-
self.class.last
|
38
|
-
end
|
23
|
+
private
|
39
24
|
|
40
25
|
def load_params_into_model params
|
41
26
|
params.each do |key, value|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
module FileDb
|
3
|
+
class DatabaseManager
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
attr_accessor :database
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@database = System::Database.new Configuration.configured(:data_directory)
|
10
|
+
end
|
11
|
+
|
12
|
+
def drop_database!
|
13
|
+
database.drop_data_directory!
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_database_if_not_exist!
|
17
|
+
database.create_database_if_not_exist!
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/file_db/model.rb
CHANGED
data/lib/file_db/query.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
module FileDb
|
2
2
|
module Query
|
3
|
-
|
4
|
-
|
3
|
+
|
4
|
+
def find id
|
5
|
+
found_element = table.find(id)
|
6
|
+
return unless found_element
|
7
|
+
new found_element
|
8
|
+
end
|
9
|
+
|
5
10
|
def first
|
6
11
|
all.first
|
7
12
|
end
|
@@ -11,43 +16,16 @@ module FileDb
|
|
11
16
|
end
|
12
17
|
|
13
18
|
def all
|
14
|
-
|
19
|
+
table.all.map{ |entry| new entry }
|
15
20
|
end
|
16
21
|
|
17
|
-
def
|
18
|
-
|
22
|
+
def where conditions
|
23
|
+
table.where(conditions).map{ |entry| new entry }
|
19
24
|
end
|
20
25
|
|
21
26
|
def find_by attribute, search_value
|
22
27
|
where("#{attribute}".to_sym => search_value).first
|
23
28
|
end
|
24
29
|
|
25
|
-
def where conditions
|
26
|
-
results = []
|
27
|
-
Database.instance.search(self) do |data_row|
|
28
|
-
if conditions_match?(conditions,data_row)
|
29
|
-
results << create_object(data_row)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
results
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def create_object values
|
38
|
-
hash = {}
|
39
|
-
columns.each do |column|
|
40
|
-
hash[column] = values[column_index(column)]
|
41
|
-
end
|
42
|
-
new hash
|
43
|
-
end
|
44
|
-
|
45
|
-
def conditions_match? conditions, data
|
46
|
-
conditions.each do |key, value|
|
47
|
-
return false unless data[column_index(key)].eql?(value.to_s)
|
48
|
-
end
|
49
|
-
true
|
50
|
-
end
|
51
|
-
|
52
30
|
end
|
53
31
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module FileDb
|
2
|
+
module System
|
3
|
+
class Database
|
4
|
+
|
5
|
+
attr_accessor :tables
|
6
|
+
|
7
|
+
def initialize data_directory
|
8
|
+
@data_directory = data_directory
|
9
|
+
create_database_if_not_exist!
|
10
|
+
load_tables!
|
11
|
+
end
|
12
|
+
|
13
|
+
def load_tables!
|
14
|
+
@tables = {}
|
15
|
+
Dir[File.join(@data_directory, "*.csv")].each do |filename|
|
16
|
+
next unless File.file?(filename)
|
17
|
+
load_table! filename
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def load_table! filename
|
22
|
+
@tables[cleared_tablename(filename)] = Table.new(filename, self)
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_database_if_not_exist!
|
26
|
+
return if exist_data_directory?
|
27
|
+
create_data_directory!
|
28
|
+
end
|
29
|
+
|
30
|
+
def drop_data_directory!
|
31
|
+
::FileUtils.rm_rf @data_directory
|
32
|
+
end
|
33
|
+
|
34
|
+
def save_to_disk table, content
|
35
|
+
File.write(table.filename, content)
|
36
|
+
end
|
37
|
+
|
38
|
+
def check_table! table_name
|
39
|
+
return if @tables[table_name]
|
40
|
+
create_table_file! table_name
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def cleared_tablename filename
|
46
|
+
filename = filename.gsub '.csv', ''
|
47
|
+
filename = filename.gsub @data_directory, ''
|
48
|
+
filename = filename.gsub '/', ''
|
49
|
+
filename.to_sym
|
50
|
+
end
|
51
|
+
|
52
|
+
def exist_data_directory?
|
53
|
+
File.exist? @data_directory
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_data_directory!
|
57
|
+
Dir.mkdir @data_directory
|
58
|
+
end
|
59
|
+
|
60
|
+
def create_table_file! table_name
|
61
|
+
File.write(File.join(@data_directory, "#{table_name}.csv"), '')
|
62
|
+
load_table! File.join(@data_directory, "#{table_name}.csv")
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module FileDb
|
2
|
+
module System
|
3
|
+
class Table
|
4
|
+
attr_accessor :entries_index_by, :filename
|
5
|
+
def initialize filename, database
|
6
|
+
@filename = filename
|
7
|
+
@database = database
|
8
|
+
@entries_index_by = {}
|
9
|
+
@entries_index_by[:id] = {}
|
10
|
+
@fields = {}
|
11
|
+
@fieldnames = {}
|
12
|
+
read_rows!
|
13
|
+
end
|
14
|
+
|
15
|
+
def read_rows!
|
16
|
+
File.foreach(@filename).with_index do |row, row_index|
|
17
|
+
if row_index == 0
|
18
|
+
set_fieldnames remove_line_break(row).split(',')
|
19
|
+
else
|
20
|
+
set_entry row.split(',')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def find id
|
26
|
+
hashed_by_id[id.to_s]
|
27
|
+
end
|
28
|
+
|
29
|
+
def all
|
30
|
+
hashed_by_id.values
|
31
|
+
end
|
32
|
+
|
33
|
+
def where conditions
|
34
|
+
found_elements = all
|
35
|
+
conditions.each do |key, value|
|
36
|
+
found_elements = found_elements.select do |entry|
|
37
|
+
entry[key.to_sym].eql?(value.to_s)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
found_elements
|
41
|
+
end
|
42
|
+
|
43
|
+
def hashed_by_id
|
44
|
+
entries_index_by[:id]
|
45
|
+
end
|
46
|
+
|
47
|
+
def next_id
|
48
|
+
hashed_by_id.keys.last.to_i + 1
|
49
|
+
end
|
50
|
+
|
51
|
+
def delete id
|
52
|
+
hashed_by_id.delete(id.to_s)
|
53
|
+
save_records!
|
54
|
+
end
|
55
|
+
|
56
|
+
def update_record object
|
57
|
+
set_fieldnames(object.class.columns) if @fields.empty?
|
58
|
+
data_to_save = {}
|
59
|
+
@fieldnames.each_with_index do |column, column_index|
|
60
|
+
field = @fields[column_index]
|
61
|
+
data_to_save[field] = object.send(field)
|
62
|
+
end
|
63
|
+
unless object.persisted?
|
64
|
+
data_to_save[:id] = next_id.to_s
|
65
|
+
object.id = data_to_save[:id]
|
66
|
+
end
|
67
|
+
@entries_index_by[:id][object.id.to_s] = data_to_save
|
68
|
+
save_records!
|
69
|
+
end
|
70
|
+
|
71
|
+
def save_records!
|
72
|
+
headline = @fields.keys.map { |field_key| @fields[field_key] }.join(',')
|
73
|
+
|
74
|
+
content = hashed_by_id.map do |index, entry|
|
75
|
+
@fields.keys.map do |identifier|
|
76
|
+
field = @fields[identifier]
|
77
|
+
entry[field.to_sym]
|
78
|
+
end.join(',')
|
79
|
+
end.join("\n")
|
80
|
+
|
81
|
+
@database.save_to_disk self, [headline, content].join("\n")
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
def set_fieldnames fieldnames
|
89
|
+
fieldnames.each_with_index do |column, column_index|
|
90
|
+
symbol_column = remove_line_break(column).to_sym
|
91
|
+
@fields[column_index] = symbol_column
|
92
|
+
@fieldnames[symbol_column] = column_index
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def set_entry entry
|
97
|
+
t_entry = {}
|
98
|
+
entry.each_with_index do |column, column_index|
|
99
|
+
t_entry[@fields[column_index].to_sym] = remove_line_break(column)
|
100
|
+
end
|
101
|
+
|
102
|
+
key_name = remove_line_break(entry[@fieldnames[:id]])
|
103
|
+
|
104
|
+
@entries_index_by[:id][key_name.to_s] = t_entry
|
105
|
+
end
|
106
|
+
|
107
|
+
def remove_line_break value
|
108
|
+
value.to_s.gsub "\n", ""
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
data/lib/file_db/table.rb
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
module FileDb
|
2
2
|
module Table
|
3
|
+
|
4
|
+
def database
|
5
|
+
DatabaseManager.instance.database
|
6
|
+
end
|
7
|
+
|
8
|
+
def table
|
9
|
+
database.check_table! table_name.to_sym
|
10
|
+
database.tables[table_name.to_sym]
|
11
|
+
end
|
12
|
+
|
3
13
|
def table_name
|
4
14
|
@table_name ||= self.new.class.to_s.gsub(/(.)([A-Z])/,'\1_\2').downcase
|
5
15
|
end
|
data/lib/file_db/version.rb
CHANGED
data/lib/file_db.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
require
|
1
|
+
require 'fileutils'
|
2
2
|
require "file_db/version"
|
3
|
-
require "file_db/system/
|
3
|
+
require "file_db/system/database"
|
4
|
+
require "file_db/system/table"
|
4
5
|
require "file_db/configuration"
|
5
|
-
require "file_db/
|
6
|
+
require "file_db/database_manager"
|
6
7
|
require "file_db/columns"
|
7
8
|
require "file_db/table"
|
8
9
|
require "file_db/data"
|
9
10
|
require "file_db/query"
|
10
|
-
require "file_db/convert"
|
11
11
|
require "file_db/model"
|
12
12
|
|
13
13
|
module FileDb
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: file_db
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Starke
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -75,12 +75,12 @@ files:
|
|
75
75
|
- lib/file_db.rb
|
76
76
|
- lib/file_db/columns.rb
|
77
77
|
- lib/file_db/configuration.rb
|
78
|
-
- lib/file_db/convert.rb
|
79
78
|
- lib/file_db/data.rb
|
80
|
-
- lib/file_db/
|
79
|
+
- lib/file_db/database_manager.rb
|
81
80
|
- lib/file_db/model.rb
|
82
81
|
- lib/file_db/query.rb
|
83
|
-
- lib/file_db/system/
|
82
|
+
- lib/file_db/system/database.rb
|
83
|
+
- lib/file_db/system/table.rb
|
84
84
|
- lib/file_db/table.rb
|
85
85
|
- lib/file_db/version.rb
|
86
86
|
homepage: https://github.com/robst/file_db
|
data/lib/file_db/convert.rb
DELETED
data/lib/file_db/database.rb
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
module FileDb
|
3
|
-
class Database
|
4
|
-
include Singleton
|
5
|
-
|
6
|
-
def self.database_check!
|
7
|
-
System::Check.run!
|
8
|
-
end
|
9
|
-
|
10
|
-
def search model
|
11
|
-
return unless File.exist?(table_file(model))
|
12
|
-
read_from_table model do |row|
|
13
|
-
yield row
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def delete_record record
|
18
|
-
records = []
|
19
|
-
read_from_table record.class do |row|
|
20
|
-
next if row[0]==record.id.to_s
|
21
|
-
records << build_object(record.class, row)
|
22
|
-
end
|
23
|
-
|
24
|
-
rebuild_table! record.class, records
|
25
|
-
end
|
26
|
-
|
27
|
-
def update_record record
|
28
|
-
records = []
|
29
|
-
read_from_table record.class do |row|
|
30
|
-
if row[0]==record.id.to_s
|
31
|
-
records << record
|
32
|
-
else
|
33
|
-
records << build_object(record.class, row)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
rebuild_table! record.class, records
|
37
|
-
end
|
38
|
-
|
39
|
-
def add_record record
|
40
|
-
write_to_table record.class, :a do
|
41
|
-
record
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def build_object clazz, data
|
48
|
-
hash = {}
|
49
|
-
clazz.columns.each do |column|
|
50
|
-
hash[column] = data[clazz.column_index(column)]
|
51
|
-
end
|
52
|
-
clazz.new hash
|
53
|
-
end
|
54
|
-
|
55
|
-
def read_from_table clazz
|
56
|
-
::CSV.foreach(table_file(clazz)) do |row|
|
57
|
-
yield(row)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def write_to_table clazz, mode = 'w'
|
62
|
-
::CSV.open(table_file(clazz), mode.to_s) do |csv|
|
63
|
-
[yield].flatten.each do |record|
|
64
|
-
csv << record.to_csv
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def rebuild_table! clazz, records
|
70
|
-
write_to_table clazz do
|
71
|
-
records
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def table_file model
|
76
|
-
File.join(data_directory, "#{model.table_name}.csv")
|
77
|
-
end
|
78
|
-
|
79
|
-
def data_directory
|
80
|
-
Configuration.configured(:data_directory)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
data/lib/file_db/system/check.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
module FileDb
|
2
|
-
module System
|
3
|
-
class Check
|
4
|
-
def self.run!
|
5
|
-
new.create_database_if_not_exist!
|
6
|
-
end
|
7
|
-
|
8
|
-
def create_database_if_not_exist!
|
9
|
-
return if exist_data_directory?
|
10
|
-
create_data_directory!
|
11
|
-
end
|
12
|
-
|
13
|
-
def exist_data_directory?
|
14
|
-
File.exist? data_directory
|
15
|
-
end
|
16
|
-
|
17
|
-
def create_data_directory!
|
18
|
-
Dir.mkdir data_directory
|
19
|
-
end
|
20
|
-
|
21
|
-
def data_directory
|
22
|
-
Configuration.configured(:data_directory)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|