jsondb 0.0.1 → 0.0.2
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/lib/jsondb/db.rb +50 -48
- data/lib/jsondb/field.rb +47 -44
- data/lib/jsondb/file_ops.rb +57 -55
- data/lib/jsondb/record.rb +70 -68
- data/lib/jsondb/resultset.rb +80 -78
- data/lib/jsondb/table.rb +116 -112
- data/lib/jsondb/validation.rb +68 -66
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42c6a44ad65e4d4f7fa846868284ab44c45daa10
|
4
|
+
data.tar.gz: 84a2a4690b49e879b6c2301aa89abdfa31a33395
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bffc48fe1baefaafd860eeea3e2d9c665c0a0691c95ca1743ee4ae790d849c002a2bdfd936c046ce9cf023d607891b80c6d0ccbac296b58db902a6325a5c41b
|
7
|
+
data.tar.gz: 3af5f5bac55261d94f1b04aa5b568ecb4826206b874d9dc8c9b3d5a229cf1e476b7d3b8bb8db2b52becf486882f4fd70e02dcfb04c5c649a0e4675b459da9b5a
|
data/lib/jsondb/db.rb
CHANGED
@@ -1,56 +1,58 @@
|
|
1
1
|
#db.rb
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
def table_add(name)
|
18
|
-
if @tables.keys.include?(name)
|
19
|
-
raise "Table '#{name}' already defined."
|
20
|
-
else
|
21
|
-
@tables[name] = Table.new(name, @root, Time.now.to_i, @writeable)
|
2
|
+
module JSONdb
|
3
|
+
class Db
|
4
|
+
|
5
|
+
attr_reader :root, :tables, :writeable
|
6
|
+
|
7
|
+
def initialize(root, writeable = true)
|
8
|
+
@root = root
|
9
|
+
@writeable = writeable
|
10
|
+
@file = FileOps.new(@root, '_db.json', 'db', @writeable)
|
11
|
+
load_tables
|
12
|
+
end
|
13
|
+
|
14
|
+
def table(name)
|
15
|
+
@tables[name] ||= Table.new(name, @root, Time.now.to_i, @writeable)
|
22
16
|
end
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
def table_names
|
31
|
-
@tables.keys
|
32
|
-
end
|
33
|
-
|
34
|
-
def persist
|
35
|
-
@file.contents['tables'] = {}
|
36
|
-
@tables.each do |name, table|
|
37
|
-
if table.persisted == false
|
38
|
-
table.updated_at = Time.now.to_i
|
39
|
-
table.persist
|
17
|
+
|
18
|
+
def table_add(name)
|
19
|
+
if @tables.keys.include?(name)
|
20
|
+
raise "Table '#{name}' already defined."
|
21
|
+
else
|
22
|
+
@tables[name] = Table.new(name, @root, Time.now.to_i, @writeable)
|
40
23
|
end
|
41
|
-
@file.contents['tables'][name] = { "name" => name, "updated_at" => table.updated_at }
|
42
24
|
end
|
43
|
-
return @file.save
|
44
|
-
end
|
45
25
|
|
46
|
-
|
26
|
+
def table_drop(name)
|
27
|
+
@tables[name].drop
|
28
|
+
@tables.delete(name)
|
29
|
+
end
|
47
30
|
|
48
|
-
|
49
|
-
|
50
|
-
@tables = Hash.new
|
51
|
-
@tables_in_file.each do |name, values|
|
52
|
-
@tables[name] = Table.new(name, @root, values['updated_at'], @writeable)
|
31
|
+
def table_names
|
32
|
+
@tables.keys
|
53
33
|
end
|
54
|
-
end
|
55
34
|
|
56
|
-
|
35
|
+
def persist
|
36
|
+
@file.contents['tables'] = {}
|
37
|
+
@tables.each do |name, table|
|
38
|
+
if table.persisted == false
|
39
|
+
table.updated_at = Time.now.to_i
|
40
|
+
table.persist
|
41
|
+
end
|
42
|
+
@file.contents['tables'][name] = { "name" => name, "updated_at" => table.updated_at }
|
43
|
+
end
|
44
|
+
return @file.save
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def load_tables
|
50
|
+
@tables_in_file = @file.contents['tables'] || Hash.new({})
|
51
|
+
@tables = Hash.new
|
52
|
+
@tables_in_file.each do |name, values|
|
53
|
+
@tables[name] = Table.new(name, @root, values['updated_at'], @writeable)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end # class
|
58
|
+
end # module
|
data/lib/jsondb/field.rb
CHANGED
@@ -1,47 +1,50 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
module JSONdb
|
2
|
+
class Field
|
3
|
+
|
4
|
+
include Validation
|
5
|
+
|
6
|
+
attr_reader :name, :type, :nullable, :default
|
7
|
+
|
8
|
+
def initialize(name)
|
9
|
+
allowed_name?(name)
|
10
|
+
|
11
|
+
@name = name
|
12
|
+
@nullable = true
|
13
|
+
@default = nil
|
14
|
+
@type = "String"
|
15
|
+
end
|
16
|
+
|
17
|
+
def type=(_class)
|
18
|
+
@type = allowed?(_class)
|
19
|
+
end
|
20
|
+
|
21
|
+
def type
|
22
|
+
@type
|
23
|
+
end
|
24
|
+
|
25
|
+
def nullable=(value)
|
26
|
+
@nullable = validate_type("Bool", value)
|
27
|
+
end
|
28
|
+
|
29
|
+
def nullable
|
30
|
+
@nullable
|
31
|
+
end
|
32
|
+
|
33
|
+
def default=(value)
|
34
|
+
@default = validate_type(@type, value)
|
35
|
+
end
|
36
|
+
|
37
|
+
def default
|
38
|
+
@default
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_hash
|
42
|
+
data = Hash.new
|
43
|
+
data['type'] = @type
|
44
|
+
data['nullable'] = @nullable
|
45
|
+
data['default'] = @default
|
46
|
+
data
|
47
|
+
end
|
9
48
|
|
10
|
-
@name = name
|
11
|
-
@nullable = true
|
12
|
-
@default = nil
|
13
|
-
@type = "String"
|
14
|
-
end
|
15
|
-
|
16
|
-
def type=(_class)
|
17
|
-
@type = allowed?(_class)
|
18
|
-
end
|
19
|
-
|
20
|
-
def type
|
21
|
-
@type
|
22
|
-
end
|
23
|
-
|
24
|
-
def nullable=(value)
|
25
|
-
@nullable = validate_type("Bool", value)
|
26
|
-
end
|
27
|
-
|
28
|
-
def nullable
|
29
|
-
@nullable
|
30
|
-
end
|
31
|
-
|
32
|
-
def default=(value)
|
33
|
-
@default = validate_type(@type, value)
|
34
|
-
end
|
35
|
-
|
36
|
-
def default
|
37
|
-
@default
|
38
|
-
end
|
39
|
-
|
40
|
-
def to_hash
|
41
|
-
data = Hash.new
|
42
|
-
data['type'] = @type
|
43
|
-
data['nullable'] = @nullable
|
44
|
-
data['default'] = @default
|
45
|
-
data
|
46
49
|
end
|
47
50
|
end
|
data/lib/jsondb/file_ops.rb
CHANGED
@@ -1,71 +1,73 @@
|
|
1
|
-
|
1
|
+
module JSONdb
|
2
|
+
class FileOps
|
2
3
|
|
3
|
-
|
4
|
+
attr_reader :writeable, :filename, :folder, :raw, :new_file
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
def initialize(folder, filename, filetype, writeable = true)
|
7
|
+
@folder = folder
|
8
|
+
@writeable = writeable
|
9
|
+
@filename = File.join(@folder, filename)
|
10
|
+
@filetype = filetype
|
11
|
+
if exists?(@folder)
|
12
|
+
load
|
13
|
+
else
|
14
|
+
raise "Folder '#{@folder}' does not exists."
|
15
|
+
end
|
14
16
|
end
|
15
|
-
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
def contents=(contents)
|
19
|
+
@contents = contents
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
def contents
|
23
|
+
@contents
|
24
|
+
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
26
|
+
def save
|
27
|
+
return false if @writeable == false
|
28
|
+
@file = File.open(@filename, 'w')
|
29
|
+
@raw = JSON.pretty_generate(@contents)
|
30
|
+
@file.write(@raw)
|
31
|
+
@file.close
|
32
|
+
@new_file = false
|
33
|
+
return true
|
34
|
+
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
def destroy
|
37
|
+
File.delete(@filename) if exists?(@filename)
|
38
|
+
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
40
|
+
def close
|
41
|
+
@file.close if @file
|
42
|
+
end
|
42
43
|
|
43
|
-
|
44
|
+
private
|
44
45
|
|
45
|
-
|
46
|
-
|
47
|
-
|
46
|
+
def exists?(file)
|
47
|
+
File.exists?(File.expand_path(file))
|
48
|
+
end
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
50
|
+
def load
|
51
|
+
@new_file = !exists?(@filename)
|
52
|
+
if exists?(@filename)
|
53
|
+
@file = File.open(@filename, 'r')
|
54
|
+
@raw = @file.read
|
55
|
+
else
|
56
|
+
@raw = default_content
|
57
|
+
end
|
58
|
+
@contents = JSON.parse(@raw)
|
59
|
+
@file.close if @file
|
56
60
|
end
|
57
|
-
@contents = JSON.parse(@raw)
|
58
|
-
@file.close if @file
|
59
|
-
end
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
62
|
+
def default_content
|
63
|
+
case @filetype
|
64
|
+
when 'db'
|
65
|
+
'{ "tables": {} }'
|
66
|
+
when 'table_structure'
|
67
|
+
'{ "last_id" : 0, "fields": {} }'
|
68
|
+
when 'table_records'
|
69
|
+
'{ }'
|
70
|
+
end
|
69
71
|
end
|
70
72
|
end
|
71
73
|
end
|
data/lib/jsondb/record.rb
CHANGED
@@ -1,90 +1,92 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
def initialize(fields, data = nil)
|
6
|
-
@fields = fields
|
7
|
-
if data.nil?
|
8
|
-
@record = Hash.new
|
9
|
-
@new = true
|
10
|
-
self.id = 0
|
11
|
-
else
|
12
|
-
@record = data
|
13
|
-
@new = false
|
14
|
-
end
|
15
|
-
@persisted = false
|
16
|
-
set_defaults # we need to apply again the defaults
|
17
|
-
end
|
1
|
+
module JSONdb
|
2
|
+
class Record
|
3
|
+
|
4
|
+
include Validation
|
18
5
|
|
19
|
-
|
20
|
-
|
6
|
+
def initialize(fields, data = nil)
|
7
|
+
@fields = fields
|
8
|
+
if data.nil?
|
9
|
+
@record = Hash.new
|
10
|
+
@new = true
|
11
|
+
self.id = 0
|
12
|
+
else
|
13
|
+
@record = data
|
14
|
+
@new = false
|
15
|
+
end
|
16
|
+
@persisted = false
|
17
|
+
set_defaults # we need to apply again the defaults
|
18
|
+
end
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
def method_missing(name, *args)
|
21
|
+
attribute = name.to_s
|
22
|
+
|
23
|
+
if @fields.to_hash.keys.include?(attribute.sub('=', ''))
|
24
|
+
if attribute =~ /=$/
|
25
|
+
if @record[attribute] != args[0]
|
26
|
+
@record[attribute.sub('=', '')] = args[0]
|
27
|
+
@persisted = true
|
28
|
+
end
|
29
|
+
else
|
30
|
+
@record[attribute]
|
27
31
|
end
|
28
32
|
else
|
29
|
-
|
33
|
+
raise "Column '#{attribute.sub('=', '')}' do not exists"
|
30
34
|
end
|
31
|
-
else
|
32
|
-
raise "Column '#{attribute.sub('=', '')}' do not exists"
|
33
35
|
end
|
34
|
-
end
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
37
|
+
def save_with_id(id)
|
38
|
+
self.created_at = Time.now.to_i
|
39
|
+
self.updated_at = Time.now.to_i
|
40
|
+
self.id = id
|
41
|
+
@new = false
|
42
|
+
@persisted = false
|
43
|
+
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
def update
|
46
|
+
self.updated_at = Time.now.to_i
|
47
|
+
@new = false
|
48
|
+
@persisted = false
|
49
|
+
end
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
def to_hash
|
52
|
+
@record
|
53
|
+
end
|
53
54
|
|
54
|
-
|
55
|
-
|
56
|
-
|
55
|
+
def new?
|
56
|
+
@new
|
57
|
+
end
|
57
58
|
|
58
|
-
|
59
|
-
|
60
|
-
|
59
|
+
def persisted?
|
60
|
+
@persisted
|
61
|
+
end
|
61
62
|
|
62
|
-
|
63
|
-
|
64
|
-
|
63
|
+
def created_at
|
64
|
+
Time.at(@record['created_at'])
|
65
|
+
end
|
65
66
|
|
66
|
-
|
67
|
-
|
68
|
-
|
67
|
+
def persisted_at
|
68
|
+
Time.at(@record['updated_at'])
|
69
|
+
end
|
69
70
|
|
70
|
-
|
71
|
+
private
|
71
72
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
def set_defaults
|
74
|
+
@fields.each do |name, values|
|
75
|
+
if values.default and @record[name].nil?
|
76
|
+
@record[name] = values.default
|
77
|
+
end
|
76
78
|
end
|
77
79
|
end
|
78
|
-
end
|
79
80
|
|
80
|
-
|
81
|
+
# # TODO : Add Validation
|
81
82
|
|
82
|
-
|
83
|
-
|
84
|
-
|
83
|
+
# def save!
|
84
|
+
# raiseif(save, false, "Error saving the record.")
|
85
|
+
# end
|
85
86
|
|
86
|
-
|
87
|
-
|
88
|
-
|
87
|
+
# def save
|
88
|
+
# return @table_class.save
|
89
|
+
# end
|
89
90
|
|
91
|
+
end
|
90
92
|
end
|
data/lib/jsondb/resultset.rb
CHANGED
@@ -1,107 +1,109 @@
|
|
1
|
-
|
1
|
+
module JSONdb
|
2
|
+
class ResultSet
|
2
3
|
|
3
|
-
|
4
|
+
include Validation
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
def initialize(table_class, array_fields = nil)
|
7
|
+
@fields = array_fields || table_class.fields.to_hash.keys
|
8
|
+
# actually it deletes the record!
|
9
|
+
@result = Hash.new()
|
10
|
+
table_class.records.each do |k, v|
|
11
|
+
@result[k] = v.dup
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
@equal = Hash.new
|
15
|
+
@min = Hash.new
|
16
|
+
@max = Hash.new
|
17
|
+
@like = Hash.new
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
def equal(field, value)
|
21
|
+
@equal[field] = value
|
22
|
+
return self
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
def min(field, value)
|
26
|
+
@min[field] = value
|
27
|
+
return self
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
def max(field, value)
|
31
|
+
@max[field] = value
|
32
|
+
return self
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
def like(field, value)
|
36
|
+
@like[field] = value
|
37
|
+
return self
|
38
|
+
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
40
|
+
def result
|
41
|
+
result_equal if @equal.keys.count != 0
|
42
|
+
result_min if @min.keys.count != 0
|
43
|
+
result_max if @max.keys.count != 0
|
44
|
+
result_like if @like.keys.count != 0
|
45
|
+
return @result
|
46
|
+
end
|
46
47
|
|
47
|
-
|
48
|
+
private
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
50
|
+
def result_equal
|
51
|
+
@equal.each do |col_name, col_value|
|
52
|
+
this_result = Array.new
|
53
|
+
@result.each do |id, record|
|
54
|
+
r = record.send col_name.to_sym
|
55
|
+
if r == col_value
|
56
|
+
this_result << id
|
57
|
+
end
|
56
58
|
end
|
59
|
+
remove_if_key_not_in(this_result)
|
57
60
|
end
|
58
|
-
remove_if_key_not_in(this_result)
|
59
61
|
end
|
60
|
-
end
|
61
62
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
63
|
+
def result_min
|
64
|
+
@min.each do |col_name, col_value|
|
65
|
+
this_result = Array.new
|
66
|
+
@result.each do |id, record|
|
67
|
+
r = record.send col_name.to_sym
|
68
|
+
if r >= col_value
|
69
|
+
this_result << id
|
70
|
+
end
|
69
71
|
end
|
72
|
+
remove_if_key_not_in(this_result)
|
70
73
|
end
|
71
|
-
remove_if_key_not_in(this_result)
|
72
74
|
end
|
73
|
-
end
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
76
|
+
def result_max
|
77
|
+
@max.each do |col_name, col_value|
|
78
|
+
this_result = Array.new
|
79
|
+
@result.each do |id, record|
|
80
|
+
r = record.send col_name.to_sym
|
81
|
+
if r <= col_value
|
82
|
+
this_result << id
|
83
|
+
end
|
82
84
|
end
|
85
|
+
remove_if_key_not_in(this_result)
|
83
86
|
end
|
84
|
-
remove_if_key_not_in(this_result)
|
85
87
|
end
|
86
|
-
end
|
87
88
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
89
|
+
def result_like
|
90
|
+
@like.each do |col_name, col_value|
|
91
|
+
this_result = Array.new
|
92
|
+
@result.each do |id, record|
|
93
|
+
r = record.send col_name.to_sym
|
94
|
+
if r =~ Regexp.new(col_value)
|
95
|
+
this_result << id
|
96
|
+
end
|
95
97
|
end
|
98
|
+
remove_if_key_not_in(this_result)
|
96
99
|
end
|
97
|
-
remove_if_key_not_in(this_result)
|
98
100
|
end
|
99
|
-
end
|
100
101
|
|
101
|
-
|
102
|
-
|
103
|
-
|
102
|
+
def remove_if_key_not_in(arr)
|
103
|
+
@result.keys.each do |key|
|
104
|
+
@result.delete(key) if arr.include?(key) == false
|
105
|
+
end
|
104
106
|
end
|
105
|
-
end
|
106
107
|
|
108
|
+
end
|
107
109
|
end
|
data/lib/jsondb/table.rb
CHANGED
@@ -1,143 +1,147 @@
|
|
1
|
-
|
1
|
+
module JSONdb
|
2
|
+
class Table
|
2
3
|
|
3
|
-
|
4
|
-
|
4
|
+
attr_accessor :updated_at
|
5
|
+
attr_reader :fields, :records, :last_id, :persisted
|
5
6
|
|
6
|
-
|
7
|
+
include Validation
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
def initialize(name, folder, updated_at, writeable)
|
10
|
+
allowed_name?(name)
|
11
|
+
|
12
|
+
@name = name
|
13
|
+
@folder = folder
|
14
|
+
@writeable = writeable
|
14
15
|
|
15
|
-
|
16
|
-
|
16
|
+
@structure_file = FileOps.new(@folder, "#{@name}_structure.json", 'table_structure', @writeable)
|
17
|
+
@records_file = FileOps.new(@folder, "#{@name}_records.json", 'table_records', @writeable)
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
# last_id
|
20
|
+
@last_id = @structure_file.contents["last_id"]
|
20
21
|
|
21
|
-
|
22
|
-
|
22
|
+
# Fields
|
23
|
+
@fields = Hash.new
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
if @structure_file.contents["fields"].keys.count
|
26
|
+
@structure_file.contents["fields"].each do |name, field|
|
27
|
+
@fields[name] ||= Field.new(name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
# add id and timestamps fields if not exists...
|
31
|
+
add_main_fields
|
32
|
+
|
33
|
+
# Fills records hash
|
34
|
+
@records_contents = @records_file.contents || {}
|
35
|
+
@records = Hash.new
|
36
|
+
@records_contents.each do |id, record|
|
37
|
+
@records[id] = Record.new(@fields, record)
|
27
38
|
end
|
28
|
-
end
|
29
|
-
# add id and timestamps fields if not exists...
|
30
|
-
add_main_fields
|
31
|
-
|
32
|
-
# Fills records hash
|
33
|
-
@records_contents = @records_file.contents || {}
|
34
|
-
@records = Hash.new
|
35
|
-
@records_contents.each do |id, record|
|
36
|
-
@records[id] = Record.new(@fields, record)
|
37
|
-
end
|
38
|
-
|
39
|
-
@updated_at = Time.now.to_i if @structure_file.new_file
|
40
|
-
@persisted = !@structure_file.new_file
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
def field(name)
|
45
|
-
return @fields[name] ||= Field.new(@name)
|
46
|
-
end
|
47
39
|
|
48
|
-
|
49
|
-
|
50
|
-
end
|
40
|
+
@updated_at = Time.now.to_i if @structure_file.new_file
|
41
|
+
@persisted = !@structure_file.new_file
|
51
42
|
|
52
|
-
|
53
|
-
@persisted = false
|
54
|
-
@updated_at = Time.now.to_i
|
55
|
-
return Record.new(@fields)
|
56
|
-
end
|
43
|
+
end
|
57
44
|
|
58
|
-
|
59
|
-
|
60
|
-
|
45
|
+
def field(name)
|
46
|
+
return @fields[name] ||= Field.new(@name)
|
47
|
+
end
|
61
48
|
|
62
|
-
|
63
|
-
|
64
|
-
|
49
|
+
def records
|
50
|
+
return @records
|
51
|
+
end
|
65
52
|
|
66
|
-
|
67
|
-
if record.id != 0
|
68
|
-
raise "Record already exists."
|
69
|
-
else
|
70
|
-
id = new_id
|
71
|
-
record.save_with_id(id)
|
72
|
-
@records[id] = record
|
53
|
+
def new_record
|
73
54
|
@persisted = false
|
74
|
-
|
55
|
+
@updated_at = Time.now.to_i
|
56
|
+
return Record.new(@fields)
|
75
57
|
end
|
76
|
-
end
|
77
58
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
59
|
+
def query(array_fields = nil)
|
60
|
+
return select(array_fields)
|
61
|
+
end
|
82
62
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
end
|
63
|
+
def select(array_fields = nil)
|
64
|
+
return ResultSet.new(self, array_fields)
|
65
|
+
end
|
87
66
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
67
|
+
def insert(record)
|
68
|
+
if record.id != 0
|
69
|
+
raise "Record already exists."
|
70
|
+
else
|
71
|
+
id = new_id
|
72
|
+
record.save_with_id(id)
|
73
|
+
@records[id] = record
|
74
|
+
@persisted = false
|
75
|
+
return id
|
76
|
+
end
|
77
|
+
end
|
92
78
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
79
|
+
def update(record)
|
80
|
+
@persisted = false
|
81
|
+
@records[record.id] = record.update
|
82
|
+
end
|
97
83
|
|
98
|
-
|
99
|
-
|
100
|
-
@
|
84
|
+
def delete(record)
|
85
|
+
@persisted = false
|
86
|
+
@records.delete(record.id)
|
101
87
|
end
|
102
|
-
@records_file.save
|
103
|
-
@updated_at = Time.now.to_i
|
104
|
-
@persisted = true
|
105
|
-
end
|
106
88
|
|
107
|
-
|
108
|
-
|
109
|
-
|
89
|
+
def drop
|
90
|
+
@structure_file.destroy
|
91
|
+
@records_file.destroy
|
92
|
+
end
|
110
93
|
|
111
|
-
|
112
|
-
|
113
|
-
|
94
|
+
def persist
|
95
|
+
@structure_file.contents['last_id'] = @last_id
|
96
|
+
@fields.each do |id, field|
|
97
|
+
@structure_file.contents['fields'][id] = field.to_hash
|
98
|
+
end
|
99
|
+
@structure_file.save
|
114
100
|
|
115
|
-
|
101
|
+
@records_file.contents = {}
|
102
|
+
@records.each do |id, record|
|
103
|
+
@records_file.contents[id] = record.to_hash
|
104
|
+
end
|
105
|
+
@records_file.save
|
106
|
+
@updated_at = Time.now.to_i
|
107
|
+
@persisted = true
|
108
|
+
end
|
116
109
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
end
|
110
|
+
def to_hash
|
111
|
+
return { "name" => @name, "updated_at" => @updated_at }
|
112
|
+
end
|
121
113
|
|
122
|
-
|
123
|
-
|
124
|
-
id_field = self.field('id')
|
125
|
-
id_field.type = "Fixnum"
|
126
|
-
id_field.nullable = false
|
127
|
-
id_field.default = 0
|
114
|
+
def updated_at_time
|
115
|
+
Time.at(@updated_at)
|
128
116
|
end
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def new_id
|
121
|
+
@last_id = @last_id + 1
|
122
|
+
return @last_id
|
134
123
|
end
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
124
|
+
|
125
|
+
def add_main_fields
|
126
|
+
if @fields["id"].nil?
|
127
|
+
id_field = self.field('id')
|
128
|
+
id_field.type = "Fixnum"
|
129
|
+
id_field.nullable = false
|
130
|
+
id_field.default = 0
|
131
|
+
end
|
132
|
+
if @fields["created_at"].nil?
|
133
|
+
created_field = self.field('created_at')
|
134
|
+
created_field.type = "Fixnum"
|
135
|
+
created_field.nullable = false
|
136
|
+
created_field.default = 0
|
137
|
+
end
|
138
|
+
if @fields["updated_at"].nil?
|
139
|
+
updated_field = self.field('updated_at')
|
140
|
+
updated_field.type = "Fixnum"
|
141
|
+
updated_field.nullable = false
|
142
|
+
updated_field.default = 0
|
143
|
+
end
|
140
144
|
end
|
141
|
-
end
|
142
145
|
|
146
|
+
end
|
143
147
|
end
|
data/lib/jsondb/validation.rb
CHANGED
@@ -1,86 +1,88 @@
|
|
1
|
-
module
|
1
|
+
module JSONdb
|
2
|
+
module Validation
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
def allowed_types
|
5
|
+
["String", "Fixnum", "Integer", "Float", "Time", "Bool"]
|
6
|
+
end
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
def allowed_name?(name)
|
9
|
+
if (name =~ /^[a-zA-Z0-9_]+$/).nil?
|
10
|
+
raise "Name not allowed. /^[a-zA-Z0-9_]+$/"
|
11
|
+
else
|
12
|
+
return true
|
13
|
+
end
|
12
14
|
end
|
13
|
-
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
def allowed?(type)
|
17
|
+
if allowed_types.include?(type.to_s)
|
18
|
+
return type.to_s
|
19
|
+
else
|
20
|
+
raise "Validation: Type '#{type.to_s}' not allowed"
|
21
|
+
end
|
20
22
|
end
|
21
|
-
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
24
|
+
def validate_type(_class, _value)
|
25
|
+
case _class
|
26
|
+
when "Bool"
|
27
|
+
bool?(_class, _value)
|
28
|
+
when "String"
|
29
|
+
string?(_class, _value)
|
30
|
+
when "Fixnum", "Integer", "Float"
|
31
|
+
numeric?(_class, _value)
|
32
|
+
when "Time"
|
33
|
+
time?(_class, _value)
|
34
|
+
else
|
35
|
+
raise "Validation: '#{_class}' type not allowed"
|
36
|
+
end
|
35
37
|
end
|
36
|
-
end
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
39
|
+
private
|
40
|
+
|
41
|
+
def bool?(_class, _value)
|
42
|
+
case _value
|
43
|
+
when true, false
|
44
|
+
return _value
|
45
|
+
else
|
46
|
+
raise "Validation: Bool: Not a Bool type"
|
47
|
+
end
|
46
48
|
end
|
47
|
-
end
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
def string?(_class, _value)
|
51
|
+
if _class == _value.class.to_s
|
52
|
+
return _value
|
53
|
+
else
|
54
|
+
raise "Validation: #{_class}: Value '#{_value}' not allowed for '#{_class}' type"
|
55
|
+
end
|
54
56
|
end
|
55
|
-
end
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
when "Float"
|
66
|
-
case eval(_value).class.to_s
|
58
|
+
def numeric?(_class, _value)
|
59
|
+
case _class
|
60
|
+
when "Fixnum", "Integer"
|
61
|
+
if _value.class.to_s == "Fixnum"
|
62
|
+
return _value
|
63
|
+
else
|
64
|
+
raise "Validation: '#{_value}' is not Integer"
|
65
|
+
end
|
67
66
|
when "Float"
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
case eval(_value).class.to_s
|
68
|
+
when "Float"
|
69
|
+
return _value
|
70
|
+
when "Fixnum"
|
71
|
+
return _value.to_f
|
72
|
+
else
|
73
|
+
raise "Validation: '#{_value} is not a Float type"
|
74
|
+
end
|
71
75
|
else
|
72
|
-
raise "Validation: '#{_value} is not a
|
76
|
+
raise "Validation: '#{_value} is not a Numeric type"
|
73
77
|
end
|
74
|
-
else
|
75
|
-
raise "Validation: '#{_value} is not a Numeric type"
|
76
78
|
end
|
77
|
-
end
|
78
79
|
|
79
|
-
|
80
|
-
|
81
|
-
|
80
|
+
def time?(_class, _value)
|
81
|
+
if eval(_value).class.to_s != "Time"
|
82
|
+
raise "Validation: '#{_value} is not a Time type"
|
83
|
+
end
|
82
84
|
end
|
85
|
+
|
83
86
|
end
|
84
|
-
|
85
|
-
end
|
86
87
|
|
88
|
+
end
|