baza 0.0.14 → 0.0.15

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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +58 -13
  3. data/VERSION +1 -1
  4. data/baza.gemspec +15 -3
  5. data/include/db.rb +871 -865
  6. data/include/drivers/mysql/mysql.rb +104 -297
  7. data/include/drivers/mysql/mysql_column.rb +133 -0
  8. data/include/drivers/mysql/mysql_columns.rb +4 -127
  9. data/include/drivers/mysql/mysql_index.rb +76 -0
  10. data/include/drivers/mysql/mysql_indexes.rb +0 -73
  11. data/include/drivers/mysql/mysql_result.rb +42 -0
  12. data/include/drivers/mysql/mysql_result_java.rb +61 -0
  13. data/include/drivers/mysql/mysql_result_mysql2.rb +26 -0
  14. data/include/drivers/mysql/mysql_result_unbuffered.rb +72 -0
  15. data/include/drivers/mysql/mysql_sqlspecs.rb +1 -1
  16. data/include/drivers/mysql/mysql_table.rb +361 -0
  17. data/include/drivers/mysql/mysql_tables.rb +23 -381
  18. data/include/drivers/sqlite3/libknjdb_java_sqlite3.rb +17 -22
  19. data/include/drivers/sqlite3/libknjdb_sqlite3_ironruby.rb +13 -13
  20. data/include/drivers/sqlite3/sqlite3.rb +39 -105
  21. data/include/drivers/sqlite3/sqlite3_column.rb +146 -0
  22. data/include/drivers/sqlite3/sqlite3_columns.rb +17 -149
  23. data/include/drivers/sqlite3/sqlite3_index.rb +55 -0
  24. data/include/drivers/sqlite3/sqlite3_indexes.rb +0 -52
  25. data/include/drivers/sqlite3/sqlite3_result.rb +35 -0
  26. data/include/drivers/sqlite3/sqlite3_result_java.rb +39 -0
  27. data/include/drivers/sqlite3/sqlite3_table.rb +399 -0
  28. data/include/drivers/sqlite3/sqlite3_tables.rb +7 -403
  29. data/include/idquery.rb +19 -19
  30. data/include/model.rb +139 -139
  31. data/include/model_handler_sqlhelper.rb +74 -74
  32. data/spec/support/driver_columns_collection.rb +17 -0
  33. metadata +14 -2
@@ -0,0 +1,133 @@
1
+ #This class handels every MySQL-column, that can be returned from a table-object.
2
+ class Baza::Driver::Mysql::Column
3
+ attr_reader :args, :name
4
+
5
+ #Constructor. Should not be called manually.
6
+ def initialize(args)
7
+ @args = args
8
+ @name = @args[:data][:Field].to_sym
9
+ @db = @args[:db]
10
+ end
11
+
12
+ #Used to validate in Knj::Wrap_map.
13
+ def __object_unique_id__
14
+ return @name
15
+ end
16
+
17
+ def table_name
18
+ @args[:table_name]
19
+ end
20
+
21
+ #Returns the table-object that this column belongs to.
22
+ def table
23
+ return @db.tables[table_name]
24
+ end
25
+
26
+ #Returns all data of the column in the knjdb-format.
27
+ def data
28
+ return {
29
+ type: type,
30
+ name: name,
31
+ null: null?,
32
+ maxlength: maxlength,
33
+ default: default,
34
+ primarykey: primarykey?,
35
+ autoincr: autoincr?
36
+ }
37
+ end
38
+
39
+ def reload
40
+ @args[:data] = @db.query("SHOW FULL COLUMNS FROM `#{@db.esc_table(table_name)}` WHERE `Field` = '#{@db.esc(name)}'").fetch
41
+ @type = nil
42
+ end
43
+
44
+ #Returns the type of the column (integer, varchar etc.).
45
+ def type
46
+ if !@type
47
+ if match = @args[:data][:Type].match(/^([A-z]+)$/)
48
+ @maxlength = false
49
+ @type = match[0].to_sym
50
+ elsif match = @args[:data][:Type].match(/^decimal\((\d+),(\d+)\)$/)
51
+ @maxlength = "#{match[1]},#{match[2]}"
52
+ @type = :decimal
53
+ elsif match = @args[:data][:Type].match(/^enum\((.+)\)$/)
54
+ @maxlength = match[1]
55
+ @type = :enum
56
+ elsif match = @args[:data][:Type].match(/^(.+)\((\d+)\)/)
57
+ @maxlength = match[2].to_i
58
+ @type = match[1].to_sym
59
+ end
60
+
61
+ raise "Still not type from: '#{@args[:data][:Type]}'." if @type.to_s.strip.empty?
62
+ end
63
+
64
+ return @type
65
+ end
66
+
67
+ #Return true if the columns allows null. Otherwise false.
68
+ def null?
69
+ return false if @args[:data][:Null] == "NO"
70
+ return true
71
+ end
72
+
73
+ #Returns the maxlength.
74
+ def maxlength
75
+ self.type unless @maxlength
76
+ return @maxlength if @maxlength
77
+ return false
78
+ end
79
+
80
+ #Returns the default value for the column.
81
+ def default
82
+ return false if (self.type == :datetime || self.type == :date) && @args[:data][:Default].to_s.strip.empty?
83
+ return false if (self.type == :int || self.type == :bigint) && @args[:data][:Default].to_s.strip.empty?
84
+ return false if !@args[:data][:Default]
85
+ return @args[:data][:Default]
86
+ end
87
+
88
+ #Returns true if the column is the primary key. Otherwise false.
89
+ def primarykey?
90
+ return true if @args[:data][:Key] == "PRI"
91
+ return false
92
+ end
93
+
94
+ #Returns true if the column is auto-increasing. Otherwise false.
95
+ def autoincr?
96
+ return true if @args[:data][:Extra].include?("auto_increment")
97
+ return false
98
+ end
99
+
100
+ #Returns the comment for the column.
101
+ def comment
102
+ return @args[:data][:Comment]
103
+ end
104
+
105
+ #Drops the column from the table.
106
+ def drop
107
+ @args[:db].query("ALTER TABLE `#{@db.esc_table(@args[:table_name])}` DROP COLUMN `#{@db.esc_col(self.name)}`")
108
+ table.__send__(:remove_column_from_list, self)
109
+ return nil
110
+ end
111
+
112
+ #Changes the column properties by the given hash.
113
+ def change(data)
114
+ col_escaped = "`#{@db.esc_col(name)}`"
115
+ table_escape = "`#{@db.esc_table(table_name)}`"
116
+ newdata = data.clone
117
+
118
+ newdata[:name] = name unless newdata.key?(:name)
119
+ newdata[:type] = type unless newdata.key?(:type)
120
+ newdata[:maxlength] = maxlength if !newdata.key?(:maxlength) && maxlength
121
+ newdata[:null] = null? unless newdata.key?(:null)
122
+ newdata[:default] = self.default if !newdata.key?(:default) && default
123
+ newdata.delete(:primarykey) if newdata.key?(:primarykey)
124
+
125
+ drop_add = true if name.to_s != newdata[:name].to_s
126
+
127
+ table.__send__(:remove_column_from_list, self) if drop_add
128
+ @db.query("ALTER TABLE #{table_escape} CHANGE #{col_escaped} #{@args[:db].cols.data_sql(newdata)}")
129
+ @name = newdata[:name].to_sym
130
+ reload
131
+ table.__send__(:add_column_to_list, self) if drop_add
132
+ end
133
+ end
@@ -12,10 +12,10 @@ class Baza::Driver::Mysql::Columns
12
12
  raise "Invalid key: '#{key}' (#{key.class.name})." if !DATA_SQL_ALLOWED_KEYS.include?(key)
13
13
  end
14
14
 
15
- raise "No type given." if !data[:type]
15
+ raise "No type given." unless data[:type]
16
16
  type = data[:type].to_sym
17
17
 
18
- data[:maxlength] = 255 if type == :varchar and !data.key?(:maxlength)
18
+ data[:maxlength] = 255 if type == :varchar && !data.key?(:maxlength)
19
19
 
20
20
  sql = "`#{data[:name]}` #{type}"
21
21
  sql << "(#{data[:maxlength]})" if data[:maxlength]
@@ -25,138 +25,15 @@ class Baza::Driver::Mysql::Columns
25
25
 
26
26
  if data.key?(:default_func)
27
27
  sql << " DEFAULT #{data[:default_func]}"
28
- elsif data.key?(:default) and data[:default] != false
28
+ elsif data.key?(:default) && data[:default] != false
29
29
  sql << " DEFAULT '#{@args[:db].escape(data[:default])}'"
30
30
  end
31
31
 
32
32
  sql << " COMMENT '#{@args[:db].escape(data[:comment])}'" if data.key?(:comment)
33
- sql << " AFTER `#{@args[:db].esc_col(data[:after])}`" if data[:after] and !data[:first]
33
+ sql << " AFTER `#{@args[:db].esc_col(data[:after])}`" if data[:after] && !data[:first]
34
34
  sql << " FIRST" if data[:first]
35
35
  sql << " STORAGE #{data[:storage].to_s.upcase}" if data[:storage]
36
36
 
37
37
  return sql
38
38
  end
39
39
  end
40
-
41
- #This class handels every MySQL-column, that can be returned from a table-object.
42
- class Baza::Driver::Mysql::Columns::Column
43
- attr_reader :args, :name
44
-
45
- #Constructor. Should not be called manually.
46
- def initialize(args)
47
- @args = args
48
- @name = @args[:data][:Field].to_sym
49
- @db = @args[:db]
50
- end
51
-
52
- #Used to validate in Knj::Wrap_map.
53
- def __object_unique_id__
54
- return @name
55
- end
56
-
57
- #Returns the table-object that this column belongs to.
58
- def table
59
- return @args[:db].tables[@args[:table_name]]
60
- end
61
-
62
- #Returns all data of the column in the knjdb-format.
63
- def data
64
- return {
65
- type: type,
66
- name: name,
67
- null: null?,
68
- maxlength: maxlength,
69
- default: default,
70
- primarykey: primarykey?,
71
- autoincr: autoincr?
72
- }
73
- end
74
-
75
- #Returns the type of the column (integer, varchar etc.).
76
- def type
77
- if !@type
78
- if match = @args[:data][:Type].match(/^([A-z]+)$/)
79
- @maxlength = false
80
- @type = match[0].to_sym
81
- elsif match = @args[:data][:Type].match(/^decimal\((\d+),(\d+)\)$/)
82
- @maxlength = "#{match[1]},#{match[2]}"
83
- @type = :decimal
84
- elsif match = @args[:data][:Type].match(/^enum\((.+)\)$/)
85
- @maxlength = match[1]
86
- @type = :enum
87
- elsif match = @args[:data][:Type].match(/^(.+)\((\d+)\)/)
88
- @maxlength = match[2].to_i
89
- @type = match[1].to_sym
90
- end
91
-
92
- raise "Still not type from: '#{@args[:data][:Type]}'." if @type.to_s.strip.empty?
93
- end
94
-
95
- return @type
96
- end
97
-
98
- #Return true if the columns allows null. Otherwise false.
99
- def null?
100
- return false if @args[:data][:Null] == "NO"
101
- return true
102
- end
103
-
104
- #Returns the maxlength.
105
- def maxlength
106
- self.type if !@maxlength
107
- return @maxlength if @maxlength
108
- return false
109
- end
110
-
111
- #Returns the default value for the column.
112
- def default
113
- return false if (self.type == :datetime or self.type == :date) and @args[:data][:Default].to_s.strip.length <= 0
114
- return false if (self.type == :int or self.type == :bigint) and @args[:data][:Default].to_s.strip.length <= 0
115
- return false if !@args[:data][:Default]
116
- return @args[:data][:Default]
117
- end
118
-
119
- #Returns true if the column is the primary key. Otherwise false.
120
- def primarykey?
121
- return true if @args[:data][:Key] == "PRI"
122
- return false
123
- end
124
-
125
- #Returns true if the column is auto-increasing. Otherwise false.
126
- def autoincr?
127
- return true if @args[:data][:Extra].include?("auto_increment")
128
- return false
129
- end
130
-
131
- #Returns the comment for the column.
132
- def comment
133
- return @args[:data][:Comment]
134
- end
135
-
136
- #Drops the column from the table.
137
- def drop
138
- @args[:db].query("ALTER TABLE `#{@db.esc_table(@args[:table_name])}` DROP COLUMN `#{@db.esc_col(self.name)}`")
139
- table = self.table.remove_column_from_list(self)
140
- return nil
141
- end
142
-
143
- #Changes the column properties by the given hash.
144
- def change(data)
145
- col_escaped = "`#{@args[:db].esc_col(self.name)}`"
146
- table_escape = "`#{@args[:db].esc_table(self.table.name)}`"
147
- newdata = data.clone
148
-
149
- newdata[:name] = self.name if !newdata.key?(:name)
150
- newdata[:type] = self.type if !newdata.key?(:type)
151
- newdata[:maxlength] = self.maxlength if !newdata.key?(:maxlength) and self.maxlength
152
- newdata[:null] = self.null? if !newdata.key?(:null)
153
- newdata[:default] = self.default if !newdata.key?(:default) and self.default
154
- newdata.delete(:primarykey) if newdata.key?(:primarykey)
155
-
156
- drop_add = true if self.name.to_s != newdata[:name].to_s
157
-
158
- self.table.__send__(:remove_column_from_list, self) if drop_add
159
- @args[:db].query("ALTER TABLE #{table_escape} CHANGE #{col_escaped} #{@args[:db].cols.data_sql(newdata)}")
160
- self.table.__send__(:add_column_to_list, self) if drop_add
161
- end
162
- end
@@ -0,0 +1,76 @@
1
+ class Baza::Driver::Mysql::Index
2
+ attr_reader :args, :columns
3
+
4
+ def initialize(args)
5
+ @args = args
6
+ @columns = []
7
+ end
8
+
9
+ #Used to validate in Knj::Wrap_map.
10
+ def __object_unique_id__
11
+ return @args[:data][:Key_name]
12
+ end
13
+
14
+ def name
15
+ return @args[:data][:Key_name]
16
+ end
17
+
18
+ def table
19
+ return @args[:db].tables[@args[:table_name]]
20
+ end
21
+
22
+ def drop
23
+ sql = "DROP INDEX `#{self.name}` ON `#{self.table.name}`"
24
+
25
+ begin
26
+ @args[:db].query(sql)
27
+ rescue => e
28
+ #The index has already been dropped - ignore.
29
+ if e.message.index("check that column/key exists") != nil
30
+ #ignore.
31
+ else
32
+ raise e
33
+ end
34
+ end
35
+ end
36
+
37
+ def rename newname
38
+ newname = newname.to_sym
39
+ create_args = data
40
+ create_args[:name] = newname
41
+
42
+ drop
43
+ table.create_indexes([create_args])
44
+ @args[:data][:Key_name] = newname
45
+ end
46
+
47
+ def data
48
+ return {
49
+ name: name,
50
+ columns: @columns
51
+ }
52
+ end
53
+
54
+ #Returns true if the index is a unique-index.
55
+ def unique?
56
+ if @args[:data][:Index_type] == "UNIQUE"
57
+ return true
58
+ else
59
+ return false
60
+ end
61
+ end
62
+
63
+ #Returns true if the index is a primary-index.
64
+ def primary?
65
+ return true if @args[:data][:Key_name] == "PRIMARY"
66
+ return false
67
+ end
68
+
69
+ def to_s
70
+ return "#<Baza::Driver::Mysql::Index name: \"#{name}\", columns: #{@columns}, primary: #{primary?}, unique: #{unique?}>"
71
+ end
72
+
73
+ def inspect
74
+ to_s
75
+ end
76
+ end
@@ -3,76 +3,3 @@ class Baza::Driver::Mysql::Indexes
3
3
  @args = args
4
4
  end
5
5
  end
6
-
7
- class Baza::Driver::Mysql::Indexes::Index
8
- attr_reader :args, :columns
9
-
10
- def initialize(args)
11
- @args = args
12
- @columns = []
13
- end
14
-
15
- #Used to validate in Knj::Wrap_map.
16
- def __object_unique_id__
17
- return @args[:data][:Key_name]
18
- end
19
-
20
- def name
21
- return @args[:data][:Key_name]
22
- end
23
-
24
- def table
25
- return @args[:db].tables[@args[:table_name]]
26
- end
27
-
28
- def drop
29
- sql = "DROP INDEX `#{self.name}` ON `#{self.table.name}`"
30
-
31
- begin
32
- @args[:db].query(sql)
33
- rescue => e
34
- #The index has already been dropped - ignore.
35
- if e.message.index("check that column/key exists") != nil
36
- #ignore.
37
- else
38
- raise e
39
- end
40
- end
41
- end
42
-
43
- def rename newname
44
- newname = newname.to_sym
45
- create_args = data
46
- create_args[:name] = newname
47
-
48
- drop
49
- table.create_indexes([create_args])
50
- @args[:data][:Key_name] = newname
51
- end
52
-
53
- def data
54
- return {
55
- name: name,
56
- columns: @columns
57
- }
58
- end
59
-
60
- #Returns true if the index is a unique-index.
61
- def unique?
62
- if @args[:data][:Index_type] == "UNIQUE"
63
- return true
64
- else
65
- return false
66
- end
67
- end
68
-
69
- #Returns true if the index is a primary-index.
70
- def primary?
71
- return true if @args[:data][:Key_name] == "PRIMARY"
72
- return false
73
- end
74
-
75
- def to_s
76
- return "#<Baza::Driver::Mysql::Index name: \"#{name}\", columns: #{@columns}, primary: #{primary?}, unique: #{unique?}>"
77
- end
78
- end
@@ -0,0 +1,42 @@
1
+ #This class controls the results for the normal MySQL-driver.
2
+ class Baza::Driver::Mysql::Result
3
+ #Constructor. This should not be called manually.
4
+ def initialize(driver, result)
5
+ @driver = driver
6
+ @result = result
7
+ @mutex = Mutex.new
8
+
9
+ if @result
10
+ @keys = []
11
+ @result.fetch_fields.each do |key|
12
+ @keys << key.name.to_sym
13
+ end
14
+ end
15
+ end
16
+
17
+ #Returns a single result as a hash with symbols as keys.
18
+ def fetch
19
+ fetched = nil
20
+ @mutex.synchronize do
21
+ fetched = @result.fetch_row
22
+ end
23
+
24
+ return false unless fetched
25
+
26
+ ret = {}
27
+ count = 0
28
+ @keys.each do |key|
29
+ ret[key] = fetched[count]
30
+ count += 1
31
+ end
32
+
33
+ return ret
34
+ end
35
+
36
+ #Loops over every result yielding it.
37
+ def each
38
+ while data = self.fetch
39
+ yield(data)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,61 @@
1
+ #This class controls the result for the Java-MySQL-driver.
2
+ class Baza::Driver::Mysql::ResultJava
3
+ #Constructor. This should not be called manually.
4
+ def initialize(knjdb, opts, result)
5
+ @baza_db = knjdb
6
+ @result = result
7
+
8
+ if !opts.key?(:result) || opts[:result] == "hash"
9
+ @as_hash = true
10
+ elsif opts[:result] == "array"
11
+ @as_hash = false
12
+ else
13
+ raise "Unknown type of result: '#{opts[:result]}'."
14
+ end
15
+ end
16
+
17
+ #Reads meta-data about the query like keys and count.
18
+ def read_meta
19
+ @result.before_first
20
+ meta = @result.meta_data
21
+ @count = meta.column_count
22
+
23
+ @keys = []
24
+ 1.upto(@count) do |count|
25
+ @keys << meta.column_label(count).to_sym
26
+ end
27
+ end
28
+
29
+ def fetch
30
+ return false unless @result
31
+ self.read_meta unless @keys
32
+ status = @result.next
33
+
34
+ unless status
35
+ @result = nil
36
+ @keys = nil
37
+ @count = nil
38
+ return false
39
+ end
40
+
41
+ if @as_hash
42
+ ret = {}
43
+ 1.upto(@count) do |count|
44
+ ret[@keys[count - 1]] = @result.object(count)
45
+ end
46
+ else
47
+ ret = []
48
+ 1.upto(@count) do |count|
49
+ ret << @result.object(count)
50
+ end
51
+ end
52
+
53
+ return ret
54
+ end
55
+
56
+ def each
57
+ while data = self.fetch
58
+ yield(data)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,26 @@
1
+ #This class controls the result for the MySQL2 driver.
2
+ class Baza::Driver::Mysql::ResultMysql2
3
+ #Constructor. This should not be called manually.
4
+ def initialize(result)
5
+ @result = result
6
+ end
7
+
8
+ #Returns a single result.
9
+ def fetch
10
+ @enum = @result.to_enum if !@enum
11
+
12
+ begin
13
+ return @enum.next
14
+ rescue StopIteration
15
+ return false
16
+ end
17
+ end
18
+
19
+ #Loops over every single result yielding it.
20
+ def each
21
+ @result.each do |res|
22
+ next unless res #This sometimes happens when streaming results...
23
+ yield(res)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,72 @@
1
+ #This class controls the unbuffered result for the normal MySQL-driver.
2
+ class Baza::Driver::Mysql::ResultUnbuffered
3
+ #Constructor. This should not be called manually.
4
+ def initialize(conn, opts, result)
5
+ @conn = conn
6
+ @result = result
7
+
8
+ if !opts.key?(:result) || opts[:result] == "hash"
9
+ @as_hash = true
10
+ elsif opts[:result] == "array"
11
+ @as_hash = false
12
+ else
13
+ raise "Unknown type of result: '#{opts[:result]}'."
14
+ end
15
+ end
16
+
17
+ #Lods the keys for the object.
18
+ def load_keys
19
+ @keys = []
20
+ keys = @res.fetch_fields
21
+ keys.each do |key|
22
+ @keys << key.name.to_sym
23
+ end
24
+ end
25
+
26
+ #Returns a single result.
27
+ def fetch
28
+ if @enum
29
+ begin
30
+ ret = @enum.next
31
+ rescue StopIteration
32
+ @enum = nil
33
+ @res = nil
34
+ end
35
+ end
36
+
37
+ if !ret && !@res && !@enum
38
+ begin
39
+ @res = @conn.use_result
40
+ @enum = @res.to_enum
41
+ ret = @enum.next
42
+ rescue Mysql::Error
43
+ #Reset it to run non-unbuffered again and then return false.
44
+ @conn.query_with_result = true
45
+ return false
46
+ rescue StopIteration
47
+ sleep 0.1
48
+ retry
49
+ end
50
+ end
51
+
52
+ if !@as_hash
53
+ return ret
54
+ else
55
+ self.load_keys if !@keys
56
+
57
+ ret_h = {}
58
+ @keys.each_index do |key_no|
59
+ ret_h[@keys[key_no]] = ret[key_no]
60
+ end
61
+
62
+ return ret_h
63
+ end
64
+ end
65
+
66
+ #Loops over every single result yielding it.
67
+ def each
68
+ while data = self.fetch
69
+ yield(data)
70
+ end
71
+ end
72
+ end
@@ -2,4 +2,4 @@ class Baza::Driver::Mysql::Sqlspecs < Baza::Sqlspecs
2
2
  def strftime(val, colstr)
3
3
  return "DATE_FORMAT(#{colstr}, '#{val}')"
4
4
  end
5
- end
5
+ end