jsondb 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|