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
@@ -1,47 +1,57 @@
1
1
  #This class handels SQLite3-specific behaviour.
2
2
  class Baza::Driver::Sqlite3
3
+ autoload :Table, "#{File.dirname(__FILE__)}/sqlite3_table"
4
+ autoload :Tables, "#{File.dirname(__FILE__)}/sqlite3_tables"
5
+ autoload :Column, "#{File.dirname(__FILE__)}/sqlite3_column"
6
+ autoload :Columns, "#{File.dirname(__FILE__)}/sqlite3_columns"
7
+ autoload :Index, "#{File.dirname(__FILE__)}/sqlite3_index"
8
+ autoload :Indexes, "#{File.dirname(__FILE__)}/sqlite3_indexes"
9
+ autoload :Result, "#{File.dirname(__FILE__)}/sqlite3_result"
10
+ autoload :ResultJava, "#{File.dirname(__FILE__)}/sqlite3_result_java"
11
+ autoload :Sqlspecs, "#{File.dirname(__FILE__)}/sqlite3_sqlspecs"
12
+
3
13
  attr_reader :baza, :conn, :sep_table, :sep_col, :sep_val, :symbolize
4
14
  attr_accessor :tables, :cols, :indexes
5
-
15
+
6
16
  #Helper to enable automatic registering of database using Baza::Db.from_object
7
17
  def self.from_object(args)
8
18
  if args[:object].class.name == "SQLite3::Database"
9
19
  return {
10
- :type => :success,
11
- :args => {
12
- :type => :sqlite3,
13
- :conn => args[:object]
20
+ type: :success,
21
+ args: {
22
+ type: :sqlite3,
23
+ conn: args[:object]
14
24
  }
15
25
  }
16
26
  end
17
-
27
+
18
28
  return nil
19
29
  end
20
-
30
+
21
31
  #Constructor. This should not be called manually.
22
32
  def initialize(baza_db_obj)
23
33
  @sep_table = "`"
24
34
  @sep_col = "`"
25
35
  @sep_val = "'"
26
-
36
+
27
37
  @baza_db = baza_db_obj
28
38
  @path = @baza_db.opts[:path] if @baza_db.opts[:path]
29
39
  @path = @baza_db.opts["path"] if @baza_db.opts["path"]
30
-
31
- @baza_db.opts[:subtype] = "java" if !@baza_db.opts.key?(:subtype) and RUBY_ENGINE == "jruby"
32
-
40
+
41
+ @baza_db.opts[:subtype] = "java" if !@baza_db.opts.key?(:subtype) && RUBY_ENGINE == "jruby"
42
+
33
43
  if @baza_db.opts[:conn]
34
44
  @conn = @baza_db.opts[:conn]
35
45
  else
36
46
  raise "No path was given." if !@path
37
-
47
+
38
48
  if @baza_db.opts[:subtype] == "java"
39
49
  if @baza_db.opts[:sqlite_driver]
40
50
  require @baza_db.opts[:sqlite_driver]
41
51
  else
42
52
  require "#{File.dirname(__FILE__)}/../../../jruby/sqlitejdbc-v056.jar"
43
53
  end
44
-
54
+
45
55
  require "java"
46
56
  import "org.sqlite.JDBC"
47
57
  @conn = java.sql.DriverManager::getConnection("jdbc:sqlite:#{@baza_db.opts[:path]}")
@@ -55,7 +65,7 @@ class Baza::Driver::Sqlite3
55
65
  end
56
66
  end
57
67
  end
58
-
68
+
59
69
  #Executes a query against the driver.
60
70
  def query(string)
61
71
  if @baza_db.opts[:subtype] == :rhodes
@@ -74,132 +84,56 @@ class Baza::Driver::Sqlite3
74
84
  return Baza::Driver::Sqlite3::Result.new(self, @conn.execute(string))
75
85
  end
76
86
  end
77
-
87
+
78
88
  #SQLite3 driver doesnt support unbuffered queries??
79
89
  alias query_ubuf query
80
-
90
+
81
91
  #Escapes a string to be safe to used in a query.
82
92
  def escape(string)
83
93
  #This code is taken directly from the documentation so we dont have to rely on the SQLite3::Database class. This way it can also be used with JRuby and IronRuby...
84
94
  #http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html
85
95
  return string.to_s.gsub(/'/, "''")
86
96
  end
87
-
97
+
88
98
  #Escapes a string to be used as a column.
89
99
  def esc_col(string)
90
100
  string = string.to_s
91
101
  raise "Invalid column-string: #{string}" if string.index(@sep_col) != nil
92
102
  return string
93
103
  end
94
-
104
+
95
105
  alias :esc_table :esc_col
96
106
  alias :esc :escape
97
-
107
+
98
108
  #Returns the last inserted ID.
99
- def lastID
109
+ def last_id
100
110
  return @conn.last_insert_row_id if @conn.respond_to?(:last_insert_row_id)
101
- return self.query("SELECT last_insert_rowid() AS id").fetch[:id].to_i
111
+ return query("SELECT last_insert_rowid() AS id").fetch[:id].to_i
102
112
  end
103
-
113
+
104
114
  #Closes the connection to the database.
105
115
  def close
106
116
  @conn.close
107
117
  end
108
-
118
+
109
119
  #Starts a transaction, yields the database and commits.
110
120
  def transaction
111
121
  @conn.transaction do
112
122
  yield(@baza_db)
113
123
  end
114
124
  end
115
-
125
+
116
126
  def insert_multi(tablename, arr_hashes, args = nil)
117
- sql = [] if args and args[:return_sql]
118
-
127
+ sql = [] if args && args[:return_sql]
128
+
119
129
  @baza_db.transaction do
120
130
  arr_hashes.each do |hash|
121
131
  res = @baza_db.insert(tablename, hash, args)
122
- sql << res if args and args[:return_sql]
132
+ sql << res if args && args[:return_sql]
123
133
  end
124
134
  end
125
-
126
- return sql if args and args[:return_sql]
127
- return nil
128
- end
129
- end
130
135
 
131
- #This class handels results when running in JRuby.
132
- class Baza::Driver::Sqlite3::ResultJava
133
- def initialize(driver, rs)
134
- @index = 0
135
- retkeys = driver.knjdb.opts[:return_keys]
136
-
137
- if rs
138
- metadata = rs.getMetaData
139
- columns_count = metadata.getColumnCount
140
-
141
- @rows = []
142
- while rs.next
143
- row_data = {}
144
- for i in (1..columns_count)
145
- col_name = metadata.getColumnName(i).to_sym
146
- row_data[col_name] = rs.getString(i)
147
- end
148
-
149
- @rows << row_data
150
- end
151
- end
152
- end
153
-
154
- #Returns a single result.
155
- def fetch
156
- return false if !@rows
157
- ret = @rows[@index]
158
- return false if !ret
159
- @index += 1
160
- return ret
161
- end
162
-
163
- #Loops over every result and yields them.
164
- def each
165
- while data = self.fetch
166
- yield(data)
167
- end
136
+ return sql if args && args[:return_sql]
137
+ return nil
168
138
  end
169
139
  end
170
-
171
- #This class handels the result when running MRI (or others).
172
- class Baza::Driver::Sqlite3::Result
173
- #Constructor. This should not be called manually.
174
- def initialize(driver, result_array)
175
- @result_array = result_array
176
- @index = 0
177
- end
178
-
179
- #Returns a single result.
180
- def fetch
181
- result_hash = @result_array[@index]
182
- return false if !result_hash
183
- @index += 1
184
-
185
- ret = {}
186
- result_hash.each do |key, val|
187
- if (Float(key) rescue false)
188
- #do nothing.
189
- elsif !key.is_a?(Symbol)
190
- ret[key.to_sym] = val
191
- else
192
- ret[key] = val
193
- end
194
- end
195
-
196
- return ret
197
- end
198
-
199
- #Loops over every result yielding them.
200
- def each
201
- while data = self.fetch
202
- yield(data)
203
- end
204
- end
205
- end
@@ -0,0 +1,146 @@
1
+ #This class handels all the SQLite3-columns.
2
+ class Baza::Driver::Sqlite3::Column
3
+ attr_reader :args
4
+
5
+ #Constructor. This should not be called manually.
6
+ def initialize(args)
7
+ @args = args
8
+ @db = @args[:db]
9
+ end
10
+
11
+ #Returns the name of the column.
12
+ def name
13
+ return @args[:data][:name].to_sym
14
+ end
15
+
16
+ def table_name
17
+ @args[:table_name]
18
+ end
19
+
20
+ #Returns the columns table-object.
21
+ def table
22
+ return @db.tables[table_name]
23
+ end
24
+
25
+ #Returns the data of the column as a hash in knjdb-format.
26
+ def data
27
+ return {
28
+ type: type,
29
+ name: name,
30
+ null: null?,
31
+ maxlength: maxlength,
32
+ default: default,
33
+ primarykey: primarykey?,
34
+ autoincr: autoincr?
35
+ }
36
+ end
37
+
38
+ #Returns the type of the column.
39
+ def type
40
+ if !@type
41
+ if match = @args[:data][:type].match(/^([A-z]+)$/)
42
+ @maxlength = false
43
+ type = match[0].to_sym
44
+ elsif match = @args[:data][:type].match(/^decimal\((\d+),(\d+)\)$/)
45
+ @maxlength = "#{match[1]},#{match[2]}"
46
+ type = :decimal
47
+ elsif match = @args[:data][:type].match(/^enum\((.+)\)$/)
48
+ @maxlength = match[1]
49
+ type = :enum
50
+ elsif match = @args[:data][:type].match(/^(.+)\((\d+)\)$/)
51
+ @maxlength = match[2]
52
+ type = match[1].to_sym
53
+ elsif @args[:data].key?(:type) and @args[:data][:type].to_s == ""
54
+ #A type can actually be empty in SQLite... Wtf?
55
+ return @args[:data][:type]
56
+ end
57
+
58
+ if type == :integer
59
+ @type = :int
60
+ else
61
+ @type = type
62
+ end
63
+
64
+ raise "Still not type? (#{@args[:data]})" if @type.to_s.strip.empty?
65
+ end
66
+
67
+ return @type
68
+ end
69
+
70
+ #Returns true if the column allows null. Otherwise false.
71
+ def null?
72
+ return false if @args[:data][:notnull].to_i == 1
73
+ return true
74
+ end
75
+
76
+ #Returns the maxlength of the column.
77
+ def maxlength
78
+ self.type if !@maxlength
79
+ return @maxlength if @maxlength
80
+ return false
81
+ end
82
+
83
+ #Returns the default value of the column.
84
+ def default
85
+ def_val = @args[:data][:dflt_value]
86
+
87
+ if def_val && match = def_val.match(/\A'(.*)'\Z/)
88
+ return match[1]
89
+ end
90
+
91
+ return false if @args[:data][:dflt_value].to_s.empty?
92
+ return def_val
93
+ end
94
+
95
+ #Returns true if the column is the primary key.
96
+ def primarykey?
97
+ return false if @args[:data][:pk].to_i == 0
98
+ return true
99
+ end
100
+
101
+ #Returns true if the column is auto-increasing.
102
+ def autoincr?
103
+ return true if @args[:data][:pk].to_i == 1 && @args[:data][:type].to_sym == :integer
104
+ return false
105
+ end
106
+
107
+ #Drops the column from the table.
108
+ def drop
109
+ table.copy(drops: name)
110
+ end
111
+
112
+ def reload
113
+ @db.q("PRAGMA table_info(`#{@db.esc_table(table_name)}`)") do |data|
114
+ next unless data[:name] == @args[:data][:name]
115
+ @args[:data] = data
116
+ @type = nil
117
+ return
118
+ end
119
+
120
+ raise "Could not find data for column: #{table_name}.#{name}"
121
+ end
122
+
123
+ #Changes data on the column. Like the name, type, maxlength or whatever.
124
+ def change(data)
125
+ newdata = data.clone
126
+
127
+ newdata[:name] = name unless newdata.key?(:name)
128
+ newdata[:type] = type unless newdata.key?(:type)
129
+ newdata[:maxlength] = maxlength unless newdata.key?(:maxlength) && maxlength
130
+ newdata[:null] = null? unless newdata.key?(:null)
131
+ newdata[:default] = default unless newdata.key?(:default)
132
+ newdata[:primarykey] = primarykey? unless newdata.key?(:primarykey)
133
+
134
+ @type = nil
135
+ @maxlength = nil
136
+
137
+ new_table = table.copy(
138
+ alter_columns: {
139
+ name.to_sym => newdata
140
+ }
141
+ )
142
+
143
+ @args[:data][:name] = newdata[:name].to_s
144
+ reload
145
+ end
146
+ end
@@ -1,179 +1,47 @@
1
1
  #This class handels the SQLite3-specific behaviour for columns.
2
2
  class Baza::Driver::Sqlite3::Columns
3
3
  attr_reader :db
4
-
4
+
5
5
  #Constructor. This should not be called manually.
6
6
  def initialize(args)
7
7
  @args = args
8
8
  end
9
-
9
+
10
10
  DATA_SQL_ALLOWED_KEYS = [:name, :type, :maxlength, :autoincr, :primarykey, :null, :default, :default_func, :renames, :after, :renames]
11
11
  #Returns SQL for a knjdb-compatible hash.
12
12
  def data_sql(data)
13
13
  data.each do |key, val|
14
14
  raise "Invalid key: '#{key}' (#{key.class.name})." unless DATA_SQL_ALLOWED_KEYS.include?(key)
15
15
  end
16
-
17
- raise "No type given." if !data[:type]
16
+
17
+ raise "No type given." unless data[:type]
18
18
  type = data[:type].to_sym
19
-
19
+
20
20
  if type == :enum
21
21
  type = :varchar
22
22
  data.delete(:maxlength)
23
23
  end
24
-
25
- data[:maxlength] = 255 if type == :varchar and !data.key?(:maxlength)
26
- data[:maxlength] = 11 if type == :int and !data.key?(:maxlength) and !data[:autoincr] and !data[:primarykey]
27
- type = :integer if @args[:db].int_types.index(type) and (data[:autoincr] or data[:primarykey])
28
-
24
+
25
+ data[:maxlength] = 255 if type == :varchar && !data.key?(:maxlength)
26
+ data[:maxlength] = 11 if type == :int && !data.key?(:maxlength) && !data[:autoincr] && !data[:primarykey]
27
+ type = :integer if @args[:db].int_types.index(type) && (data[:autoincr] || data[:primarykey])
28
+
29
29
  sql = "`#{data[:name]}` #{type}"
30
- sql << "(#{data[:maxlength]})" if data[:maxlength] and !data[:autoincr]
30
+ sql << "(#{data[:maxlength]})" if data[:maxlength] && !data[:autoincr]
31
31
  sql << " PRIMARY KEY" if data[:primarykey]
32
32
  sql << " AUTOINCREMENT" if data[:autoincr]
33
-
34
- if !data[:null] and data.key?(:null)
33
+
34
+ if !data[:null] && data.key?(:null)
35
35
  sql << " NOT NULL"
36
- data[:default] = 0 if type == :int if !data.key?(:default) or !data[:default]
36
+ data[:default] = 0 if type == :int if !data.key?(:default) || !data[:default]
37
37
  end
38
-
38
+
39
39
  if data.key?(:default_func)
40
40
  sql << " DEFAULT #{data[:default_func]}"
41
- elsif data.key?(:default) and data[:default] != false
41
+ elsif data.key?(:default) && data[:default] != false
42
42
  sql << " DEFAULT '#{@args[:db].escape(data[:default])}'"
43
43
  end
44
-
44
+
45
45
  return sql
46
46
  end
47
47
  end
48
-
49
- #This class handels all the SQLite3-columns.
50
- class Baza::Driver::Sqlite3::Columns::Column
51
- attr_reader :args
52
-
53
- #Constructor. This should not be called manually.
54
- def initialize(args)
55
- @args = args
56
- @db = @args[:db]
57
- end
58
-
59
- #Returns the name of the column.
60
- def name
61
- return @args[:data][:name]
62
- end
63
-
64
- #Returns the columns table-object.
65
- def table
66
- return @db.tables[@args[:table_name]]
67
- end
68
-
69
- #Returns the data of the column as a hash in knjdb-format.
70
- def data
71
- return {
72
- :type => self.type,
73
- :name => self.name,
74
- :null => self.null?,
75
- :maxlength => self.maxlength,
76
- :default => self.default,
77
- :primarykey => self.primarykey?,
78
- :autoincr => self.autoincr?
79
- }
80
- end
81
-
82
- #Returns the type of the column.
83
- def type
84
- if !@type
85
- if match = @args[:data][:type].match(/^([A-z]+)$/)
86
- @maxlength = false
87
- type = match[0].to_sym
88
- elsif match = @args[:data][:type].match(/^decimal\((\d+),(\d+)\)$/)
89
- @maxlength = "#{match[1]},#{match[2]}"
90
- type = :decimal
91
- elsif match = @args[:data][:type].match(/^enum\((.+)\)$/)
92
- @maxlength = match[1]
93
- type = :enum
94
- elsif match = @args[:data][:type].match(/^(.+)\((\d+)\)$/)
95
- @maxlength = match[2]
96
- type = match[1].to_sym
97
- elsif @args[:data].key?(:type) and @args[:data][:type].to_s == ""
98
- #A type can actually be empty in SQLite... Wtf?
99
- return @args[:data][:type]
100
- end
101
-
102
- if type == :integer
103
- @type = :int
104
- else
105
- @type = type
106
- end
107
-
108
- raise "Still not type? (#{@args[:data]})" if @type.to_s.strip.length <= 0
109
- end
110
-
111
- return @type
112
- end
113
-
114
- #Returns true if the column allows null. Otherwise false.
115
- def null?
116
- return false if @args[:data][:notnull].to_i == 1
117
- return true
118
- end
119
-
120
- #Returns the maxlength of the column.
121
- def maxlength
122
- self.type if !@maxlength
123
- return @maxlength if @maxlength
124
- return false
125
- end
126
-
127
- #Returns the default value of the column.
128
- def default
129
- def_val = @args[:data][:dflt_value]
130
- if def_val.to_s.slice(0..0) == "'"
131
- def_val = def_val.to_s.slice(0)
132
- end
133
-
134
- if def_val.to_s.slice(-1..-1) == "'"
135
- def_val = def_val.to_s.slice(0, def_val.length - 1)
136
- end
137
-
138
- return false if @args[:data][:dflt_value].to_s.empty?
139
- return def_val
140
- end
141
-
142
- #Returns true if the column is the primary key.
143
- def primarykey?
144
- return false if @args[:data][:pk].to_i == 0
145
- return true
146
- end
147
-
148
- #Returns true if the column is auto-increasing.
149
- def autoincr?
150
- return true if @args[:data][:pk].to_i == 1 and @args[:data][:type].to_sym == :integer
151
- return false
152
- end
153
-
154
- #Drops the column from the table.
155
- def drop
156
- self.table.copy(:drops => self.name)
157
- end
158
-
159
- #Changes data on the column. Like the name, type, maxlength or whatever.
160
- def change(data)
161
- newdata = data.clone
162
-
163
- newdata[:name] = self.name if !newdata.key?(:name)
164
- newdata[:type] = self.type if !newdata.key?(:type)
165
- newdata[:maxlength] = self.maxlength if !newdata.key?(:maxlength) and self.maxlength
166
- newdata[:null] = self.null? if !newdata.key?(:null)
167
- newdata[:default] = self.default if !newdata.key?(:default)
168
- newdata[:primarykey] = self.primarykey? if !newdata.key?(:primarykey)
169
-
170
- @type = nil
171
- @maxlength = nil
172
-
173
- new_table = self.table.copy(
174
- :alter_columns => {
175
- self.name.to_sym => newdata
176
- }
177
- )
178
- end
179
- end
@@ -0,0 +1,55 @@
1
+ class Baza::Driver::Sqlite3::Index
2
+ attr_reader :args, :columns
3
+
4
+ def initialize(args)
5
+ @args = args
6
+ @columns = []
7
+ @db = args[:db]
8
+ end
9
+
10
+ def name
11
+ return @args[:data][:name]
12
+ end
13
+
14
+ def table_name
15
+ return @args[:table_name]
16
+ end
17
+
18
+ def table
19
+ return @db.tables[table_name]
20
+ end
21
+
22
+ def drop
23
+ @db.query("DROP INDEX `#{name}`")
24
+ end
25
+
26
+ def rename newname
27
+ newname = newname.to_sym
28
+
29
+ create_args = data
30
+ create_args[:name] = newname
31
+
32
+ drop
33
+ table.create_indexes([create_args])
34
+ @args[:data][:name] = newname
35
+ end
36
+
37
+ def data
38
+ return {
39
+ name: name,
40
+ columns: @columns
41
+ }
42
+ end
43
+
44
+ def column_names
45
+ @columns
46
+ end
47
+
48
+ def to_s
49
+ "#<Baza::Driver::Sqlite3::Index name: \"#{name}\", columns: #{@columns}>"
50
+ end
51
+
52
+ def inspect
53
+ to_s
54
+ end
55
+ end
@@ -3,55 +3,3 @@ class Baza::Driver::Sqlite3::Indexes
3
3
  @args = args
4
4
  end
5
5
  end
6
-
7
- class Baza::Driver::Sqlite3::Indexes::Index
8
- attr_reader :args, :columns
9
-
10
- def initialize(args)
11
- @args = args
12
- @columns = []
13
- @db = args[:db]
14
- end
15
-
16
- def name
17
- return @args[:data][:name]
18
- end
19
-
20
- def table_name
21
- return @args[:table_name]
22
- end
23
-
24
- def table
25
- return @db.tables[table_name]
26
- end
27
-
28
- def drop
29
- @db.query("DROP INDEX `#{name}`")
30
- end
31
-
32
- def rename newname
33
- newname = newname.to_sym
34
-
35
- create_args = data
36
- create_args[:name] = newname
37
-
38
- drop
39
- table.create_indexes([create_args])
40
- @args[:data][:name] = newname
41
- end
42
-
43
- def data
44
- return {
45
- name: name,
46
- columns: @columns
47
- }
48
- end
49
-
50
- def column_names
51
- @columns
52
- end
53
-
54
- def to_s
55
- "#<Baza::Driver::Sqlite3::Index name: \"#{name}\", columns: #{@columns}>"
56
- end
57
- end