activerecord-jdbc-adapter 0.9.3-java

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 (121) hide show
  1. data/History.txt +248 -0
  2. data/LICENSE.txt +21 -0
  3. data/Manifest.txt +125 -0
  4. data/README.txt +218 -0
  5. data/Rakefile +10 -0
  6. data/lib/active_record/connection_adapters/cachedb_adapter.rb +1 -0
  7. data/lib/active_record/connection_adapters/derby_adapter.rb +13 -0
  8. data/lib/active_record/connection_adapters/h2_adapter.rb +13 -0
  9. data/lib/active_record/connection_adapters/hsqldb_adapter.rb +13 -0
  10. data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
  11. data/lib/active_record/connection_adapters/jdbc_adapter.rb +640 -0
  12. data/lib/active_record/connection_adapters/jdbc_adapter_spec.rb +26 -0
  13. data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
  14. data/lib/active_record/connection_adapters/mysql_adapter.rb +13 -0
  15. data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
  16. data/lib/active_record/connection_adapters/postgresql_adapter.rb +13 -0
  17. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +13 -0
  18. data/lib/generators/jdbc/jdbc_generator.rb +9 -0
  19. data/lib/jdbc_adapter.rb +27 -0
  20. data/lib/jdbc_adapter/jdbc.rake +121 -0
  21. data/lib/jdbc_adapter/jdbc_adapter_internal.jar +0 -0
  22. data/lib/jdbc_adapter/jdbc_cachedb.rb +33 -0
  23. data/lib/jdbc_adapter/jdbc_db2.rb +203 -0
  24. data/lib/jdbc_adapter/jdbc_derby.rb +430 -0
  25. data/lib/jdbc_adapter/jdbc_firebird.rb +109 -0
  26. data/lib/jdbc_adapter/jdbc_hsqldb.rb +218 -0
  27. data/lib/jdbc_adapter/jdbc_informix.rb +147 -0
  28. data/lib/jdbc_adapter/jdbc_mimer.rb +141 -0
  29. data/lib/jdbc_adapter/jdbc_mssql.rb +337 -0
  30. data/lib/jdbc_adapter/jdbc_mysql.rb +236 -0
  31. data/lib/jdbc_adapter/jdbc_oracle.rb +377 -0
  32. data/lib/jdbc_adapter/jdbc_postgre.rb +498 -0
  33. data/lib/jdbc_adapter/jdbc_sqlite3.rb +384 -0
  34. data/lib/jdbc_adapter/jdbc_sybase.rb +50 -0
  35. data/lib/jdbc_adapter/missing_functionality_helper.rb +87 -0
  36. data/lib/jdbc_adapter/rake_tasks.rb +10 -0
  37. data/lib/jdbc_adapter/tsql_helper.rb +60 -0
  38. data/lib/jdbc_adapter/version.rb +5 -0
  39. data/lib/pg.rb +4 -0
  40. data/rails_generators/jdbc_generator.rb +15 -0
  41. data/rails_generators/templates/config/initializers/jdbc.rb +7 -0
  42. data/rails_generators/templates/lib/tasks/jdbc.rake +8 -0
  43. data/rakelib/compile.rake +23 -0
  44. data/rakelib/package.rake +90 -0
  45. data/rakelib/rails.rake +41 -0
  46. data/rakelib/test.rake +76 -0
  47. data/src/java/jdbc_adapter/JdbcAdapterInternalService.java +53 -0
  48. data/src/java/jdbc_adapter/JdbcConnectionFactory.java +36 -0
  49. data/src/java/jdbc_adapter/JdbcDerbySpec.java +293 -0
  50. data/src/java/jdbc_adapter/JdbcMySQLSpec.java +134 -0
  51. data/src/java/jdbc_adapter/MssqlRubyJdbcConnection.java +71 -0
  52. data/src/java/jdbc_adapter/PostgresRubyJdbcConnection.java +55 -0
  53. data/src/java/jdbc_adapter/RubyJdbcConnection.java +1162 -0
  54. data/src/java/jdbc_adapter/SQLBlock.java +27 -0
  55. data/src/java/jdbc_adapter/Sqlite3RubyJdbcConnection.java +41 -0
  56. data/test/abstract_db_create.rb +107 -0
  57. data/test/activerecord/connection_adapters/type_conversion_test.rb +31 -0
  58. data/test/activerecord/connections/native_jdbc_mysql/connection.rb +25 -0
  59. data/test/cachedb_simple_test.rb +6 -0
  60. data/test/db/cachedb.rb +9 -0
  61. data/test/db/db2.rb +9 -0
  62. data/test/db/derby.rb +14 -0
  63. data/test/db/h2.rb +11 -0
  64. data/test/db/hsqldb.rb +12 -0
  65. data/test/db/informix.rb +11 -0
  66. data/test/db/jdbc.rb +11 -0
  67. data/test/db/jndi_config.rb +30 -0
  68. data/test/db/logger.rb +3 -0
  69. data/test/db/mssql.rb +9 -0
  70. data/test/db/mysql.rb +10 -0
  71. data/test/db/oracle.rb +34 -0
  72. data/test/db/postgres.rb +9 -0
  73. data/test/db/sqlite3.rb +15 -0
  74. data/test/db2_simple_test.rb +10 -0
  75. data/test/derby_migration_test.rb +21 -0
  76. data/test/derby_multibyte_test.rb +12 -0
  77. data/test/derby_simple_test.rb +21 -0
  78. data/test/generic_jdbc_connection_test.rb +9 -0
  79. data/test/h2_simple_test.rb +6 -0
  80. data/test/has_many_through.rb +79 -0
  81. data/test/helper.rb +5 -0
  82. data/test/hsqldb_simple_test.rb +6 -0
  83. data/test/informix_simple_test.rb +48 -0
  84. data/test/jdbc_adapter/jdbc_db2_test.rb +26 -0
  85. data/test/jdbc_adapter/jdbc_sybase_test.rb +33 -0
  86. data/test/jdbc_common.rb +25 -0
  87. data/test/jndi_callbacks_test.rb +38 -0
  88. data/test/jndi_test.rb +35 -0
  89. data/test/manualTestDatabase.rb +191 -0
  90. data/test/minirunit.rb +109 -0
  91. data/test/minirunit/testConnect.rb +14 -0
  92. data/test/minirunit/testH2.rb +73 -0
  93. data/test/minirunit/testHsqldb.rb +73 -0
  94. data/test/minirunit/testLoadActiveRecord.rb +3 -0
  95. data/test/minirunit/testMysql.rb +83 -0
  96. data/test/minirunit/testRawSelect.rb +24 -0
  97. data/test/models/add_not_null_column_to_table.rb +12 -0
  98. data/test/models/auto_id.rb +18 -0
  99. data/test/models/data_types.rb +28 -0
  100. data/test/models/entry.rb +23 -0
  101. data/test/models/mixed_case.rb +20 -0
  102. data/test/models/reserved_word.rb +18 -0
  103. data/test/models/string_id.rb +18 -0
  104. data/test/models/validates_uniqueness_of_string.rb +19 -0
  105. data/test/mssql_simple_test.rb +6 -0
  106. data/test/mysql_db_create_test.rb +25 -0
  107. data/test/mysql_multibyte_test.rb +10 -0
  108. data/test/mysql_nonstandard_primary_key_test.rb +42 -0
  109. data/test/mysql_simple_test.rb +32 -0
  110. data/test/oracle_simple_test.rb +29 -0
  111. data/test/pick_rails_version.rb +3 -0
  112. data/test/postgres_db_create_test.rb +21 -0
  113. data/test/postgres_mixed_case_test.rb +19 -0
  114. data/test/postgres_nonseq_pkey_test.rb +40 -0
  115. data/test/postgres_reserved_test.rb +22 -0
  116. data/test/postgres_schema_search_path_test.rb +46 -0
  117. data/test/postgres_simple_test.rb +13 -0
  118. data/test/simple.rb +475 -0
  119. data/test/sqlite3_simple_test.rb +233 -0
  120. data/test/sybase_jtds_simple_test.rb +6 -0
  121. metadata +188 -0
@@ -0,0 +1,218 @@
1
+ module ::JdbcSpec
2
+ module ActiveRecordExtensions
3
+ def hsqldb_connection(config)
4
+ require File.dirname(__FILE__) + "/../active_record/connection_adapters/hsqldb_adapter"
5
+ config[:url] ||= "jdbc:hsqldb:#{config[:database]}"
6
+ config[:driver] ||= "org.hsqldb.jdbcDriver"
7
+ embedded_driver(config)
8
+ end
9
+
10
+ def h2_connection(config)
11
+ require File.dirname(__FILE__) + "/../active_record/connection_adapters/h2_adapter"
12
+ config[:url] ||= "jdbc:h2:#{config[:database]}"
13
+ config[:driver] ||= "org.h2.Driver"
14
+ embedded_driver(config)
15
+ end
16
+ end
17
+
18
+ module HSQLDB
19
+ def self.extended(mod)
20
+ mod.class.class_eval do
21
+ alias_chained_method :insert, :query_dirty, :insert
22
+ end
23
+ end
24
+
25
+ def self.adapter_matcher(name, *)
26
+ name =~ /hsqldb/i ? self : false
27
+ end
28
+
29
+ def self.column_selector
30
+ [/hsqldb|\.h2\./i, lambda {|cfg,col| col.extend(::JdbcSpec::HSQLDB::Column)}]
31
+ end
32
+
33
+ module Column
34
+ private
35
+ def simplified_type(field_type)
36
+ case field_type
37
+ when /longvarchar/i
38
+ :text
39
+ when /tinyint/i
40
+ :boolean
41
+ else
42
+ super(field_type)
43
+ end
44
+ end
45
+
46
+ # Override of ActiveRecord::ConnectionAdapters::Column
47
+ def extract_limit(sql_type)
48
+ # HSQLDB appears to return "LONGVARCHAR(0)" for :text columns, which
49
+ # for AR purposes should be interpreted as "no limit"
50
+ return nil if sql_type =~ /\(0\)/
51
+ super
52
+ end
53
+
54
+ # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
55
+ def default_value(value)
56
+ # jdbc returns column default strings with actual single quotes around the value.
57
+ return $1 if value =~ /^'(.*)'$/
58
+
59
+ value
60
+ end
61
+ end
62
+
63
+ def adapter_name #:nodoc:
64
+ defined?(::Jdbc::H2) ? 'h2' : 'hsqldb'
65
+ end
66
+
67
+ def modify_types(tp)
68
+ tp[:primary_key] = "INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY"
69
+ tp[:integer][:limit] = nil
70
+ tp[:boolean][:limit] = nil
71
+ # set text and float limits so we don't see odd scales tacked on
72
+ # in migrations
73
+ tp[:boolean] = { :name => "tinyint" }
74
+ tp[:text][:limit] = nil
75
+ tp[:float][:limit] = 17 if defined?(::Jdbc::H2)
76
+ tp[:string][:limit] = 255
77
+ tp[:datetime] = { :name => "DATETIME" }
78
+ tp[:timestamp] = { :name => "DATETIME" }
79
+ tp[:time] = { :name => "TIME" }
80
+ tp[:date] = { :name => "DATE" }
81
+ tp
82
+ end
83
+
84
+ def quote(value, column = nil) # :nodoc:
85
+ return value.quoted_id if value.respond_to?(:quoted_id)
86
+
87
+ case value
88
+ when String
89
+ if respond_to?(:h2_adapter) && value.empty?
90
+ "''"
91
+ elsif column && column.type == :binary
92
+ "'#{value.unpack("H*")}'"
93
+ elsif column.respond_to?(:primary) && column.primary && column.klass != String
94
+ value.to_i.to_s
95
+ else
96
+ "'#{quote_string(value)}'"
97
+ end
98
+ else
99
+ super
100
+ end
101
+ end
102
+
103
+ def quote_column_name(name) #:nodoc:
104
+ name = name.to_s
105
+ if name =~ /[-]/
106
+ %Q{"#{name.upcase}"}
107
+ else
108
+ name
109
+ end
110
+ end
111
+
112
+ def quote_string(str)
113
+ str.gsub(/'/, "''")
114
+ end
115
+
116
+ def quoted_true
117
+ '1'
118
+ end
119
+
120
+ def quoted_false
121
+ '0'
122
+ end
123
+
124
+ def add_column(table_name, column_name, type, options = {})
125
+ if option_not_null = options[:null] == false
126
+ option_not_null = options.delete(:null)
127
+ end
128
+ add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
129
+ add_column_options!(add_column_sql, options)
130
+ execute(add_column_sql)
131
+ if option_not_null
132
+ alter_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} NOT NULL"
133
+ end
134
+ end
135
+
136
+ def change_column(table_name, column_name, type, options = {}) #:nodoc:
137
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
138
+ end
139
+
140
+ def change_column_default(table_name, column_name, default) #:nodoc:
141
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DEFAULT #{quote(default)}"
142
+ end
143
+
144
+ def rename_column(table_name, column_name, new_column_name) #:nodoc:
145
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} RENAME TO #{new_column_name}"
146
+ end
147
+
148
+ # Maps logical Rails types to MySQL-specific data types.
149
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
150
+ return super if defined?(::Jdbc::H2) || type.to_s != 'integer' || limit == nil
151
+
152
+ type
153
+ end
154
+
155
+ def rename_table(name, new_name)
156
+ execute "ALTER TABLE #{name} RENAME TO #{new_name}"
157
+ end
158
+
159
+ def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
160
+ log(sql,name) do
161
+ @connection.execute_update(sql)
162
+ end
163
+ table = sql.split(" ", 4)[2]
164
+ id_value || last_insert_id(table, nil)
165
+ end
166
+
167
+ def last_insert_id(table, sequence_name)
168
+ Integer(select_value("CALL IDENTITY()"))
169
+ end
170
+
171
+ # Override normal #_execute: See Rubyforge #11567
172
+ def _execute(sql, name = nil)
173
+ if ::ActiveRecord::ConnectionAdapters::JdbcConnection::select?(sql)
174
+ @connection.execute_query(sql)
175
+ elsif ::ActiveRecord::ConnectionAdapters::JdbcConnection::insert?(sql)
176
+ insert(sql, name)
177
+ else
178
+ @connection.execute_update(sql)
179
+ end
180
+ end
181
+
182
+ def add_limit_offset!(sql, options) #:nodoc:
183
+ offset = options[:offset] || 0
184
+ bef = sql[7..-1]
185
+ if limit = options[:limit]
186
+ sql.replace "select limit #{offset} #{limit} #{bef}"
187
+ elsif offset > 0
188
+ sql.replace "select limit #{offset} 0 #{bef}"
189
+ end
190
+ end
191
+
192
+ # override to filter out system tables that otherwise end
193
+ # up in db/schema.rb during migrations. JdbcConnection#tables
194
+ # now takes an optional block filter so we can screen out
195
+ # rows corresponding to system tables. HSQLDB names its
196
+ # system tables SYSTEM.*, but H2 seems to name them without
197
+ # any kind of convention
198
+ def tables
199
+ @connection.tables.select {|row| row.to_s !~ /^system_/i }
200
+ end
201
+
202
+ def remove_index(table_name, options = {})
203
+ execute "DROP INDEX #{quote_column_name(index_name(table_name, options))}"
204
+ end
205
+ end
206
+
207
+ module H2
208
+ include HSQLDB
209
+
210
+ def self.adapter_matcher(name, *)
211
+ name =~ /\.h2\./i ? self : false
212
+ end
213
+
214
+ def h2_adapter
215
+ true
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,147 @@
1
+ module ::ActiveRecord
2
+ class Base
3
+ after_save :write_lobs
4
+
5
+ private
6
+ def write_lobs
7
+ if connection.is_a?(JdbcSpec::Informix)
8
+ self.class.columns.each do |c|
9
+ if [:text, :binary].include? c.type
10
+ value = self[c.name]
11
+ value = value.to_yaml if unserializable_attribute?(c.name, c)
12
+
13
+ unless value.nil? || (value == '')
14
+ connection.write_large_object(c.type == :binary,
15
+ c.name,
16
+ self.class.table_name,
17
+ self.class.primary_key,
18
+ quote_value(id),
19
+ value)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ module ::JdbcSpec
29
+ module ActiveRecordExtensions
30
+ def informix_connection(config)
31
+ config[:port] ||= 9088
32
+ config[:url] ||= "jdbc:informix-sqli://#{config[:host]}:#{config[:port]}/#{config[:database]}:INFORMIXSERVER=#{config[:servername]}"
33
+ config[:driver] = 'com.informix.jdbc.IfxDriver'
34
+ jdbc_connection(config)
35
+ end
36
+ end
37
+
38
+ module Informix
39
+ def self.extended(base)
40
+ @@db_major_version = base.select_one("SELECT dbinfo('version', 'major') version FROM systables WHERE tabid = 1")['version'].to_i
41
+ end
42
+
43
+ def self.adapter_matcher(name, *)
44
+ name =~ /informix/i ? self : false
45
+ end
46
+
47
+ def self.column_selector
48
+ [ /informix/i,
49
+ lambda { |cfg, column| column.extend(::JdbcSpec::Informix::Column) } ]
50
+ end
51
+
52
+ module Column
53
+ private
54
+ # TODO: Test all Informix column types.
55
+ def simplified_type(field_type)
56
+ if field_type =~ /serial/i
57
+ :primary_key
58
+ else
59
+ super
60
+ end
61
+ end
62
+ end
63
+
64
+ def modify_types(tp)
65
+ tp[:primary_key] = "SERIAL PRIMARY KEY"
66
+ tp[:string] = { :name => "VARCHAR", :limit => 255 }
67
+ tp[:integer] = { :name => "INTEGER" }
68
+ tp[:float] = { :name => "FLOAT" }
69
+ tp[:decimal] = { :name => "DECIMAL" }
70
+ tp[:datetime] = { :name => "DATETIME YEAR TO FRACTION(5)" }
71
+ tp[:timestamp] = { :name => "DATETIME YEAR TO FRACTION(5)" }
72
+ tp[:time] = { :name => "DATETIME HOUR TO FRACTION(5)" }
73
+ tp[:date] = { :name => "DATE" }
74
+ tp[:binary] = { :name => "BYTE" }
75
+ tp[:boolean] = { :name => "BOOLEAN" }
76
+ tp
77
+ end
78
+
79
+ def prefetch_primary_key?(table_name = nil)
80
+ true
81
+ end
82
+
83
+ def supports_migrations?
84
+ true
85
+ end
86
+
87
+ def default_sequence_name(table, column)
88
+ "#{table}_seq"
89
+ end
90
+
91
+ def add_limit_offset!(sql, options)
92
+ if options[:limit]
93
+ limit = "FIRST #{options[:limit]}"
94
+ # SKIP available only in IDS >= 10
95
+ offset = (@@db_major_version >= 10 && options[:offset]?
96
+ "SKIP #{options[:offset]}" : "")
97
+ sql.sub!(/^select /i, "SELECT #{offset} #{limit} ")
98
+ end
99
+ sql
100
+ end
101
+
102
+ def next_sequence_value(sequence_name)
103
+ select_one("SELECT #{sequence_name}.nextval id FROM systables WHERE tabid=1")['id']
104
+ end
105
+
106
+ # TODO: Add some smart quoting for newlines in string and text fields.
107
+ def quote_string(string)
108
+ string.gsub(/\'/, "''")
109
+ end
110
+
111
+ def quote(value, column = nil)
112
+ if column && [:binary, :text].include?(column.type)
113
+ # LOBs are updated separately by an after_save trigger.
114
+ "NULL"
115
+ elsif column && column.type == :date
116
+ "'#{value.mon}/#{value.day}/#{value.year}'"
117
+ else
118
+ super
119
+ end
120
+ end
121
+
122
+ def create_table(name, options = {})
123
+ super(name, options)
124
+ execute("CREATE SEQUENCE #{name}_seq")
125
+ end
126
+
127
+ def rename_table(name, new_name)
128
+ execute("RENAME TABLE #{name} TO #{new_name}")
129
+ execute("RENAME SEQUENCE #{name}_seq TO #{new_name}_seq")
130
+ end
131
+
132
+ def drop_table(name)
133
+ super(name)
134
+ execute("DROP SEQUENCE #{name}_seq")
135
+ end
136
+
137
+ def remove_index(table_name, options = {})
138
+ @connection.execute_update("DROP INDEX #{index_name(table_name, options)}")
139
+ end
140
+
141
+ private
142
+ def select(sql, name = nil)
143
+ # Informix does not like "= NULL", "!= NULL", or "<> NULL".
144
+ execute(sql.gsub(/(!=|<>)\s*null/i, "IS NOT NULL").gsub(/=\s*null/i, "IS NULL"), name)
145
+ end
146
+ end # module Informix
147
+ end # module ::JdbcSpec
@@ -0,0 +1,141 @@
1
+ module JdbcSpec
2
+ module Mimer
3
+ def self.adapter_matcher(name, *)
4
+ name =~ /mimer/i ? self : false
5
+ end
6
+
7
+ def modify_types(tp)
8
+ tp[:primary_key] = "INTEGER NOT NULL PRIMARY KEY"
9
+ tp[:boolean][:limit] = nil
10
+ tp[:string][:limit] = 255
11
+ tp[:binary] = {:name => "BINARY VARYING", :limit => 4096}
12
+ tp[:text] = {:name => "VARCHAR", :limit => 4096}
13
+ tp[:datetime] = { :name => "TIMESTAMP" }
14
+ tp[:timestamp] = { :name => "TIMESTAMP" }
15
+ tp[:time] = { :name => "TIMESTAMP" }
16
+ tp[:date] = { :name => "TIMESTAMP" }
17
+ tp
18
+ end
19
+
20
+ def default_sequence_name(table, column) #:nodoc:
21
+ "#{table}_seq"
22
+ end
23
+
24
+ def create_table(name, options = {}) #:nodoc:
25
+ super(name, options)
26
+ execute "CREATE SEQUENCE #{name}_seq" unless options[:id] == false
27
+ end
28
+
29
+ def drop_table(name, options = {}) #:nodoc:
30
+ super(name) rescue nil
31
+ execute "DROP SEQUENCE #{name}_seq" rescue nil
32
+ end
33
+
34
+ def change_column(table_name, column_name, type, options = {}) #:nodoc:
35
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
36
+ end
37
+
38
+ def change_column_default(table_name, column_name, default) #:nodoc:
39
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DEFAULT #{quote(default)}"
40
+ end
41
+
42
+ def remove_index(table_name, options = {}) #:nodoc:
43
+ execute "DROP INDEX #{index_name(table_name, options)}"
44
+ end
45
+
46
+ def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
47
+ if pk.nil? # Who called us? What does the sql look like? No idea!
48
+ execute sql, name
49
+ elsif id_value # Pre-assigned id
50
+ log(sql, name) { @connection.execute_insert sql,pk }
51
+ else # Assume the sql contains a bind-variable for the id
52
+ id_value = select_one("SELECT NEXT_VALUE OF #{sequence_name} AS val FROM MIMER.ONEROW")['val']
53
+ log(sql, name) {
54
+ execute_prepared_insert(sql,id_value)
55
+ }
56
+ end
57
+ id_value
58
+ end
59
+
60
+ def execute_prepared_insert(sql, id)
61
+ @stmts ||= {}
62
+ @stmts[sql] ||= @connection.ps(sql)
63
+ stmt = @stmts[sql]
64
+ stmt.setLong(1,id)
65
+ stmt.executeUpdate
66
+ id
67
+ end
68
+
69
+ def quote(value, column = nil) #:nodoc:
70
+ return value.quoted_id if value.respond_to?(:quoted_id)
71
+
72
+ if String === value && column && column.type == :binary
73
+ return "X'#{quote_string(value.unpack("C*").collect {|v| v.to_s(16)}.join)}'"
74
+ end
75
+ case value
76
+ when String
77
+ %Q{'#{quote_string(value)}'}
78
+ when NilClass
79
+ 'NULL'
80
+ when TrueClass
81
+ '1'
82
+ when FalseClass
83
+ '0'
84
+ when Numeric
85
+ value.to_s
86
+ when Date, Time
87
+ %Q{TIMESTAMP '#{value.strftime("%Y-%m-%d %H:%M:%S")}'}
88
+ else
89
+ %Q{'#{quote_string(value.to_yaml)}'}
90
+ end
91
+ end
92
+
93
+ def quoted_true
94
+ '1'
95
+ end
96
+
97
+ def quoted_false
98
+ '0'
99
+ end
100
+
101
+ def add_limit_offset!(sql, options) # :nodoc:
102
+ @limit = options[:limit]
103
+ @offset = options[:offset]
104
+ end
105
+
106
+ def select_all(sql, name = nil)
107
+ @offset ||= 0
108
+ if !@limit || @limit == -1
109
+ range = @offset..-1
110
+ else
111
+ range = @offset...(@offset+@limit)
112
+ end
113
+ select(sql, name)[range]
114
+ ensure
115
+ @limit = @offset = nil
116
+ end
117
+
118
+ def select_one(sql, name = nil)
119
+ @offset ||= 0
120
+ select(sql, name)[@offset]
121
+ ensure
122
+ @limit = @offset = nil
123
+ end
124
+
125
+ def _execute(sql, name = nil)
126
+ if sql =~ /^select/i
127
+ @offset ||= 0
128
+ if !@limit || @limit == -1
129
+ range = @offset..-1
130
+ else
131
+ range = @offset...(@offset+@limit)
132
+ end
133
+ @connection.execute_query(sql)[range]
134
+ else
135
+ @connection.execute_update(sql)
136
+ end
137
+ ensure
138
+ @limit = @offset = nil
139
+ end
140
+ end
141
+ end