jsondb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/jsondb.rb +11 -0
- data/lib/jsondb/db.rb +56 -0
- data/lib/jsondb/field.rb +47 -0
- data/lib/jsondb/file_ops.rb +71 -0
- data/lib/jsondb/record.rb +90 -0
- data/lib/jsondb/resultset.rb +107 -0
- data/lib/jsondb/table.rb +143 -0
- data/lib/jsondb/validation.rb +86 -0
- metadata +65 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f12ca944e1c7a4a054b787da398a96998aa78f37
|
4
|
+
data.tar.gz: 29b3f64e40cfd3cf4355b3fe3e9ce255105c7b86
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e01e62d7f226e0c81cd006294f54b5b628ba830d2fed14c1870eff0fd9484497817900e11ee4087bca5449131b9a613eeab385d5c75b73d83c3380774888cd15
|
7
|
+
data.tar.gz: 6a7324ba2fffb7c7cc5e9232dbe247b5e5e8bf30c4fba2daf81212161a7295ddb843e443fe89c0cafbe2b5223bb4a94bedd2696645523dcdb7c38b89b4c025d6
|
data/lib/jsondb.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#it depends on json_pure
|
2
|
+
require 'json/pure'
|
3
|
+
|
4
|
+
this_dir = File.dirname(__FILE__)
|
5
|
+
require File.join(this_dir, 'jsondb/file_ops')
|
6
|
+
require File.join(this_dir, 'jsondb/db')
|
7
|
+
require File.join(this_dir, 'jsondb/validation')
|
8
|
+
require File.join(this_dir, 'jsondb/table')
|
9
|
+
require File.join(this_dir, 'jsondb/field')
|
10
|
+
require File.join(this_dir, 'jsondb/record')
|
11
|
+
require File.join(this_dir, 'jsondb/resultset')
|
data/lib/jsondb/db.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
#db.rb
|
2
|
+
class Db
|
3
|
+
|
4
|
+
attr_reader :root, :tables, :writeable
|
5
|
+
|
6
|
+
def initialize(root, writeable = true)
|
7
|
+
@root = root
|
8
|
+
@writeable = writeable
|
9
|
+
@file = FileOps.new(@root, '_db.json', 'db', @writeable)
|
10
|
+
load_tables
|
11
|
+
end
|
12
|
+
|
13
|
+
def table(name)
|
14
|
+
@tables[name] ||= Table.new(name, @root, Time.now.to_i, @writeable)
|
15
|
+
end
|
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)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def table_drop(name)
|
26
|
+
@tables[name].drop
|
27
|
+
@tables.delete(name)
|
28
|
+
end
|
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
|
40
|
+
end
|
41
|
+
@file.contents['tables'][name] = { "name" => name, "updated_at" => table.updated_at }
|
42
|
+
end
|
43
|
+
return @file.save
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def load_tables
|
49
|
+
@tables_in_file = @file.contents['tables'] || Hash.new({})
|
50
|
+
@tables = Hash.new
|
51
|
+
@tables_in_file.each do |name, values|
|
52
|
+
@tables[name] = Table.new(name, @root, values['updated_at'], @writeable)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
data/lib/jsondb/field.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
class Field
|
2
|
+
|
3
|
+
include Validation
|
4
|
+
|
5
|
+
attr_reader :name, :type, :nullable, :default
|
6
|
+
|
7
|
+
def initialize(name)
|
8
|
+
allowed_name?(name)
|
9
|
+
|
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
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
class FileOps
|
2
|
+
|
3
|
+
attr_reader :writeable, :filename, :folder, :raw, :new_file
|
4
|
+
|
5
|
+
def initialize(folder, filename, filetype, writeable = true)
|
6
|
+
@folder = folder
|
7
|
+
@writeable = writeable
|
8
|
+
@filename = File.join(@folder, filename)
|
9
|
+
@filetype = filetype
|
10
|
+
if exists?(@folder)
|
11
|
+
load
|
12
|
+
else
|
13
|
+
raise "Folder '#{@folder}' does not exists."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def contents=(contents)
|
18
|
+
@contents = contents
|
19
|
+
end
|
20
|
+
|
21
|
+
def contents
|
22
|
+
@contents
|
23
|
+
end
|
24
|
+
|
25
|
+
def save
|
26
|
+
return false if @writeable == false
|
27
|
+
@file = File.open(@filename, 'w')
|
28
|
+
@raw = JSON.pretty_generate(@contents)
|
29
|
+
@file.write(@raw)
|
30
|
+
@file.close
|
31
|
+
@new_file = false
|
32
|
+
return true
|
33
|
+
end
|
34
|
+
|
35
|
+
def destroy
|
36
|
+
File.delete(@filename) if exists?(@filename)
|
37
|
+
end
|
38
|
+
|
39
|
+
def close
|
40
|
+
@file.close if @file
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def exists?(file)
|
46
|
+
File.exists?(File.expand_path(file))
|
47
|
+
end
|
48
|
+
|
49
|
+
def load
|
50
|
+
@new_file = !exists?(@filename)
|
51
|
+
if exists?(@filename)
|
52
|
+
@file = File.open(@filename, 'r')
|
53
|
+
@raw = @file.read
|
54
|
+
else
|
55
|
+
@raw = default_content
|
56
|
+
end
|
57
|
+
@contents = JSON.parse(@raw)
|
58
|
+
@file.close if @file
|
59
|
+
end
|
60
|
+
|
61
|
+
def default_content
|
62
|
+
case @filetype
|
63
|
+
when 'db'
|
64
|
+
'{ "tables": {} }'
|
65
|
+
when 'table_structure'
|
66
|
+
'{ "last_id" : 0, "fields": {} }'
|
67
|
+
when 'table_records'
|
68
|
+
'{ }'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
class Record
|
2
|
+
|
3
|
+
include Validation
|
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
|
18
|
+
|
19
|
+
def method_missing(name, *args)
|
20
|
+
attribute = name.to_s
|
21
|
+
|
22
|
+
if @fields.to_hash.keys.include?(attribute.sub('=', ''))
|
23
|
+
if attribute =~ /=$/
|
24
|
+
if @record[attribute] != args[0]
|
25
|
+
@record[attribute.sub('=', '')] = args[0]
|
26
|
+
@persisted = true
|
27
|
+
end
|
28
|
+
else
|
29
|
+
@record[attribute]
|
30
|
+
end
|
31
|
+
else
|
32
|
+
raise "Column '#{attribute.sub('=', '')}' do not exists"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def save_with_id(id)
|
37
|
+
self.created_at = Time.now.to_i
|
38
|
+
self.updated_at = Time.now.to_i
|
39
|
+
self.id = id
|
40
|
+
@new = false
|
41
|
+
@persisted = false
|
42
|
+
end
|
43
|
+
|
44
|
+
def update
|
45
|
+
self.updated_at = Time.now.to_i
|
46
|
+
@new = false
|
47
|
+
@persisted = false
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_hash
|
51
|
+
@record
|
52
|
+
end
|
53
|
+
|
54
|
+
def new?
|
55
|
+
@new
|
56
|
+
end
|
57
|
+
|
58
|
+
def persisted?
|
59
|
+
@persisted
|
60
|
+
end
|
61
|
+
|
62
|
+
def created_at
|
63
|
+
Time.at(@record['created_at'])
|
64
|
+
end
|
65
|
+
|
66
|
+
def persisted_at
|
67
|
+
Time.at(@record['updated_at'])
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def set_defaults
|
73
|
+
@fields.each do |name, values|
|
74
|
+
if values.default and @record[name].nil?
|
75
|
+
@record[name] = values.default
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# # TODO : Add Validation
|
81
|
+
|
82
|
+
# def save!
|
83
|
+
# raiseif(save, false, "Error saving the record.")
|
84
|
+
# end
|
85
|
+
|
86
|
+
# def save
|
87
|
+
# return @table_class.save
|
88
|
+
# end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
class ResultSet
|
2
|
+
|
3
|
+
include Validation
|
4
|
+
|
5
|
+
def initialize(table_class, array_fields = nil)
|
6
|
+
@fields = array_fields || table_class.fields.to_hash.keys
|
7
|
+
# actually it deletes the record!
|
8
|
+
@result = Hash.new()
|
9
|
+
table_class.records.each do |k, v|
|
10
|
+
@result[k] = v.dup
|
11
|
+
end
|
12
|
+
|
13
|
+
@equal = Hash.new
|
14
|
+
@min = Hash.new
|
15
|
+
@max = Hash.new
|
16
|
+
@like = Hash.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def equal(field, value)
|
20
|
+
@equal[field] = value
|
21
|
+
return self
|
22
|
+
end
|
23
|
+
|
24
|
+
def min(field, value)
|
25
|
+
@min[field] = value
|
26
|
+
return self
|
27
|
+
end
|
28
|
+
|
29
|
+
def max(field, value)
|
30
|
+
@max[field] = value
|
31
|
+
return self
|
32
|
+
end
|
33
|
+
|
34
|
+
def like(field, value)
|
35
|
+
@like[field] = value
|
36
|
+
return self
|
37
|
+
end
|
38
|
+
|
39
|
+
def result
|
40
|
+
result_equal if @equal.keys.count != 0
|
41
|
+
result_min if @min.keys.count != 0
|
42
|
+
result_max if @max.keys.count != 0
|
43
|
+
result_like if @like.keys.count != 0
|
44
|
+
return @result
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def result_equal
|
50
|
+
@equal.each do |col_name, col_value|
|
51
|
+
this_result = Array.new
|
52
|
+
@result.each do |id, record|
|
53
|
+
r = record.send col_name.to_sym
|
54
|
+
if r == col_value
|
55
|
+
this_result << id
|
56
|
+
end
|
57
|
+
end
|
58
|
+
remove_if_key_not_in(this_result)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def result_min
|
63
|
+
@min.each do |col_name, col_value|
|
64
|
+
this_result = Array.new
|
65
|
+
@result.each do |id, record|
|
66
|
+
r = record.send col_name.to_sym
|
67
|
+
if r >= col_value
|
68
|
+
this_result << id
|
69
|
+
end
|
70
|
+
end
|
71
|
+
remove_if_key_not_in(this_result)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def result_max
|
76
|
+
@max.each do |col_name, col_value|
|
77
|
+
this_result = Array.new
|
78
|
+
@result.each do |id, record|
|
79
|
+
r = record.send col_name.to_sym
|
80
|
+
if r <= col_value
|
81
|
+
this_result << id
|
82
|
+
end
|
83
|
+
end
|
84
|
+
remove_if_key_not_in(this_result)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def result_like
|
89
|
+
@like.each do |col_name, col_value|
|
90
|
+
this_result = Array.new
|
91
|
+
@result.each do |id, record|
|
92
|
+
r = record.send col_name.to_sym
|
93
|
+
if r =~ Regexp.new(col_value)
|
94
|
+
this_result << id
|
95
|
+
end
|
96
|
+
end
|
97
|
+
remove_if_key_not_in(this_result)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def remove_if_key_not_in(arr)
|
102
|
+
@result.keys.each do |key|
|
103
|
+
@result.delete(key) if arr.include?(key) == false
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
data/lib/jsondb/table.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
class Table
|
2
|
+
|
3
|
+
attr_accessor :updated_at
|
4
|
+
attr_reader :fields, :records, :last_id, :persisted
|
5
|
+
|
6
|
+
include Validation
|
7
|
+
|
8
|
+
def initialize(name, folder, updated_at, writeable)
|
9
|
+
allowed_name?(name)
|
10
|
+
|
11
|
+
@name = name
|
12
|
+
@folder = folder
|
13
|
+
@writeable = writeable
|
14
|
+
|
15
|
+
@structure_file = FileOps.new(@folder, "#{@name}_structure.json", 'table_structure', @writeable)
|
16
|
+
@records_file = FileOps.new(@folder, "#{@name}_records.json", 'table_records', @writeable)
|
17
|
+
|
18
|
+
# last_id
|
19
|
+
@last_id = @structure_file.contents["last_id"]
|
20
|
+
|
21
|
+
# Fields
|
22
|
+
@fields = Hash.new
|
23
|
+
|
24
|
+
if @structure_file.contents["fields"].keys.count
|
25
|
+
@structure_file.contents["fields"].each do |name, field|
|
26
|
+
@fields[name] ||= Field.new(name)
|
27
|
+
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
|
+
|
48
|
+
def records
|
49
|
+
return @records
|
50
|
+
end
|
51
|
+
|
52
|
+
def new_record
|
53
|
+
@persisted = false
|
54
|
+
@updated_at = Time.now.to_i
|
55
|
+
return Record.new(@fields)
|
56
|
+
end
|
57
|
+
|
58
|
+
def query(array_fields = nil)
|
59
|
+
return select(array_fields)
|
60
|
+
end
|
61
|
+
|
62
|
+
def select(array_fields = nil)
|
63
|
+
return ResultSet.new(self, array_fields)
|
64
|
+
end
|
65
|
+
|
66
|
+
def insert(record)
|
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
|
73
|
+
@persisted = false
|
74
|
+
return id
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def update(record)
|
79
|
+
@persisted = false
|
80
|
+
@records[record.id] = record.update
|
81
|
+
end
|
82
|
+
|
83
|
+
def delete(record)
|
84
|
+
@persisted = false
|
85
|
+
@records.delete(record.id)
|
86
|
+
end
|
87
|
+
|
88
|
+
def drop
|
89
|
+
@structure_file.destroy
|
90
|
+
@records_file.destroy
|
91
|
+
end
|
92
|
+
|
93
|
+
def persist
|
94
|
+
@structure_file.contents['last_id'] = @last_id
|
95
|
+
@structure_file.contents['fields'] = @fields.to_hash
|
96
|
+
@structure_file.save
|
97
|
+
|
98
|
+
@records_file.contents = {}
|
99
|
+
@records.each do |id, record|
|
100
|
+
@records_file.contents[id] = record.to_hash
|
101
|
+
end
|
102
|
+
@records_file.save
|
103
|
+
@updated_at = Time.now.to_i
|
104
|
+
@persisted = true
|
105
|
+
end
|
106
|
+
|
107
|
+
def to_hash
|
108
|
+
return { "name" => @name, "updated_at" => @updated_at }
|
109
|
+
end
|
110
|
+
|
111
|
+
def updated_at_time
|
112
|
+
Time.at(@updated_at)
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def new_id
|
118
|
+
@last_id = @last_id + 1
|
119
|
+
return @last_id
|
120
|
+
end
|
121
|
+
|
122
|
+
def add_main_fields
|
123
|
+
if @fields["id"].nil?
|
124
|
+
id_field = self.field('id')
|
125
|
+
id_field.type = "Fixnum"
|
126
|
+
id_field.nullable = false
|
127
|
+
id_field.default = 0
|
128
|
+
end
|
129
|
+
if @fields["created_at"].nil?
|
130
|
+
created_field = self.field('created_at')
|
131
|
+
created_field.type = "Fixnum"
|
132
|
+
created_field.nullable = false
|
133
|
+
created_field.default = 0
|
134
|
+
end
|
135
|
+
if @fields["updated_at"].nil?
|
136
|
+
updated_field = self.field('updated_at')
|
137
|
+
updated_field.type = "Fixnum"
|
138
|
+
updated_field.nullable = false
|
139
|
+
updated_field.default = 0
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Validation
|
2
|
+
|
3
|
+
def allowed_types
|
4
|
+
["String", "Fixnum", "Integer", "Float", "Time", "Bool"]
|
5
|
+
end
|
6
|
+
|
7
|
+
def allowed_name?(name)
|
8
|
+
if (name =~ /^[a-zA-Z0-9_]+$/).nil?
|
9
|
+
raise "Name not allowed. /^[a-zA-Z0-9_]+$/"
|
10
|
+
else
|
11
|
+
return true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def allowed?(type)
|
16
|
+
if allowed_types.include?(type.to_s)
|
17
|
+
return type.to_s
|
18
|
+
else
|
19
|
+
raise "Validation: Type '#{type.to_s}' not allowed"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate_type(_class, _value)
|
24
|
+
case _class
|
25
|
+
when "Bool"
|
26
|
+
bool?(_class, _value)
|
27
|
+
when "String"
|
28
|
+
string?(_class, _value)
|
29
|
+
when "Fixnum", "Integer", "Float"
|
30
|
+
numeric?(_class, _value)
|
31
|
+
when "Time"
|
32
|
+
time?(_class, _value)
|
33
|
+
else
|
34
|
+
raise "Validation: '#{_class}' type not allowed"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def bool?(_class, _value)
|
41
|
+
case _value
|
42
|
+
when true, false
|
43
|
+
return _value
|
44
|
+
else
|
45
|
+
raise "Validation: Bool: Not a Bool type"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def string?(_class, _value)
|
50
|
+
if _class == _value.class.to_s
|
51
|
+
return _value
|
52
|
+
else
|
53
|
+
raise "Validation: #{_class}: Value '#{_value}' not allowed for '#{_class}' type"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def numeric?(_class, _value)
|
58
|
+
case _class
|
59
|
+
when "Fixnum", "Integer"
|
60
|
+
if _value.class.to_s == "Fixnum"
|
61
|
+
return _value
|
62
|
+
else
|
63
|
+
raise "Validation: '#{_value}' is not Integer"
|
64
|
+
end
|
65
|
+
when "Float"
|
66
|
+
case eval(_value).class.to_s
|
67
|
+
when "Float"
|
68
|
+
return _value
|
69
|
+
when "Fixnum"
|
70
|
+
return _value.to_f
|
71
|
+
else
|
72
|
+
raise "Validation: '#{_value} is not a Float type"
|
73
|
+
end
|
74
|
+
else
|
75
|
+
raise "Validation: '#{_value} is not a Numeric type"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def time?(_class, _value)
|
80
|
+
if eval(_value).class.to_s != "Time"
|
81
|
+
raise "Validation: '#{_value} is not a Time type"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jsondb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Antonio Fernandez
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: json_pure
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.8.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.8.1
|
27
|
+
description: Local Database using JSON files
|
28
|
+
email: antoniofernandezvara@gmail.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- lib/jsondb.rb
|
34
|
+
- lib/jsondb/db.rb
|
35
|
+
- lib/jsondb/field.rb
|
36
|
+
- lib/jsondb/file_ops.rb
|
37
|
+
- lib/jsondb/record.rb
|
38
|
+
- lib/jsondb/resultset.rb
|
39
|
+
- lib/jsondb/table.rb
|
40
|
+
- lib/jsondb/validation.rb
|
41
|
+
homepage: http://fernandezvara.github.io/jsondb/
|
42
|
+
licenses:
|
43
|
+
- MIT
|
44
|
+
metadata: {}
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 2.2.2
|
62
|
+
signing_key:
|
63
|
+
specification_version: 4
|
64
|
+
summary: lib to manage tiny databases in plain JSON files
|
65
|
+
test_files: []
|