knjrbfw 0.0.110 → 0.0.111
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.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +2 -2
- data/VERSION +1 -1
- data/knjrbfw.gemspec +8 -36
- data/lib/knj/autoload.rb +1 -2
- data/lib/knj/gtk2_window.rb +7 -7
- data/lib/knj/unix_proc.rb +35 -35
- metadata +33 -62
- data/lib/knj/db.rb +0 -1
- data/lib/knj/knjdb/dbtime.rb +0 -35
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql.rb +0 -604
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_columns.rb +0 -155
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_indexes.rb +0 -69
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_sqlspecs.rb +0 -5
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_tables.rb +0 -443
- data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3.rb +0 -184
- data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_columns.rb +0 -177
- data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_indexes.rb +0 -29
- data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_sqlspecs.rb +0 -5
- data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb +0 -449
- data/lib/knj/knjdb/dump.rb +0 -122
- data/lib/knj/knjdb/idquery.rb +0 -109
- data/lib/knj/knjdb/libknjdb.rb +0 -797
- data/lib/knj/knjdb/libknjdb_java_sqlite3.rb +0 -83
- data/lib/knj/knjdb/libknjdb_row.rb +0 -153
- data/lib/knj/knjdb/libknjdb_sqlite3_ironruby.rb +0 -69
- data/lib/knj/knjdb/query_buffer.rb +0 -87
- data/lib/knj/knjdb/revision.rb +0 -342
- data/lib/knj/knjdb/sqlspecs.rb +0 -5
- data/lib/knj/objects.rb +0 -957
- data/lib/knj/process.rb +0 -480
- data/lib/knj/process_meta.rb +0 -569
- data/spec/db_spec.rb +0 -282
- data/spec/db_spec_encoding_test_file.txt +0 -1
- data/spec/objects_spec.rb +0 -394
- data/spec/process_meta_spec.rb +0 -172
- data/spec/process_spec.rb +0 -115
@@ -1,184 +0,0 @@
|
|
1
|
-
#This class handels SQLite3-specific behaviour.
|
2
|
-
class KnjDB_sqlite3
|
3
|
-
attr_reader :knjdb, :conn, :sep_table, :sep_col, :sep_val, :symbolize
|
4
|
-
attr_accessor :tables, :cols, :indexes
|
5
|
-
|
6
|
-
#Constructor. This should not be called manually.
|
7
|
-
def initialize(knjdb_ob)
|
8
|
-
@sep_table = "`"
|
9
|
-
@sep_col = "`"
|
10
|
-
@sep_val = "'"
|
11
|
-
|
12
|
-
@knjdb = knjdb_ob
|
13
|
-
@path = @knjdb.opts[:path] if @knjdb.opts[:path]
|
14
|
-
@path = @knjdb.opts["path"] if @knjdb.opts["path"]
|
15
|
-
@symbolize = true if !@knjdb.opts.key?(:return_keys) or @knjdb.opts[:return_keys] == "symbols"
|
16
|
-
|
17
|
-
@knjdb.opts[:subtype] = "java" if !@knjdb.opts.key?(:subtype) and RUBY_ENGINE == "jruby"
|
18
|
-
raise "No path was given." if !@path
|
19
|
-
|
20
|
-
if @knjdb.opts[:subtype] == "java"
|
21
|
-
if @knjdb.opts[:sqlite_driver]
|
22
|
-
require @knjdb.opts[:sqlite_driver]
|
23
|
-
else
|
24
|
-
require "#{File.dirname(__FILE__)}/../../../jruby/sqlitejdbc-v056.jar"
|
25
|
-
end
|
26
|
-
|
27
|
-
require "java"
|
28
|
-
import "org.sqlite.JDBC"
|
29
|
-
@conn = java.sql.DriverManager::getConnection("jdbc:sqlite:#{@knjdb.opts[:path]}")
|
30
|
-
@stat = @conn.createStatement
|
31
|
-
elsif @knjdb.opts[:subtype] == "rhodes"
|
32
|
-
@conn = SQLite3::Database.new(@path, @path)
|
33
|
-
else
|
34
|
-
@conn = SQLite3::Database.open(@path)
|
35
|
-
@conn.results_as_hash = true
|
36
|
-
@conn.type_translation = false
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
#Executes a query against the driver.
|
41
|
-
def query(string)
|
42
|
-
begin
|
43
|
-
if @knjdb.opts[:subtype] == "rhodes"
|
44
|
-
return KnjDB_sqlite3_result.new(self, @conn.execute(string, string))
|
45
|
-
elsif @knjdb.opts[:subtype] == "java"
|
46
|
-
begin
|
47
|
-
return KnjDB_sqlite3_result_java.new(self, @stat.executeQuery(string))
|
48
|
-
rescue java.sql.SQLException => e
|
49
|
-
if e.message.to_s.index("query does not return ResultSet") != nil
|
50
|
-
return KnjDB_sqlite3_result_java.new(self, nil)
|
51
|
-
else
|
52
|
-
raise e
|
53
|
-
end
|
54
|
-
end
|
55
|
-
else
|
56
|
-
return KnjDB_sqlite3_result.new(self, @conn.execute(string))
|
57
|
-
end
|
58
|
-
rescue => e
|
59
|
-
#Add SQL to the error message.
|
60
|
-
raise e.class, "#{e.message} (SQL: #{string})"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
#SQLite3 driver doesnt support unbuffered queries??
|
65
|
-
alias query_ubuf query
|
66
|
-
|
67
|
-
#Escapes a string to be safe to used in a query.
|
68
|
-
def escape(string)
|
69
|
-
#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...
|
70
|
-
#http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html
|
71
|
-
return string.to_s.gsub(/'/, "''")
|
72
|
-
end
|
73
|
-
|
74
|
-
#Escapes a string to be used as a column.
|
75
|
-
def esc_col(string)
|
76
|
-
string = string.to_s
|
77
|
-
raise "Invalid column-string: #{string}" if string.index(@sep_col) != nil
|
78
|
-
return string
|
79
|
-
end
|
80
|
-
|
81
|
-
alias :esc_table :esc_col
|
82
|
-
alias :esc :escape
|
83
|
-
|
84
|
-
#Returns the last inserted ID.
|
85
|
-
def lastID
|
86
|
-
return @conn.last_insert_row_id if @conn.respond_to?(:last_insert_row_id)
|
87
|
-
return self.query("SELECT last_insert_rowid() AS id").fetch[:id].to_i
|
88
|
-
end
|
89
|
-
|
90
|
-
#Closes the connection to the database.
|
91
|
-
def close
|
92
|
-
@conn.close
|
93
|
-
end
|
94
|
-
|
95
|
-
#Starts a transaction, yields the database and commits.
|
96
|
-
def transaction
|
97
|
-
@conn.transaction do
|
98
|
-
yield(@knjdb)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
#This class handels results when running in JRuby.
|
104
|
-
class KnjDB_sqlite3_result_java
|
105
|
-
def initialize(driver, rs)
|
106
|
-
@index = 0
|
107
|
-
retkeys = driver.knjdb.opts[:return_keys]
|
108
|
-
|
109
|
-
if rs
|
110
|
-
metadata = rs.getMetaData
|
111
|
-
columns_count = metadata.getColumnCount
|
112
|
-
|
113
|
-
@rows = []
|
114
|
-
while rs.next
|
115
|
-
row_data = {}
|
116
|
-
for i in (1..columns_count)
|
117
|
-
col_name = metadata.getColumnName(i)
|
118
|
-
col_name = col_name.to_s.to_sym if retkeys == "symbols"
|
119
|
-
row_data[col_name] = rs.getString(i)
|
120
|
-
end
|
121
|
-
|
122
|
-
@rows << row_data
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
#Returns a single result.
|
128
|
-
def fetch
|
129
|
-
return false if !@rows
|
130
|
-
ret = @rows[@index]
|
131
|
-
return false if !ret
|
132
|
-
@index += 1
|
133
|
-
return ret
|
134
|
-
end
|
135
|
-
|
136
|
-
#Loops over every result and yields them.
|
137
|
-
def each
|
138
|
-
while data = self.fetch
|
139
|
-
yield(data)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
#This class handels the result when running MRI (or others).
|
145
|
-
class KnjDB_sqlite3_result
|
146
|
-
#Constructor. This should not be called manually.
|
147
|
-
def initialize(driver, result_array)
|
148
|
-
@result_array = result_array
|
149
|
-
@index = 0
|
150
|
-
|
151
|
-
if driver.knjdb.opts[:return_keys] == "symbols"
|
152
|
-
@symbols = true
|
153
|
-
else
|
154
|
-
@symbols = false
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
#Returns a single result.
|
159
|
-
def fetch
|
160
|
-
result_hash = @result_array[@index]
|
161
|
-
return false if !result_hash
|
162
|
-
@index += 1
|
163
|
-
|
164
|
-
ret = {}
|
165
|
-
result_hash.each do |key, val|
|
166
|
-
if (Float(key) rescue false)
|
167
|
-
#do nothing.
|
168
|
-
elsif @symbols and !key.is_a?(Symbol)
|
169
|
-
ret[key.to_sym] = val
|
170
|
-
else
|
171
|
-
ret[key] = val
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
return ret
|
176
|
-
end
|
177
|
-
|
178
|
-
#Loops over every result yielding them.
|
179
|
-
def each
|
180
|
-
while data = self.fetch
|
181
|
-
yield(data)
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
@@ -1,177 +0,0 @@
|
|
1
|
-
#This class handels the SQLite3-specific behaviour for columns.
|
2
|
-
class KnjDB_sqlite3::Columns
|
3
|
-
attr_reader :db
|
4
|
-
|
5
|
-
#Constructor. This should not be called manually.
|
6
|
-
def initialize(args)
|
7
|
-
@args = args
|
8
|
-
end
|
9
|
-
|
10
|
-
#Returns SQL for a knjdb-compatible hash.
|
11
|
-
def data_sql(data)
|
12
|
-
raise "No type given." if !data["type"]
|
13
|
-
type = data["type"].to_s
|
14
|
-
|
15
|
-
if type == "enum"
|
16
|
-
type = "varchar"
|
17
|
-
data.delete("maxlength")
|
18
|
-
end
|
19
|
-
|
20
|
-
data["maxlength"] = 255 if type == "varchar" and !data.key?("maxlength")
|
21
|
-
data["maxlength"] = 11 if type == "int" and !data.key?("maxlength") and !data["autoincr"] and !data["primarykey"]
|
22
|
-
type = "integer" if @args[:db].int_types.index(type) and (data["autoincr"] or data["primarykey"])
|
23
|
-
|
24
|
-
sql = "`#{data["name"]}` #{type}"
|
25
|
-
sql << "(#{data["maxlength"]})" if data["maxlength"] and !data["autoincr"]
|
26
|
-
sql << " PRIMARY KEY" if data["primarykey"]
|
27
|
-
sql << " AUTOINCREMENT" if data["autoincr"]
|
28
|
-
|
29
|
-
if !data["null"] and data.key?("null")
|
30
|
-
sql << " NOT NULL"
|
31
|
-
|
32
|
-
if !data.key?("default") or !data["default"]
|
33
|
-
data["default"] = 0 if type == "int"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
if data.key?("default_func")
|
38
|
-
sql << " DEFAULT #{data["default_func"]}"
|
39
|
-
elsif data.key?("default") and data["default"] != false
|
40
|
-
sql << " DEFAULT '#{@args[:db].escape(data["default"])}'"
|
41
|
-
end
|
42
|
-
|
43
|
-
return sql
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
#This class handels all the SQLite3-columns.
|
48
|
-
class KnjDB_sqlite3::Columns::Column
|
49
|
-
attr_reader :args
|
50
|
-
|
51
|
-
#Constructor. This should not be called manually.
|
52
|
-
def initialize(args)
|
53
|
-
@args = args
|
54
|
-
@db = @args[:db]
|
55
|
-
end
|
56
|
-
|
57
|
-
#Returns the name of the column.
|
58
|
-
def name
|
59
|
-
return @args[:data][:name]
|
60
|
-
end
|
61
|
-
|
62
|
-
#Returns the columns table-object.
|
63
|
-
def table
|
64
|
-
return @db.tables[@args[:table_name]]
|
65
|
-
end
|
66
|
-
|
67
|
-
#Returns the data of the column as a hash in knjdb-format.
|
68
|
-
def data
|
69
|
-
return {
|
70
|
-
"type" => self.type,
|
71
|
-
"name" => self.name,
|
72
|
-
"null" => self.null?,
|
73
|
-
"maxlength" => self.maxlength,
|
74
|
-
"default" => self.default,
|
75
|
-
"primarykey" => self.primarykey?,
|
76
|
-
"autoincr" => self.autoincr?
|
77
|
-
}
|
78
|
-
end
|
79
|
-
|
80
|
-
#Returns the type of the column.
|
81
|
-
def type
|
82
|
-
if !@type
|
83
|
-
if match = @args[:data][:type].match(/^([A-z]+)$/)
|
84
|
-
@maxlength = false
|
85
|
-
type = match[0].to_sym
|
86
|
-
elsif match = @args[:data][:type].match(/^decimal\((\d+),(\d+)\)$/)
|
87
|
-
@maxlength = "#{match[1]},#{match[2]}"
|
88
|
-
type = :decimal
|
89
|
-
elsif match = @args[:data][:type].match(/^enum\((.+)\)$/)
|
90
|
-
@maxlength = match[1]
|
91
|
-
type = :enum
|
92
|
-
elsif match = @args[:data][:type].match(/^(.+)\((\d+)\)$/)
|
93
|
-
@maxlength = match[2]
|
94
|
-
type = match[1].to_sym
|
95
|
-
elsif @args[:data].key?(:type) and @args[:data][:type].to_s == ""
|
96
|
-
#A type can actually be empty in SQLite... Wtf?
|
97
|
-
return @args[:data][:type]
|
98
|
-
end
|
99
|
-
|
100
|
-
if type == :integer
|
101
|
-
@type = :int
|
102
|
-
else
|
103
|
-
@type = type
|
104
|
-
end
|
105
|
-
|
106
|
-
raise "Still not type? (#{@args[:data]})" if @type.to_s.strip.length <= 0
|
107
|
-
end
|
108
|
-
|
109
|
-
return @type
|
110
|
-
end
|
111
|
-
|
112
|
-
#Returns true if the column allows null. Otherwise false.
|
113
|
-
def null?
|
114
|
-
return false if @args[:data][:notnull].to_i == 1
|
115
|
-
return true
|
116
|
-
end
|
117
|
-
|
118
|
-
#Returns the maxlength of the column.
|
119
|
-
def maxlength
|
120
|
-
self.type if !@maxlength
|
121
|
-
return @maxlength if @maxlength
|
122
|
-
return false
|
123
|
-
end
|
124
|
-
|
125
|
-
#Returns the default value of the column.
|
126
|
-
def default
|
127
|
-
def_val = @args[:data][:dflt_value]
|
128
|
-
if def_val.to_s.slice(0..0) == "'"
|
129
|
-
def_val = def_val.to_s.slice(0)
|
130
|
-
end
|
131
|
-
|
132
|
-
if def_val.to_s.slice(-1..-1) == "'"
|
133
|
-
def_val = def_val.to_s.slice(0, def_val.length - 1)
|
134
|
-
end
|
135
|
-
|
136
|
-
return false if @args[:data][:dflt_value].to_s.length == 0
|
137
|
-
return def_val
|
138
|
-
end
|
139
|
-
|
140
|
-
#Returns true if the column is the primary key.
|
141
|
-
def primarykey?
|
142
|
-
return false if @args[:data][:pk].to_i == 0
|
143
|
-
return true
|
144
|
-
end
|
145
|
-
|
146
|
-
#Returns true if the column is auto-increasing.
|
147
|
-
def autoincr?
|
148
|
-
return true if @args[:data][:pk].to_i == 1 and @args[:data][:type].to_s == "integer"
|
149
|
-
return false
|
150
|
-
end
|
151
|
-
|
152
|
-
#Drops the column from the table.
|
153
|
-
def drop
|
154
|
-
self.table.copy("drops" => self.name)
|
155
|
-
end
|
156
|
-
|
157
|
-
#Changes data on the column. Like the name, type, maxlength or whatever.
|
158
|
-
def change(data)
|
159
|
-
newdata = data.clone
|
160
|
-
|
161
|
-
newdata["name"] = self.name if !newdata.key?("name")
|
162
|
-
newdata["type"] = self.type if !newdata.key?("type")
|
163
|
-
newdata["maxlength"] = self.maxlength if !newdata.key?("maxlength") and self.maxlength
|
164
|
-
newdata["null"] = self.null? if !newdata.key?("null")
|
165
|
-
newdata["default"] = self.default if !newdata.key?("default")
|
166
|
-
newdata["primarykey"] = self.primarykey? if !newdata.key?("primarykey")
|
167
|
-
|
168
|
-
@type = nil
|
169
|
-
@maxlength = nil
|
170
|
-
|
171
|
-
new_table = self.table.copy(
|
172
|
-
"alter_columns" => {
|
173
|
-
self.name.to_s => newdata
|
174
|
-
}
|
175
|
-
)
|
176
|
-
end
|
177
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
class KnjDB_sqlite3::Indexes
|
2
|
-
def initialize(args)
|
3
|
-
@args = args
|
4
|
-
end
|
5
|
-
end
|
6
|
-
|
7
|
-
class KnjDB_sqlite3::Indexes::Index
|
8
|
-
attr_reader :columns
|
9
|
-
|
10
|
-
def initialize(args)
|
11
|
-
@args = args
|
12
|
-
@columns = []
|
13
|
-
end
|
14
|
-
|
15
|
-
def name
|
16
|
-
return @args[:data][:name]
|
17
|
-
end
|
18
|
-
|
19
|
-
def drop
|
20
|
-
@args[:db].query("DROP INDEX `#{self.name}`")
|
21
|
-
end
|
22
|
-
|
23
|
-
def data
|
24
|
-
return {
|
25
|
-
"name" => name,
|
26
|
-
"columns" => @columns
|
27
|
-
}
|
28
|
-
end
|
29
|
-
end
|
@@ -1,449 +0,0 @@
|
|
1
|
-
class KnjDB_sqlite3::Tables
|
2
|
-
attr_reader :db, :driver
|
3
|
-
|
4
|
-
def initialize(args)
|
5
|
-
@args = args
|
6
|
-
@db = @args[:db]
|
7
|
-
|
8
|
-
@list_mutex = Mutex.new
|
9
|
-
@list = Wref_map.new
|
10
|
-
end
|
11
|
-
|
12
|
-
def [](table_name)
|
13
|
-
table_name = table_name.to_s
|
14
|
-
|
15
|
-
begin
|
16
|
-
ret = @list[table_name]
|
17
|
-
return ret
|
18
|
-
rescue Wref::Recycled
|
19
|
-
#ignore.
|
20
|
-
end
|
21
|
-
|
22
|
-
self.list do |table_obj|
|
23
|
-
return table_obj if table_obj.name.to_s == table_name.to_s
|
24
|
-
end
|
25
|
-
|
26
|
-
raise Errno::ENOENT, "Table was not found: #{table_name}."
|
27
|
-
end
|
28
|
-
|
29
|
-
def list
|
30
|
-
ret = {} unless block_given?
|
31
|
-
|
32
|
-
@list_mutex.synchronize do
|
33
|
-
q_tables = @db.select("sqlite_master", {"type" => "table"}, {"orderby" => "name"}) do |d_tables|
|
34
|
-
next if d_tables[:name] == "sqlite_sequence"
|
35
|
-
|
36
|
-
obj = @list.get!(d_tables[:name])
|
37
|
-
|
38
|
-
if !obj
|
39
|
-
obj = KnjDB_sqlite3::Tables::Table.new(
|
40
|
-
:db => @db,
|
41
|
-
:data => d_tables
|
42
|
-
)
|
43
|
-
@list[d_tables[:name]] = obj
|
44
|
-
end
|
45
|
-
|
46
|
-
if block_given?
|
47
|
-
yield(obj)
|
48
|
-
else
|
49
|
-
ret[d_tables[:name]] = obj
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
if block_given?
|
55
|
-
return nil
|
56
|
-
else
|
57
|
-
return ret
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def create(name, data, args = nil)
|
62
|
-
sql = "CREATE TABLE `#{name}` ("
|
63
|
-
|
64
|
-
first = true
|
65
|
-
data["columns"].each do |col_data|
|
66
|
-
sql << ", " if !first
|
67
|
-
first = false if first
|
68
|
-
sql << @db.cols.data_sql(col_data)
|
69
|
-
end
|
70
|
-
|
71
|
-
sql << ")"
|
72
|
-
|
73
|
-
if args and args[:return_sql]
|
74
|
-
ret = [sql]
|
75
|
-
else
|
76
|
-
@db.query(sql)
|
77
|
-
end
|
78
|
-
|
79
|
-
if data.key?("indexes") and data["indexes"]
|
80
|
-
table_obj = self[name]
|
81
|
-
|
82
|
-
if args and args[:return_sql]
|
83
|
-
ret += table_obj.create_indexes(data["indexes"], :return_sql => true)
|
84
|
-
else
|
85
|
-
table_obj.create_indexes(data["indexes"])
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
if args and args[:return_sql]
|
90
|
-
return ret
|
91
|
-
else
|
92
|
-
return nil
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
class KnjDB_sqlite3::Tables::Table
|
98
|
-
def initialize(args)
|
99
|
-
@db = args[:db]
|
100
|
-
@data = args[:data]
|
101
|
-
|
102
|
-
@list = Wref_map.new
|
103
|
-
@indexes_list = Wref_map.new
|
104
|
-
end
|
105
|
-
|
106
|
-
def name
|
107
|
-
return @data[:name]
|
108
|
-
end
|
109
|
-
|
110
|
-
def type
|
111
|
-
return @data[:type]
|
112
|
-
end
|
113
|
-
|
114
|
-
def maxlength
|
115
|
-
return @data[:maxlength]
|
116
|
-
end
|
117
|
-
|
118
|
-
def reload
|
119
|
-
@data = @db.select("sqlite_master", {"type" => "table", "name" => self.name}, {"orderby" => "name"}).fetch
|
120
|
-
end
|
121
|
-
|
122
|
-
def rows_count
|
123
|
-
data = @db.q("SELECT COUNT(*) AS count FROM `#{self.name}`").fetch
|
124
|
-
return data[:count].to_i
|
125
|
-
end
|
126
|
-
|
127
|
-
#Drops the table from the database.
|
128
|
-
def drop
|
129
|
-
raise "Cant drop native table: '#{self.name}'." if self.native?
|
130
|
-
@db.query("DROP TABLE `#{self.name}`")
|
131
|
-
end
|
132
|
-
|
133
|
-
#Returns true if the table is safe to drop.
|
134
|
-
def native?
|
135
|
-
return true if self.name.to_s == "sqlite_sequence"
|
136
|
-
return false
|
137
|
-
end
|
138
|
-
|
139
|
-
def optimize
|
140
|
-
raise "stub!"
|
141
|
-
end
|
142
|
-
|
143
|
-
def rename(newname)
|
144
|
-
self.clone(newname)
|
145
|
-
self.drop
|
146
|
-
end
|
147
|
-
|
148
|
-
def truncate
|
149
|
-
@db.query("DELETE FROM `#{self.name}` WHERE 1=1")
|
150
|
-
return nil
|
151
|
-
end
|
152
|
-
|
153
|
-
def table
|
154
|
-
return @db.tables[@table_name]
|
155
|
-
end
|
156
|
-
|
157
|
-
def column(name)
|
158
|
-
list = self.columns
|
159
|
-
return list[name] if list[name]
|
160
|
-
raise Errno::ENOENT.new("Column not found: #{name}.")
|
161
|
-
end
|
162
|
-
|
163
|
-
def columns
|
164
|
-
@db.cols
|
165
|
-
ret = {}
|
166
|
-
|
167
|
-
@db.q("PRAGMA table_info(`#{@db.esc_table(self.name)}`)") do |d_cols|
|
168
|
-
obj = @list.get!(d_cols[:name])
|
169
|
-
|
170
|
-
if !obj
|
171
|
-
obj = KnjDB_sqlite3::Columns::Column.new(
|
172
|
-
:table_name => self.name,
|
173
|
-
:db => @db,
|
174
|
-
:data => d_cols
|
175
|
-
)
|
176
|
-
@list[d_cols[:name]] = obj
|
177
|
-
end
|
178
|
-
|
179
|
-
if block_given?
|
180
|
-
yield(obj)
|
181
|
-
else
|
182
|
-
ret[d_cols[:name]] = obj
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
if block_given?
|
187
|
-
return nil
|
188
|
-
else
|
189
|
-
return ret
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
def create_columns(col_arr)
|
194
|
-
col_arr.each do |col_data|
|
195
|
-
#if col_data.key?("after")
|
196
|
-
# self.create_column_programmatic(col_data)
|
197
|
-
#else
|
198
|
-
@db.query("ALTER TABLE `#{self.name}` ADD COLUMN #{@db.cols.data_sql(col_data)};")
|
199
|
-
#end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
def create_column_programmatic(col_data)
|
204
|
-
temp_name = "temptable_#{Time.now.to_f.to_s.hash}"
|
205
|
-
cloned_tabled = self.clone(temp_name)
|
206
|
-
cols_cur = self.columns
|
207
|
-
@db.query("DROP TABLE `#{self.name}`")
|
208
|
-
|
209
|
-
sql = "CREATE TABLE `#{self.name}` ("
|
210
|
-
first = true
|
211
|
-
cols_cur.each do |name, col|
|
212
|
-
sql << ", " if !first
|
213
|
-
first = false if first
|
214
|
-
sql << @db.cols.data_sql(col.data)
|
215
|
-
|
216
|
-
if col_data["after"] and col_data["after"] == name
|
217
|
-
sql << ", #{@db.cols.data_sql(col_data)}"
|
218
|
-
end
|
219
|
-
end
|
220
|
-
sql << ");"
|
221
|
-
@db.query(sql)
|
222
|
-
|
223
|
-
sql = "INSERT INTO `#{self.name}` SELECT "
|
224
|
-
first = true
|
225
|
-
cols_cur.each do |name, col|
|
226
|
-
sql << ", " if !first
|
227
|
-
first = false if first
|
228
|
-
|
229
|
-
sql << "`#{name}`"
|
230
|
-
|
231
|
-
if col_data["after"] and col_data["after"] == name
|
232
|
-
sql << ", ''"
|
233
|
-
end
|
234
|
-
end
|
235
|
-
sql << " FROM `#{temp_name}`"
|
236
|
-
@db.query(sql)
|
237
|
-
@db.query("DROP TABLE `#{temp_name}`")
|
238
|
-
end
|
239
|
-
|
240
|
-
def clone(newname)
|
241
|
-
raise "Invalid name." if newname.to_s.strip.length <= 0
|
242
|
-
cols_cur = self.columns
|
243
|
-
|
244
|
-
sql = "CREATE TABLE `#{newname}` ("
|
245
|
-
first = true
|
246
|
-
cols_cur.each do |name, col|
|
247
|
-
sql << ", " if !first
|
248
|
-
first = false if first
|
249
|
-
sql << @db.cols.data_sql(col.data)
|
250
|
-
end
|
251
|
-
|
252
|
-
sql << ");"
|
253
|
-
@db.query(sql)
|
254
|
-
|
255
|
-
sql = "INSERT INTO `#{newname}` SELECT * FROM `#{self.name}`"
|
256
|
-
@db.query(sql)
|
257
|
-
return @db.tables[newname]
|
258
|
-
end
|
259
|
-
|
260
|
-
def copy(args = {})
|
261
|
-
temp_name = "temptable_#{Time.now.to_f.to_s.hash}"
|
262
|
-
cloned_tabled = self.clone(temp_name)
|
263
|
-
cols_cur = self.columns
|
264
|
-
@db.query("DROP TABLE `#{self.name}`")
|
265
|
-
|
266
|
-
sql = "CREATE TABLE `#{self.name}` ("
|
267
|
-
first = true
|
268
|
-
cols_cur.each do |name, col|
|
269
|
-
next if args["drops"] and args["drops"].index(name) != nil
|
270
|
-
|
271
|
-
sql << ", " if !first
|
272
|
-
first = false if first
|
273
|
-
|
274
|
-
if args.key?("alter_columns") and args["alter_columns"][name.to_s]
|
275
|
-
sql << @db.cols.data_sql(args["alter_columns"][name.to_s])
|
276
|
-
else
|
277
|
-
sql << @db.cols.data_sql(col.data)
|
278
|
-
end
|
279
|
-
|
280
|
-
if args["new"]
|
281
|
-
args["new"].each do |col_data|
|
282
|
-
if col_data["after"] and col_data["after"] == name
|
283
|
-
sql << ", #{@db.cols.data_sql(col_data)}"
|
284
|
-
end
|
285
|
-
end
|
286
|
-
end
|
287
|
-
end
|
288
|
-
sql << ");"
|
289
|
-
@db.query(sql)
|
290
|
-
|
291
|
-
sql = "INSERT INTO `#{self.name}` SELECT "
|
292
|
-
first = true
|
293
|
-
cols_cur.each do |name, col|
|
294
|
-
next if args["drops"] and args["drops"].index(name) != nil
|
295
|
-
|
296
|
-
sql << ", " if !first
|
297
|
-
first = false if first
|
298
|
-
|
299
|
-
sql << "`#{name}`"
|
300
|
-
|
301
|
-
if args["news"]
|
302
|
-
args["news"].each do |col_data|
|
303
|
-
if col_data["after"] and col_data["after"] == name
|
304
|
-
sql << ", ''"
|
305
|
-
end
|
306
|
-
end
|
307
|
-
end
|
308
|
-
end
|
309
|
-
|
310
|
-
sql << " FROM `#{temp_name}`"
|
311
|
-
@db.query(sql)
|
312
|
-
@db.query("DROP TABLE `#{temp_name}`")
|
313
|
-
end
|
314
|
-
|
315
|
-
def index(name)
|
316
|
-
name = name.to_s
|
317
|
-
|
318
|
-
begin
|
319
|
-
return @indexes_list[name]
|
320
|
-
rescue Wref::Recycled
|
321
|
-
if @db.opts[:index_append_table_name]
|
322
|
-
tryname = "#{self.name}__#{name}"
|
323
|
-
|
324
|
-
begin
|
325
|
-
return @indexes_list[tryname]
|
326
|
-
rescue Wref::Recycled
|
327
|
-
#ignore.
|
328
|
-
end
|
329
|
-
else
|
330
|
-
#ignore
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
self.indexes do |index|
|
335
|
-
return index if index.name.to_s == name
|
336
|
-
end
|
337
|
-
|
338
|
-
raise Errno::ENOENT.new("Index not found: #{name}.")
|
339
|
-
end
|
340
|
-
|
341
|
-
def indexes
|
342
|
-
@db.indexes
|
343
|
-
ret = {} unless block_given?
|
344
|
-
|
345
|
-
@db.q("PRAGMA index_list(`#{@db.esc_table(self.name)}`)") do |d_indexes|
|
346
|
-
next if d_indexes[:Key_name] == "PRIMARY"
|
347
|
-
|
348
|
-
obj = @indexes_list.get!(d_indexes[:name])
|
349
|
-
|
350
|
-
if !obj
|
351
|
-
if @db.opts[:index_append_table_name]
|
352
|
-
match_name = d_indexes[:name].match(/__(.+)$/)
|
353
|
-
|
354
|
-
if match_name
|
355
|
-
name = match_name[1]
|
356
|
-
else
|
357
|
-
name = d_indexes[:name]
|
358
|
-
end
|
359
|
-
else
|
360
|
-
name = d_indexes[:name]
|
361
|
-
end
|
362
|
-
|
363
|
-
obj = KnjDB_sqlite3::Indexes::Index.new(
|
364
|
-
:table_name => self.name,
|
365
|
-
:db => @db,
|
366
|
-
:data => d_indexes
|
367
|
-
)
|
368
|
-
obj.columns << name
|
369
|
-
@indexes_list[d_indexes[:name]] = obj
|
370
|
-
end
|
371
|
-
|
372
|
-
if block_given?
|
373
|
-
yield(obj)
|
374
|
-
else
|
375
|
-
ret[d_indexes[:name]] = obj
|
376
|
-
end
|
377
|
-
end
|
378
|
-
|
379
|
-
if block_given?
|
380
|
-
return nil
|
381
|
-
else
|
382
|
-
return ret
|
383
|
-
end
|
384
|
-
end
|
385
|
-
|
386
|
-
def create_indexes(index_arr, args = nil)
|
387
|
-
if args and args[:return_sql]
|
388
|
-
ret = []
|
389
|
-
end
|
390
|
-
|
391
|
-
index_arr.each do |index_data|
|
392
|
-
if index_data.is_a?(String)
|
393
|
-
index_data = {"name" => index_data, "columns" => [index_data]}
|
394
|
-
end
|
395
|
-
|
396
|
-
raise "No name was given." if !index_data.key?("name") or index_data["name"].strip.length <= 0
|
397
|
-
raise "No columns was given on index #{index_data["name"]}." if index_data["columns"].empty?
|
398
|
-
|
399
|
-
name = index_data["name"]
|
400
|
-
name = "#{self.name}__#{name}" if @db.opts[:index_append_table_name]
|
401
|
-
|
402
|
-
sql = "CREATE INDEX '#{@db.esc_col(name)}' ON `#{@db.esc_table(self.name)}` ("
|
403
|
-
|
404
|
-
first = true
|
405
|
-
index_data["columns"].each do |col_name|
|
406
|
-
sql << ", " if !first
|
407
|
-
first = false if first
|
408
|
-
|
409
|
-
sql << "`#{@db.esc_col(col_name)}`"
|
410
|
-
end
|
411
|
-
|
412
|
-
sql << ")"
|
413
|
-
|
414
|
-
if args and args[:return_sql]
|
415
|
-
ret << sql
|
416
|
-
else
|
417
|
-
@db.query(sql)
|
418
|
-
end
|
419
|
-
end
|
420
|
-
|
421
|
-
if args and args[:return_sql]
|
422
|
-
return ret
|
423
|
-
else
|
424
|
-
return nil
|
425
|
-
end
|
426
|
-
end
|
427
|
-
|
428
|
-
def data
|
429
|
-
ret = {
|
430
|
-
"name" => name,
|
431
|
-
"columns" => [],
|
432
|
-
"indexes" => []
|
433
|
-
}
|
434
|
-
|
435
|
-
columns.each do |name, column|
|
436
|
-
ret["columns"] << column.data
|
437
|
-
end
|
438
|
-
|
439
|
-
indexes.each do |name, index|
|
440
|
-
ret["indexes"] << index.data if name != "PRIMARY"
|
441
|
-
end
|
442
|
-
|
443
|
-
return ret
|
444
|
-
end
|
445
|
-
|
446
|
-
def insert(data)
|
447
|
-
@db.insert(self.name, data)
|
448
|
-
end
|
449
|
-
end
|