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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 24e147af83c09e392af68b2d35ba364359222dc0
4
- data.tar.gz: a14ad70583def016b74a250cfb147734cf5b5afb
3
+ metadata.gz: 08faf66085096d47a2174f7b9a830ffefab7a0c9
4
+ data.tar.gz: e04c84ba4d2b326abb841fde573d4aec1a71f420
5
5
  SHA512:
6
- metadata.gz: 00ef2f85b0fe7017354b1be6afb198dd71c204e8dd928692ee0123cbacf0e9d377bd42cb38965a39dd28002e0051a1ba7c9d5b935c96852ace50e7dde90ad709
7
- data.tar.gz: ab4e957e912e51413f85e3d08bd7445e6db12faa6af3b085e9e595e90454e3db78f04f2d0c557ada78b4661d1d8d7a122494f03bd198dde302828f354da35c58
6
+ metadata.gz: a320df01f983701a6d0d714705a87979484bbd0a8ccffb1e5ff77cfb72f78c9e8f7e5509d1434673251feaa119f4fa547a7af958811f4f49209fd23bac1ae6a5
7
+ data.tar.gz: 4a4cf440242030a75fb4f1aebd504b66d2d8e425ece1589706b0327556ce6af3c73c4a8fa71f57a6ae95bf487fd9ef96904bdd464569a932ca8f469bb8cc3fa1
data/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # FileDb
2
2
 
3
- You need to store data into a small type of database, like CSV and want a better way to handle it? So you can use `FileDb` for this. It stores all data for a model into CSV files and create accessor for you.
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.7.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
 
@@ -2,7 +2,6 @@ module FileDb
2
2
  module Configuration
3
3
  def self.configure options = {}
4
4
  @configuration = default_options.merge(options)
5
- System::Check.run!
6
5
  end
7
6
 
8
7
  def self.configured option
data/lib/file_db/data.rb CHANGED
@@ -5,37 +5,22 @@ module FileDb
5
5
  end
6
6
 
7
7
  def delete
8
- Database.instance.delete_record self
8
+ table.delete(id)
9
9
  end
10
10
 
11
11
  def save
12
- if persisted?
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
- private
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
- def current_id
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
@@ -1,7 +1,8 @@
1
1
  module FileDb
2
2
  class Model
3
+ extend FileDb::Columns
4
+ extend FileDb::Table
3
5
  extend FileDb::Query
4
6
  include FileDb::Data
5
- include FileDb::Convert
6
7
  end
7
8
  end
data/lib/file_db/query.rb CHANGED
@@ -1,7 +1,12 @@
1
1
  module FileDb
2
2
  module Query
3
- include FileDb::Columns
4
- include FileDb::Table
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
- where({})
19
+ table.all.map{ |entry| new entry }
15
20
  end
16
21
 
17
- def find id
18
- find_by(:id, id)
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
@@ -1,3 +1,3 @@
1
1
  module FileDb
2
- VERSION = "0.7.0"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/file_db.rb CHANGED
@@ -1,13 +1,13 @@
1
- require "csv"
1
+ require 'fileutils'
2
2
  require "file_db/version"
3
- require "file_db/system/check"
3
+ require "file_db/system/database"
4
+ require "file_db/system/table"
4
5
  require "file_db/configuration"
5
- require "file_db/database"
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.7.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-27 00:00:00.000000000 Z
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/database.rb
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/check.rb
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
@@ -1,11 +0,0 @@
1
- module FileDb
2
- module Convert
3
-
4
- def to_csv
5
- self.class.columns.inject([]) do |csv, column|
6
- csv << send(column)
7
- end
8
- end
9
- end
10
-
11
- end
@@ -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
@@ -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