imparcial 0.0.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.
- data/lib/imparcial/driver/base/expression/base.rb +104 -0
- data/lib/imparcial/driver/base/expression/delete.rb +72 -0
- data/lib/imparcial/driver/base/expression/index.rb +199 -0
- data/lib/imparcial/driver/base/expression/insert.rb +33 -0
- data/lib/imparcial/driver/base/expression/lock.rb +11 -0
- data/lib/imparcial/driver/base/expression/select.rb +36 -0
- data/lib/imparcial/driver/base/expression/sequence.rb +189 -0
- data/lib/imparcial/driver/base/expression/statement.rb +128 -0
- data/lib/imparcial/driver/base/expression/table_diff.rb +154 -0
- data/lib/imparcial/driver/base/expression/table_evolution.rb +94 -0
- data/lib/imparcial/driver/base/expression/table_metadata.rb +122 -0
- data/lib/imparcial/driver/base/expression/table_operation.rb +137 -0
- data/lib/imparcial/driver/base/expression/transaction.rb +59 -0
- data/lib/imparcial/driver/base/expression/update.rb +33 -0
- data/lib/imparcial/driver/base/expression/util.rb +45 -0
- data/lib/imparcial/driver/base/expression.rb +37 -0
- data/lib/imparcial/driver/base/result.rb +94 -0
- data/lib/imparcial/driver/base/sql/delete.rb +22 -0
- data/lib/imparcial/driver/base/sql/index.rb +53 -0
- data/lib/imparcial/driver/base/sql/insert.rb +63 -0
- data/lib/imparcial/driver/base/sql/select.rb +101 -0
- data/lib/imparcial/driver/base/sql/sequence.rb +55 -0
- data/lib/imparcial/driver/base/sql/table_metadata.rb +29 -0
- data/lib/imparcial/driver/base/sql/table_operation.rb +49 -0
- data/lib/imparcial/driver/base/sql/transaction.rb +43 -0
- data/lib/imparcial/driver/base/sql/update.rb +29 -0
- data/lib/imparcial/driver/base/sql.rb +25 -0
- data/lib/imparcial/driver/base/typemap.rb +214 -0
- data/lib/imparcial/driver/base/util.rb +41 -0
- data/lib/imparcial/driver/base.rb +156 -0
- data/lib/imparcial/driver/mysql/expression/index.rb +44 -0
- data/lib/imparcial/driver/mysql/expression/table.rb +26 -0
- data/lib/imparcial/driver/mysql/expression.rb +11 -0
- data/lib/imparcial/driver/mysql/result.rb +33 -0
- data/lib/imparcial/driver/mysql/sql/index.rb +51 -0
- data/lib/imparcial/driver/mysql/sql/sequence.rb +39 -0
- data/lib/imparcial/driver/mysql/sql/table_metadata.rb +43 -0
- data/lib/imparcial/driver/mysql/sql/table_operation.rb +20 -0
- data/lib/imparcial/driver/mysql/sql.rb +15 -0
- data/lib/imparcial/driver/mysql/typemap.rb +13 -0
- data/lib/imparcial/driver/mysql/util.rb +13 -0
- data/lib/imparcial/driver/mysql.rb +48 -0
- data/lib/imparcial/driver/postgre/expression/index.rb +10 -0
- data/lib/imparcial/driver/postgre/expression/sequence.rb +9 -0
- data/lib/imparcial/driver/postgre/expression/table.rb +20 -0
- data/lib/imparcial/driver/postgre/expression.rb +13 -0
- data/lib/imparcial/driver/postgre/result.rb +35 -0
- data/lib/imparcial/driver/postgre/sql/index.rb +53 -0
- data/lib/imparcial/driver/postgre/sql/sequence.rb +28 -0
- data/lib/imparcial/driver/postgre/sql/table_metadata.rb +46 -0
- data/lib/imparcial/driver/postgre/sql/table_operation.rb +9 -0
- data/lib/imparcial/driver/postgre/sql.rb +15 -0
- data/lib/imparcial/driver/postgre/typemap.rb +29 -0
- data/lib/imparcial/driver/postgre/util.rb +19 -0
- data/lib/imparcial/driver/postgre.rb +43 -0
- data/lib/imparcial/driver.rb +1 -0
- data/lib/imparcial/exception.rb +61 -0
- data/lib/imparcial.rb +82 -0
- metadata +114 -0
@@ -0,0 +1,214 @@
|
|
1
|
+
module Imparcial
|
2
|
+
module Driver
|
3
|
+
module TypemapBase
|
4
|
+
|
5
|
+
public
|
6
|
+
|
7
|
+
# Those are types shared among all databases.
|
8
|
+
# Of course they are not enough. Feel free to override them
|
9
|
+
# if necessary.
|
10
|
+
|
11
|
+
def regular_types
|
12
|
+
|
13
|
+
{
|
14
|
+
:integer => 'INTEGER',
|
15
|
+
:string => 'VARCHAR',
|
16
|
+
:float => 'FLOAT',
|
17
|
+
:datetime => 'DATETIME',
|
18
|
+
:time => 'TIME',
|
19
|
+
:date => 'DATE',
|
20
|
+
:text => 'TEXT',
|
21
|
+
:boolean => 'TINYINT',
|
22
|
+
:serial => 'SERIAL'
|
23
|
+
}
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
# The opposite of above.
|
28
|
+
|
29
|
+
def sql_types
|
30
|
+
|
31
|
+
regular_types.invert
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
# Default size can be very handy when users are lazy to supply them
|
36
|
+
# or they expect a given type to be in a default size.
|
37
|
+
|
38
|
+
def default_size_for_types
|
39
|
+
|
40
|
+
{
|
41
|
+
:string => 255,
|
42
|
+
:boolean => 1
|
43
|
+
}
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
public
|
48
|
+
|
49
|
+
# Transform regular user defined hash fields into a proper one.
|
50
|
+
|
51
|
+
def parse_field ( field )
|
52
|
+
|
53
|
+
# No name? error!
|
54
|
+
|
55
|
+
if not field[:name]
|
56
|
+
|
57
|
+
raise OptionError.new('A name must be supplied')
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
# No type? error!
|
62
|
+
|
63
|
+
if not field[:type]
|
64
|
+
|
65
|
+
raise OptionError.new('A type must be supplied')
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
# Simple conversions.
|
70
|
+
|
71
|
+
field[:name] = field[:name].to_s
|
72
|
+
field[:type] = field[:type].to_sym
|
73
|
+
|
74
|
+
# Set default size if nothing has been supplied.
|
75
|
+
|
76
|
+
field[:size] = default_size_for_types[field[:type]] unless field[:size]
|
77
|
+
|
78
|
+
# Primary key is set as false.
|
79
|
+
|
80
|
+
field[:pk] ||= false
|
81
|
+
|
82
|
+
# Allow Null is set as true.
|
83
|
+
|
84
|
+
field[:allow_null] = true if field[:allow_null] == nil
|
85
|
+
|
86
|
+
# let's verify if everything is okay.
|
87
|
+
|
88
|
+
if field[:auto_increment] && !field[:pk]
|
89
|
+
|
90
|
+
raise OptionError.new("To auto increment field must be primary key")
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
field[:indexed] ||= false
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
# In order to work with fields in RDBAL, you have to provide
|
99
|
+
# field datas in hashes.
|
100
|
+
# This function is basically evaluate them and pass into a block.
|
101
|
+
|
102
|
+
def parse_fields ( fields = [], &block )
|
103
|
+
|
104
|
+
# At least a field must be supplied.
|
105
|
+
|
106
|
+
raise OptionError.new unless fields
|
107
|
+
raise OptionError.new if fields.length < 1
|
108
|
+
|
109
|
+
for field in fields
|
110
|
+
|
111
|
+
parse_field field
|
112
|
+
yield field
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
# Transform a regular SQL column into RDBAL's hash.
|
119
|
+
|
120
|
+
def parse_column ( column )
|
121
|
+
|
122
|
+
# Apply the appropriate type.
|
123
|
+
|
124
|
+
type = sql_types[column[:type].upcase]
|
125
|
+
|
126
|
+
if not type
|
127
|
+
|
128
|
+
raise OptionError.new('Cannot map column type: ' + column[:type].to_s)
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
column[:type] = type
|
133
|
+
|
134
|
+
if column[:size]
|
135
|
+
|
136
|
+
column[:size] = unquote_value(column[:size])
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
# Let's work on default value.
|
141
|
+
|
142
|
+
if column[:default_value]
|
143
|
+
|
144
|
+
column[:default_value].gsub!("'",'')
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
# Allow null?
|
149
|
+
|
150
|
+
if column[:allow_null] == 't' || column[:allow_null] == 1
|
151
|
+
|
152
|
+
column[:allow_null] = true
|
153
|
+
|
154
|
+
else
|
155
|
+
|
156
|
+
column[:allow_null] = false
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
# Is primary key?
|
161
|
+
|
162
|
+
if column[:pk] == 't' || column[:pk] == 1
|
163
|
+
|
164
|
+
column[:pk] = true
|
165
|
+
|
166
|
+
else
|
167
|
+
|
168
|
+
column[:pk] = false
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
# Is automagically incremented?
|
173
|
+
|
174
|
+
if column[:auto_increment] == 1
|
175
|
+
|
176
|
+
column[:auto_increment] = true
|
177
|
+
|
178
|
+
else
|
179
|
+
|
180
|
+
column[:auto_increment] = false
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
if column[:indexed] == 't' || column[:indexed] == 1
|
185
|
+
|
186
|
+
column[:indexed] = true
|
187
|
+
|
188
|
+
else
|
189
|
+
|
190
|
+
column[:indexed] = false
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
# Iterate columns by parsing them.
|
197
|
+
|
198
|
+
def parse_columns ( columns, &block )
|
199
|
+
|
200
|
+
raise OptionError.new unless columns
|
201
|
+
raise OptionError.new if columns.length < 1
|
202
|
+
|
203
|
+
for column in columns
|
204
|
+
|
205
|
+
parse_column column
|
206
|
+
yield column
|
207
|
+
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Imparcial
|
2
|
+
module Driver
|
3
|
+
module UtilBase
|
4
|
+
|
5
|
+
# This method possibly will work for many databases.
|
6
|
+
|
7
|
+
def quote_value ( val )
|
8
|
+
|
9
|
+
if val.class == String || val.class == Symbol
|
10
|
+
|
11
|
+
"\"#{val}\""
|
12
|
+
|
13
|
+
else
|
14
|
+
|
15
|
+
val.to_s
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
# This method possibly will work for many databases.
|
22
|
+
|
23
|
+
def unquote_value ( val )
|
24
|
+
|
25
|
+
return 0 if val == '0'
|
26
|
+
|
27
|
+
val.to_i == 0 ? val : val.to_i
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
# Subclasses need to override it.
|
32
|
+
|
33
|
+
def quote ( val )
|
34
|
+
|
35
|
+
raise FeatureNotFound
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require 'imparcial/driver/base/util'
|
2
|
+
require 'imparcial/driver/base/typemap'
|
3
|
+
require 'imparcial/driver/base/result'
|
4
|
+
require 'imparcial/driver/base/sql'
|
5
|
+
require 'imparcial/driver/base/expression'
|
6
|
+
|
7
|
+
module Imparcial
|
8
|
+
module Driver
|
9
|
+
|
10
|
+
# You have seriously to pay attention on this class.
|
11
|
+
# Basically speaking, it servers as base for all new drivers.
|
12
|
+
# The idea behind Imparcial is to keep an abstract interface without
|
13
|
+
# exposing any database-specific-features.
|
14
|
+
# Of course, it's an impossible mission anyhow. There are so many
|
15
|
+
# databases out there and there are so many cool features that
|
16
|
+
# make impossible not to expose them.
|
17
|
+
# We recommend you to obey the interface as much as possible.
|
18
|
+
# However you may develop some specific features.
|
19
|
+
|
20
|
+
class AdapterBase
|
21
|
+
|
22
|
+
# Include SQL syntax generation.
|
23
|
+
# Here where all SQL syntax lies on.
|
24
|
+
|
25
|
+
include SQLBase
|
26
|
+
|
27
|
+
# Include the expression mechanism.
|
28
|
+
# Things like create table, drop table, select and so forth.
|
29
|
+
# They all come from this module.
|
30
|
+
|
31
|
+
include ExpressionBase
|
32
|
+
|
33
|
+
# Include some util methods.
|
34
|
+
# Things like quoting columns, tables and values.
|
35
|
+
|
36
|
+
include UtilBase
|
37
|
+
|
38
|
+
# Include Typemap mechanism.
|
39
|
+
|
40
|
+
include TypemapBase
|
41
|
+
|
42
|
+
# Let's keep a track of the initializer. We'll need some info eventually.
|
43
|
+
|
44
|
+
attr_reader :initializer
|
45
|
+
|
46
|
+
# Let's also keep a track of the connection.
|
47
|
+
|
48
|
+
attr_accessor :conn
|
49
|
+
alias_method :connection, :conn
|
50
|
+
|
51
|
+
attr_reader :host, :user, :pass, :database, :socket, :port
|
52
|
+
|
53
|
+
def initialize ( initializer )
|
54
|
+
|
55
|
+
# Cannot accept classes different from Initializer.
|
56
|
+
|
57
|
+
if initializer.class != Imparcial::Initializer
|
58
|
+
|
59
|
+
msg = 'An initializer is needed in order to start a driver'
|
60
|
+
raise AdapterConfigError.new(msg)
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
@initializer = initializer
|
65
|
+
|
66
|
+
@host = initializer.host
|
67
|
+
|
68
|
+
if not initializer.user
|
69
|
+
|
70
|
+
raise AdapterConfigError.new('Adapter requires an username')
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
@user = initializer.user
|
75
|
+
|
76
|
+
if not initializer.pass
|
77
|
+
|
78
|
+
raise AdapterConfigError.new('Adapter requires a password')
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
@pass = initializer.pass
|
83
|
+
|
84
|
+
if not initializer.database
|
85
|
+
|
86
|
+
raise AdapterConfigErrornew('Adapter requires a database')
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
@database = initializer.database
|
91
|
+
@socket = initializer.socket
|
92
|
+
@port = initializer.port
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
#####################################################
|
97
|
+
# #
|
98
|
+
# Those are methods shared among all databases. #
|
99
|
+
# Hardly, one will need to override them. #
|
100
|
+
# #
|
101
|
+
#####################################################
|
102
|
+
|
103
|
+
def conn
|
104
|
+
|
105
|
+
raise AdapterConnectionError.new('Have you connected?') unless @conn
|
106
|
+
@conn
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
def close
|
111
|
+
|
112
|
+
conn.close
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
def result
|
117
|
+
|
118
|
+
raise ResultError.new('Have you made a query?') unless @result
|
119
|
+
@result
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
#####################################################
|
124
|
+
# #
|
125
|
+
# Subclasses must override those following methods. #
|
126
|
+
# They are driver-specific. #
|
127
|
+
# #
|
128
|
+
#####################################################
|
129
|
+
|
130
|
+
def connect
|
131
|
+
|
132
|
+
raise FeatureNotFound
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
def version
|
137
|
+
|
138
|
+
raise FeatureNotFound
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
def query ( sql )
|
143
|
+
|
144
|
+
raise FeatureNotFound
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
def adapter_specific_exception
|
149
|
+
|
150
|
+
raise FeatureNotFound
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Imparcial
|
2
|
+
module Driver
|
3
|
+
module ExpressionMysql
|
4
|
+
module Index
|
5
|
+
|
6
|
+
public
|
7
|
+
|
8
|
+
def drop_all_indexes
|
9
|
+
|
10
|
+
for index in retrieve_indexes
|
11
|
+
|
12
|
+
meta = {:index_name => index[:name], :table_name => index[:table]}
|
13
|
+
query sql_for_dropping_index(meta)
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
rescue adapter_specific_exception => ex
|
18
|
+
|
19
|
+
raise IndexDropError.new(ex.message)
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
def drop_all_indexes_for_table ( options = {} )
|
24
|
+
|
25
|
+
check_options expected_options_for_index_table, options
|
26
|
+
|
27
|
+
for index in retrieve_indexes_for_table options
|
28
|
+
|
29
|
+
meta = {:index_name => index[:name], :table_name => options[:table_name]}
|
30
|
+
query sql_for_dropping_index(meta)
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
rescue adapter_specific_exception => ex
|
35
|
+
|
36
|
+
raise IndexDropError.new(ex.message)
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Imparcial
|
2
|
+
module Driver
|
3
|
+
module ExpressionMysql
|
4
|
+
module Table
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def expected_options_for_creating_table
|
9
|
+
|
10
|
+
super.merge :engine => :optional
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
def field_to_column ( field )
|
15
|
+
|
16
|
+
column = super
|
17
|
+
column[:auto_increment] = field[:auto_increment] ? ' AUTO_INCREMENT' : ''
|
18
|
+
|
19
|
+
column
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Imparcial
|
2
|
+
module Driver
|
3
|
+
class ResultMysql < ResultBase
|
4
|
+
|
5
|
+
def rows
|
6
|
+
|
7
|
+
@specific.num_rows
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch
|
12
|
+
|
13
|
+
fields = @specific.fetch_fields
|
14
|
+
|
15
|
+
@specific.each do |row|
|
16
|
+
|
17
|
+
v = []
|
18
|
+
|
19
|
+
row.each_with_index do |r, index|
|
20
|
+
|
21
|
+
v << Row.new(fields[index].name, r)
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
yield(*v)
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Imparcial
|
2
|
+
module Driver
|
3
|
+
module SQLMysql
|
4
|
+
module Index
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def sql_for_dropping_index ( options )
|
9
|
+
|
10
|
+
%{
|
11
|
+
DROP INDEX #{options[:index_name]} ON
|
12
|
+
#{quote(options[:table_name])}
|
13
|
+
}
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
# Generate SQL statement for verifying if a given index exists.
|
18
|
+
|
19
|
+
def sql_for_index_exists? ( options )
|
20
|
+
|
21
|
+
%{
|
22
|
+
SELECT 1 FROM INFORMATION_SCHEMA.statistics
|
23
|
+
WHERE INDEX_NAME = #{quote_value(options[:index_name])}
|
24
|
+
}
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def sql_for_retrieving_indexes
|
29
|
+
|
30
|
+
%{
|
31
|
+
SELECT
|
32
|
+
TABLE_NAME AS 'table',
|
33
|
+
COLUMN_NAME AS 'column',
|
34
|
+
INDEX_NAME AS 'index'
|
35
|
+
FROM INFORMATION_SCHEMA.statistics
|
36
|
+
}
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
def sql_for_retrieving_indexes_for_table ( options )
|
41
|
+
|
42
|
+
sql_for_retrieving_indexes + %{
|
43
|
+
WHERE TABLE_NAME = #{quote_value(options[:table_name])}
|
44
|
+
}
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Imparcial
|
2
|
+
module Driver
|
3
|
+
module SQLMysql
|
4
|
+
|
5
|
+
# Mysql doesn't support sequences.
|
6
|
+
# We have to disable all them.
|
7
|
+
|
8
|
+
module Sequence
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def sql_for_creating_sequence ( options )
|
13
|
+
|
14
|
+
raise FeatureNotFound
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
def sql_for_dropping_sequence ( options )
|
19
|
+
|
20
|
+
raise FeatureNotFound
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def sql_for_sequence_exists? ( options )
|
25
|
+
|
26
|
+
raise FeatureNotFound
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
def sql_for_retrieving_sequences
|
31
|
+
|
32
|
+
raise FeatureNotFound
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Imparcial
|
2
|
+
module Driver
|
3
|
+
module SQLMysql
|
4
|
+
module TableMetadata
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
# Generate SQL statement for retrieving tables.
|
9
|
+
|
10
|
+
def sql_for_retrieving_tables
|
11
|
+
|
12
|
+
'SHOW TABLES'
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
# Generate SQL statement for retrieving columns.
|
17
|
+
|
18
|
+
def sql_for_retrieving_columns ( options = {} )
|
19
|
+
|
20
|
+
%{
|
21
|
+
SELECT
|
22
|
+
A.column_name, A.data_type, A.character_maximum_length as size,
|
23
|
+
(A.is_nullable = 'YES') as allow_null,
|
24
|
+
(A.column_name = B.column_name) as pk,
|
25
|
+
A.column_default,
|
26
|
+
A.extra = 'auto_increment' as auto_inc,
|
27
|
+
A.column_name in (
|
28
|
+
SELECT s.COLUMN_NAME FROM INFORMATION_SCHEMA.statistics s
|
29
|
+
WHERE s.COLUMN_NAME = A.column_name
|
30
|
+
) as indexed
|
31
|
+
|
32
|
+
FROM information_schema.columns A
|
33
|
+
LEFT JOIN information_schema.key_column_usage B ON A.table_name = B.table_name
|
34
|
+
WHERE A.table_name = #{quote_value(options[:table_name])}
|
35
|
+
|
36
|
+
}
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Imparcial
|
2
|
+
module Driver
|
3
|
+
module SQLMysql
|
4
|
+
module TableOperation
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def sql_for_creating_table ( options = {} )
|
9
|
+
|
10
|
+
syntax = super
|
11
|
+
syntax += 'ENGINE = ' + options[:engine].to_s if options[:engine]
|
12
|
+
|
13
|
+
syntax
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'imparcial/driver/mysql/sql/table_operation'
|
2
|
+
require 'imparcial/driver/mysql/sql/table_metadata'
|
3
|
+
require 'imparcial/driver/mysql/sql/sequence'
|
4
|
+
require 'imparcial/driver/mysql/sql/index'
|
5
|
+
|
6
|
+
module Imparcial
|
7
|
+
module Driver
|
8
|
+
module SQLMysql
|
9
|
+
include TableOperation
|
10
|
+
include TableMetadata
|
11
|
+
include Sequence
|
12
|
+
include Index
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|