jsondb 0.0.2 → 0.1.1

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.
@@ -0,0 +1,34 @@
1
+ module JSONdb
2
+
3
+ class Settings
4
+
5
+ include JSONdb::Logger
6
+
7
+ attr_accessor :folder, :writeable, :raise_errors, :log_enabled, :log_level, :log_file, :log_folder, :verbose
8
+
9
+ def initialize
10
+ @folder = ""
11
+ # read-only?
12
+ @writeable = true
13
+ # raise errors or return true or false
14
+ @raise_errors = true
15
+ # logs
16
+ @log_enabled = false
17
+ @log_level = :info
18
+ @log_file = "db.log"
19
+ @log_folder = nil
20
+ @verbose = false
21
+ #
22
+ end
23
+
24
+ def log_level=(level)
25
+ if allowed_log_level?(level)
26
+ @log_level = level
27
+ else
28
+ log("Log level not log_level_allowed", :error)
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -1,147 +1,95 @@
1
1
  module JSONdb
2
- class Table
3
-
4
- attr_accessor :updated_at
5
- attr_reader :fields, :records, :last_id, :persisted
6
-
7
- include Validation
8
-
9
- def initialize(name, folder, updated_at, writeable)
10
- allowed_name?(name)
11
-
12
- @name = name
13
- @folder = folder
14
- @writeable = writeable
15
-
16
- @structure_file = FileOps.new(@folder, "#{@name}_structure.json", 'table_structure', @writeable)
17
- @records_file = FileOps.new(@folder, "#{@name}_records.json", 'table_records', @writeable)
18
-
19
- # last_id
20
- @last_id = @structure_file.contents["last_id"]
21
-
22
- # Fields
23
- @fields = Hash.new
24
-
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)
38
- end
39
-
40
- @updated_at = Time.now.to_i if @structure_file.new_file
41
- @persisted = !@structure_file.new_file
42
-
43
- end
44
-
45
- def field(name)
46
- return @fields[name] ||= Field.new(@name)
47
- end
48
-
49
- def records
50
- return @records
51
- end
52
-
53
- def new_record
54
- @persisted = false
55
- @updated_at = Time.now.to_i
56
- return Record.new(@fields)
57
- end
58
-
59
- def query(array_fields = nil)
60
- return select(array_fields)
61
- end
62
-
63
- def select(array_fields = nil)
64
- return ResultSet.new(self, array_fields)
65
- end
66
-
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
78
-
79
- def update(record)
80
- @persisted = false
81
- @records[record.id] = record.update
82
- end
83
-
84
- def delete(record)
85
- @persisted = false
86
- @records.delete(record.id)
87
- end
88
-
89
- def drop
90
- @structure_file.destroy
91
- @records_file.destroy
92
- end
93
-
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
100
-
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
109
-
110
- def to_hash
111
- return { "name" => @name, "updated_at" => @updated_at }
112
- end
113
-
114
- def updated_at_time
115
- Time.at(@updated_at)
116
- end
117
-
118
- private
119
-
120
- def new_id
121
- @last_id = @last_id + 1
122
- return @last_id
123
- end
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
144
- end
145
-
146
- end
2
+
3
+ class Table
4
+
5
+ include JSONdb::Validations::Naming
6
+ include JSONdb::Logger
7
+ include JSONdb::Fields
8
+ include JSONdb::Records
9
+
10
+ attr_reader :created_at, :updated_at, :persisted
11
+ attr_accessor :timestamp
12
+
13
+ def initialize(name, new_table = true)
14
+ @name = name
15
+
16
+ @persisted = false
17
+
18
+ JSONdb.records[@name] = Hash.new
19
+ JSONdb.fields[@name] = Hash.new
20
+
21
+ set_defaults
22
+ add_main_fields
23
+ init_table(new_table)
24
+ end
25
+
26
+ def persist
27
+ @persisted = true
28
+ @file.contents = records_to_hash
29
+ @file.write
30
+ end
31
+
32
+ def to_hash
33
+ {
34
+ @name => {
35
+ "created_at" => @created_at,
36
+ "updated_at" => @updated_at,
37
+ "last_id" => @last_id,
38
+ "fields" => fields_to_hash
39
+ },
40
+ }
41
+ end
42
+
43
+ def destroy
44
+ @file.destroy
45
+ end
46
+
47
+ private
48
+
49
+ def new_id
50
+ @last_id = @last_id + 1
51
+ return @last_id
52
+ end
53
+
54
+ def set_defaults
55
+ @created_at = Time.now.to_i
56
+ @updated_at = Time.now.to_i
57
+
58
+ @timestamp = true
59
+ @id_autonumber = true
60
+ @last_id = 0
61
+ end
62
+
63
+ def init_table(new_table)
64
+ begin
65
+ if allowed_name?(@name)
66
+ @file = FileOps.new(JSONdb.settings.folder, "#{@name}.json", 'table', true)
67
+ @file.read
68
+
69
+ records_in_file = @file.contents
70
+
71
+ JSONdb.records[@name] = Hash.new
72
+ records_in_file.each do |key, values|
73
+ JSONdb.records[@name][values['id']] = Record.new(@name, values)
74
+ end
75
+
76
+ if new_table
77
+ @file.write
78
+ @persisted = true
79
+ log("Created data file for '#{@name}'.", :info)
80
+ else
81
+ @persisted = true
82
+ log("Loaded data file for '#{@name}'.", :info)
83
+ end
84
+ else
85
+ log("Could not initialize class for table '#{@name}'.", :error)
86
+ end
87
+ rescue
88
+ log("Could not initialize class for table '#{@name}'.", :error)
89
+ end
90
+ end
91
+
92
+
93
+ end
94
+
147
95
  end
@@ -0,0 +1,78 @@
1
+ module JSONdb
2
+
3
+ module Tables
4
+
5
+ include JSONdb::Logger
6
+
7
+ def table(name)
8
+ begin
9
+ return JSONdb.tables[name]
10
+ rescue
11
+ log("Table does not exists '#{name}'.", :error)
12
+ return nil
13
+ end
14
+ end
15
+
16
+ def table_names
17
+ JSONdb.tables.keys
18
+ end
19
+
20
+ def table_count
21
+ return table_names.count
22
+ end
23
+
24
+ def table_exists?(name)
25
+ JSONdb.tables.keys.include?(name)
26
+ end
27
+
28
+ def load_table(name)
29
+ begin
30
+ JSONdb.tables[name] = JSONdb::Table.new(name, false)
31
+ log("Loaded from disk '#{name}',", :info)
32
+ return true
33
+ rescue
34
+ log("Cannot load from disk '#{name}'", :error)
35
+ return false
36
+ end
37
+ end
38
+
39
+ def create_table(name)
40
+ if table_exists?(name)
41
+ log("Already exists '#{name}'.", :error)
42
+ return false
43
+ else
44
+ begin
45
+ JSONdb.tables[name] = JSONdb::Table.new(name, true)
46
+ log("Created '#{name}'.", :info)
47
+ return true
48
+ rescue
49
+ log("Cannot create '#{name}'", :error)
50
+ return false
51
+ end
52
+ end
53
+ end
54
+
55
+ def drop_table(name)
56
+ begin
57
+ JSONdb.tables[name].destroy
58
+ JSONdb.tables[name] = nil
59
+ JSONdb.tables.delete(name)
60
+ log("Deleted '#{name}'.", :info)
61
+ return true
62
+ rescue
63
+ log("Could not delete '#{name}'.", :error)
64
+ return false
65
+ end
66
+ end
67
+
68
+ def tables_to_hash
69
+ to_hash = Hash.new
70
+ JSONdb.tables.each do |key, values|
71
+ to_hash = to_hash.merge(values.to_hash)
72
+ end
73
+ return to_hash
74
+ end
75
+
76
+ end
77
+
78
+ end
@@ -0,0 +1,133 @@
1
+ module JSONdb
2
+
3
+ module Validations
4
+
5
+ module Naming
6
+
7
+ include JSONdb::Logger
8
+
9
+ def allowed_name?(name)
10
+ if (name =~ /^[a-zA-Z0-9_]+$/).nil?
11
+ log("Name '#{name}' not allowed. /^[a-zA-Z0-9_]+$/", :error)
12
+ return false
13
+ else
14
+ return true
15
+ end
16
+ end
17
+ end
18
+
19
+ module Types
20
+
21
+ include JSONdb::Logger
22
+
23
+ AllowedTypes = [
24
+ "String",
25
+ "Fixnum",
26
+ "Integer",
27
+ "Float",
28
+ "Time",
29
+ "Bool"
30
+ ]
31
+
32
+ def allowed_type?(type)
33
+ if AllowedTypes.include?(type.to_s)
34
+ return true
35
+ else
36
+ log("Validation: Type '#{type.to_s}' not allowed", :error)
37
+ return false
38
+ end
39
+ end
40
+
41
+ def validate_type(_class, _value)
42
+ case _class
43
+ when "Bool"
44
+ bool?(_class, _value)
45
+ when "String"
46
+ string?(_class, _value)
47
+ when "Fixnum", "Integer", "Float"
48
+ numeric?(_class, _value)
49
+ when "Time"
50
+ time?(_class, _value)
51
+ else
52
+ log("Validation: '#{_class}' type not allowed", :error)
53
+ return false
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def bool?(_class, _value)
60
+ case _value
61
+ when true, false
62
+ return true
63
+ else
64
+ log("Validation: Bool: Not a Bool type", :error)
65
+ return false
66
+ end
67
+ end
68
+
69
+ def string?(_class, _value)
70
+ if _class == _value.class.to_s
71
+ return true
72
+ else
73
+ log("Validation: #{_class}: Value '#{_value}' not allowed for '#{_class}' type", :error)
74
+ return false
75
+ end
76
+ end
77
+
78
+ def numeric?(_class, _value)
79
+ case _class
80
+ when "Fixnum", "Integer"
81
+ if _value.class.to_s == "Fixnum"
82
+ return true
83
+ else
84
+ log("Validation: '#{_value}' is not Integer", :error)
85
+ return false
86
+ end
87
+ when "Float"
88
+ case _value.class.to_s
89
+ when "Float"
90
+ return true
91
+ when "Fixnum"
92
+ return true
93
+ else
94
+ log("Validation: '#{_value} is not a Float type", :error)
95
+ end
96
+ else
97
+ log("Validation: '#{_value} is not a Numeric type", :error)
98
+ return false
99
+ end
100
+ end
101
+
102
+ def time?(_class, _value)
103
+ if eval(_value).class.to_s == "Time"
104
+ return true
105
+ else
106
+ log("Validation: '#{_value} is not a Time type", :error)
107
+ return false
108
+ end
109
+ end
110
+ end # Types
111
+
112
+ module Records
113
+
114
+ include JSONdb::Validations::Types
115
+
116
+ FieldsToNotVerify = ['id', 'created_at', 'updated_at']
117
+
118
+ def record_validates?(table_name, record)
119
+ table_fields = JSONdb.fields[table_name]
120
+ table_fields.each do |field_name, field_values|
121
+ if FieldsToNotVerify.include?(field_name) == false
122
+ actual_value = record.send field_name.to_sym
123
+ return false if field_values.nullable == false and actual_value.nil?
124
+ return false if validate_type(field_values.type, actual_value) == false
125
+ end
126
+ end
127
+ return true # true if no previous invalidation
128
+ end
129
+
130
+ end
131
+
132
+ end # Validations
133
+ end # JSONdb