activerecord-jdbc-adapter-onsite 1.2.2
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/.gitignore +22 -0
- data/.travis.yml +14 -0
- data/Appraisals +16 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +45 -0
- data/History.txt +488 -0
- data/LICENSE.txt +21 -0
- data/README.rdoc +214 -0
- data/Rakefile +62 -0
- data/activerecord-jdbc-adapter.gemspec +23 -0
- data/bench/bench_attributes.rb +13 -0
- data/bench/bench_attributes_new.rb +14 -0
- data/bench/bench_create.rb +12 -0
- data/bench/bench_find_all.rb +12 -0
- data/bench/bench_find_all_mt.rb +25 -0
- data/bench/bench_model.rb +85 -0
- data/bench/bench_new.rb +12 -0
- data/bench/bench_new_valid.rb +12 -0
- data/bench/bench_valid.rb +13 -0
- data/gemfiles/rails23.gemfile +10 -0
- data/gemfiles/rails23.gemfile.lock +38 -0
- data/gemfiles/rails30.gemfile +9 -0
- data/gemfiles/rails30.gemfile.lock +33 -0
- data/gemfiles/rails31.gemfile +9 -0
- data/gemfiles/rails31.gemfile.lock +35 -0
- data/gemfiles/rails32.gemfile +9 -0
- data/gemfiles/rails32.gemfile.lock +35 -0
- data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/h2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
- data/lib/activerecord-jdbc-adapter.rb +8 -0
- data/lib/arel/engines/sql/compilers/db2_compiler.rb +9 -0
- data/lib/arel/engines/sql/compilers/derby_compiler.rb +6 -0
- data/lib/arel/engines/sql/compilers/h2_compiler.rb +6 -0
- data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +15 -0
- data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +6 -0
- data/lib/arel/engines/sql/compilers/mssql_compiler.rb +46 -0
- data/lib/arel/visitors/compat.rb +13 -0
- data/lib/arel/visitors/db2.rb +17 -0
- data/lib/arel/visitors/derby.rb +32 -0
- data/lib/arel/visitors/firebird.rb +24 -0
- data/lib/arel/visitors/hsqldb.rb +26 -0
- data/lib/arel/visitors/sql_server.rb +46 -0
- data/lib/arjdbc.rb +24 -0
- data/lib/arjdbc/db2.rb +2 -0
- data/lib/arjdbc/db2/adapter.rb +541 -0
- data/lib/arjdbc/derby.rb +7 -0
- data/lib/arjdbc/derby/adapter.rb +358 -0
- data/lib/arjdbc/derby/connection_methods.rb +19 -0
- data/lib/arjdbc/discover.rb +92 -0
- data/lib/arjdbc/firebird.rb +2 -0
- data/lib/arjdbc/firebird/adapter.rb +140 -0
- data/lib/arjdbc/h2.rb +4 -0
- data/lib/arjdbc/h2/adapter.rb +54 -0
- data/lib/arjdbc/h2/connection_methods.rb +13 -0
- data/lib/arjdbc/hsqldb.rb +4 -0
- data/lib/arjdbc/hsqldb/adapter.rb +184 -0
- data/lib/arjdbc/hsqldb/connection_methods.rb +15 -0
- data/lib/arjdbc/informix.rb +3 -0
- data/lib/arjdbc/informix/adapter.rb +142 -0
- data/lib/arjdbc/informix/connection_methods.rb +11 -0
- data/lib/arjdbc/jdbc.rb +2 -0
- data/lib/arjdbc/jdbc/adapter.rb +356 -0
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/base_ext.rb +15 -0
- data/lib/arjdbc/jdbc/callbacks.rb +44 -0
- data/lib/arjdbc/jdbc/column.rb +47 -0
- data/lib/arjdbc/jdbc/compatibility.rb +51 -0
- data/lib/arjdbc/jdbc/connection.rb +134 -0
- data/lib/arjdbc/jdbc/connection_methods.rb +16 -0
- data/lib/arjdbc/jdbc/core_ext.rb +24 -0
- data/lib/arjdbc/jdbc/discover.rb +18 -0
- data/lib/arjdbc/jdbc/driver.rb +35 -0
- data/lib/arjdbc/jdbc/extension.rb +47 -0
- data/lib/arjdbc/jdbc/java.rb +14 -0
- data/lib/arjdbc/jdbc/jdbc.rake +131 -0
- data/lib/arjdbc/jdbc/missing_functionality_helper.rb +88 -0
- data/lib/arjdbc/jdbc/quoted_primary_key.rb +28 -0
- data/lib/arjdbc/jdbc/railtie.rb +9 -0
- data/lib/arjdbc/jdbc/rake_tasks.rb +10 -0
- data/lib/arjdbc/jdbc/require_driver.rb +16 -0
- data/lib/arjdbc/jdbc/type_converter.rb +126 -0
- data/lib/arjdbc/mimer.rb +2 -0
- data/lib/arjdbc/mimer/adapter.rb +142 -0
- data/lib/arjdbc/mssql.rb +4 -0
- data/lib/arjdbc/mssql/adapter.rb +477 -0
- data/lib/arjdbc/mssql/connection_methods.rb +31 -0
- data/lib/arjdbc/mssql/limit_helpers.rb +101 -0
- data/lib/arjdbc/mssql/lock_helpers.rb +72 -0
- data/lib/arjdbc/mssql/tsql_helper.rb +61 -0
- data/lib/arjdbc/mysql.rb +4 -0
- data/lib/arjdbc/mysql/adapter.rb +505 -0
- data/lib/arjdbc/mysql/connection_methods.rb +28 -0
- data/lib/arjdbc/oracle.rb +3 -0
- data/lib/arjdbc/oracle/adapter.rb +432 -0
- data/lib/arjdbc/oracle/connection_methods.rb +12 -0
- data/lib/arjdbc/postgresql.rb +4 -0
- data/lib/arjdbc/postgresql/adapter.rb +861 -0
- data/lib/arjdbc/postgresql/connection_methods.rb +23 -0
- data/lib/arjdbc/sqlite3.rb +4 -0
- data/lib/arjdbc/sqlite3/adapter.rb +389 -0
- data/lib/arjdbc/sqlite3/connection_methods.rb +35 -0
- data/lib/arjdbc/sybase.rb +2 -0
- data/lib/arjdbc/sybase/adapter.rb +46 -0
- data/lib/arjdbc/version.rb +8 -0
- data/lib/generators/jdbc/USAGE +10 -0
- data/lib/generators/jdbc/jdbc_generator.rb +9 -0
- data/lib/jdbc_adapter.rb +2 -0
- data/lib/jdbc_adapter/rake_tasks.rb +3 -0
- data/lib/jdbc_adapter/version.rb +3 -0
- data/lib/pg.rb +26 -0
- data/pom.xml +57 -0
- data/rails_generators/jdbc_generator.rb +15 -0
- data/rails_generators/templates/config/initializers/jdbc.rb +7 -0
- data/rails_generators/templates/lib/tasks/jdbc.rake +8 -0
- data/rakelib/bundler_ext.rb +11 -0
- data/rakelib/compile.rake +23 -0
- data/rakelib/db.rake +39 -0
- data/rakelib/rails.rake +41 -0
- data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +69 -0
- data/src/java/arjdbc/derby/DerbyModule.java +324 -0
- data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +70 -0
- data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +74 -0
- data/src/java/arjdbc/jdbc/AdapterJavaService.java +68 -0
- data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +36 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +1346 -0
- data/src/java/arjdbc/jdbc/SQLBlock.java +48 -0
- data/src/java/arjdbc/mssql/MssqlRubyJdbcConnection.java +127 -0
- data/src/java/arjdbc/mysql/MySQLModule.java +134 -0
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +161 -0
- data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +85 -0
- data/src/java/arjdbc/postgresql/PostgresqlRubyJdbcConnection.java +82 -0
- data/src/java/arjdbc/sqlite3/Sqlite3RubyJdbcConnection.java +126 -0
- data/test/abstract_db_create.rb +135 -0
- data/test/activerecord/connection_adapters/type_conversion_test.rb +31 -0
- data/test/activerecord/connections/native_jdbc_mysql/connection.rb +25 -0
- data/test/activerecord/jall.sh +7 -0
- data/test/activerecord/jtest.sh +3 -0
- data/test/db/db2.rb +11 -0
- data/test/db/derby.rb +12 -0
- data/test/db/h2.rb +11 -0
- data/test/db/hsqldb.rb +13 -0
- data/test/db/informix.rb +11 -0
- data/test/db/jdbc.rb +12 -0
- data/test/db/jndi_config.rb +40 -0
- data/test/db/logger.rb +3 -0
- data/test/db/mssql.rb +9 -0
- data/test/db/mysql.rb +10 -0
- data/test/db/oracle.rb +34 -0
- data/test/db/postgres.rb +18 -0
- data/test/db/sqlite3.rb +11 -0
- data/test/db2_reset_column_information_test.rb +8 -0
- data/test/db2_simple_test.rb +66 -0
- data/test/derby_migration_test.rb +68 -0
- data/test/derby_multibyte_test.rb +12 -0
- data/test/derby_reset_column_information_test.rb +8 -0
- data/test/derby_row_locking_test.rb +9 -0
- data/test/derby_simple_test.rb +139 -0
- data/test/generic_jdbc_connection_test.rb +29 -0
- data/test/h2_change_column_test.rb +68 -0
- data/test/h2_simple_test.rb +41 -0
- data/test/has_many_through.rb +79 -0
- data/test/helper.rb +108 -0
- data/test/hsqldb_simple_test.rb +6 -0
- data/test/informix_simple_test.rb +48 -0
- data/test/jdbc_common.rb +28 -0
- data/test/jndi_callbacks_test.rb +36 -0
- data/test/jndi_test.rb +25 -0
- data/test/manualTestDatabase.rb +191 -0
- data/test/models/add_not_null_column_to_table.rb +9 -0
- data/test/models/auto_id.rb +15 -0
- data/test/models/custom_pk_name.rb +14 -0
- data/test/models/data_types.rb +30 -0
- data/test/models/entry.rb +40 -0
- data/test/models/mixed_case.rb +22 -0
- data/test/models/reserved_word.rb +15 -0
- data/test/models/string_id.rb +17 -0
- data/test/models/thing.rb +16 -0
- data/test/models/validates_uniqueness_of_string.rb +19 -0
- data/test/mssql_db_create_test.rb +26 -0
- data/test/mssql_identity_insert_test.rb +19 -0
- data/test/mssql_ignore_system_views_test.rb +27 -0
- data/test/mssql_legacy_types_test.rb +58 -0
- data/test/mssql_limit_offset_test.rb +136 -0
- data/test/mssql_multibyte_test.rb +18 -0
- data/test/mssql_null_test.rb +14 -0
- data/test/mssql_reset_column_information_test.rb +8 -0
- data/test/mssql_row_locking_sql_test.rb +159 -0
- data/test/mssql_row_locking_test.rb +9 -0
- data/test/mssql_simple_test.rb +55 -0
- data/test/mysql_db_create_test.rb +27 -0
- data/test/mysql_index_length_test.rb +58 -0
- data/test/mysql_info_test.rb +123 -0
- data/test/mysql_multibyte_test.rb +10 -0
- data/test/mysql_nonstandard_primary_key_test.rb +42 -0
- data/test/mysql_reset_column_information_test.rb +8 -0
- data/test/mysql_simple_test.rb +125 -0
- data/test/oracle_reset_column_information_test.rb +8 -0
- data/test/oracle_simple_test.rb +18 -0
- data/test/oracle_specific_test.rb +83 -0
- data/test/postgres_db_create_test.rb +32 -0
- data/test/postgres_drop_db_test.rb +16 -0
- data/test/postgres_information_schema_leak_test.rb +29 -0
- data/test/postgres_mixed_case_test.rb +29 -0
- data/test/postgres_native_type_mapping_test.rb +93 -0
- data/test/postgres_nonseq_pkey_test.rb +38 -0
- data/test/postgres_reserved_test.rb +22 -0
- data/test/postgres_reset_column_information_test.rb +8 -0
- data/test/postgres_schema_search_path_test.rb +48 -0
- data/test/postgres_simple_test.rb +168 -0
- data/test/postgres_table_alias_length_test.rb +15 -0
- data/test/postgres_type_conversion_test.rb +34 -0
- data/test/row_locking.rb +90 -0
- data/test/simple.rb +731 -0
- data/test/sqlite3_reset_column_information_test.rb +8 -0
- data/test/sqlite3_simple_test.rb +316 -0
- data/test/sybase_jtds_simple_test.rb +28 -0
- data/test/sybase_reset_column_information_test.rb +8 -0
- metadata +288 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module ArJdbc
|
|
2
|
+
module Sybase
|
|
3
|
+
def add_limit_offset!(sql, options) # :nodoc:
|
|
4
|
+
@limit = options[:limit]
|
|
5
|
+
@offset = options[:offset]
|
|
6
|
+
if use_temp_table?
|
|
7
|
+
# Use temp table to hack offset with Sybase
|
|
8
|
+
sql.sub!(/ FROM /i, ' INTO #artemp FROM ')
|
|
9
|
+
elsif zero_limit?
|
|
10
|
+
# "SET ROWCOUNT 0" turns off limits, so we havesy
|
|
11
|
+
# to use a cheap trick.
|
|
12
|
+
if sql =~ /WHERE/i
|
|
13
|
+
sql.sub!(/WHERE/i, 'WHERE 1 = 2 AND ')
|
|
14
|
+
elsif sql =~ /ORDER\s+BY/i
|
|
15
|
+
sql.sub!(/ORDER\s+BY/i, 'WHERE 1 = 2 ORDER BY')
|
|
16
|
+
else
|
|
17
|
+
sql << 'WHERE 1 = 2'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# If limit is not set at all, we can ignore offset;
|
|
23
|
+
# if limit *is* set but offset is zero, use normal select
|
|
24
|
+
# with simple SET ROWCOUNT. Thus, only use the temp table
|
|
25
|
+
# if limit is set and offset > 0.
|
|
26
|
+
def use_temp_table?
|
|
27
|
+
!@limit.nil? && !@offset.nil? && @offset > 0
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def zero_limit?
|
|
31
|
+
!@limit.nil? && @limit == 0
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def modify_types(tp) #:nodoc:
|
|
35
|
+
tp[:primary_key] = "NUMERIC(22,0) IDENTITY PRIMARY KEY"
|
|
36
|
+
tp[:integer][:limit] = nil
|
|
37
|
+
tp[:boolean] = {:name => "bit"}
|
|
38
|
+
tp[:binary] = {:name => "image"}
|
|
39
|
+
tp
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def remove_index(table_name, options = {})
|
|
43
|
+
execute "DROP INDEX #{table_name}.#{index_name(table_name, options)}"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/jdbc_adapter.rb
ADDED
data/lib/pg.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Stub library for postgresql -- allows Rails to load
|
|
2
|
+
# postgresql_adapter without error. Other than postgres-pr, there's no
|
|
3
|
+
# other way to use PostgreSQL on JRuby anyway, right? If you've
|
|
4
|
+
# installed ar-jdbc you probably want to use that to connect to pg.
|
|
5
|
+
#
|
|
6
|
+
# If by chance this library is installed in another Ruby and this file
|
|
7
|
+
# got required then we'll just continue to try to load the next pg.rb
|
|
8
|
+
# in the $LOAD_PATH.
|
|
9
|
+
|
|
10
|
+
unless defined?(JRUBY_VERSION)
|
|
11
|
+
gem 'pg' if respond_to?(:gem) # make sure pg gem is activated
|
|
12
|
+
after_current_file = false
|
|
13
|
+
$LOAD_PATH.each do |p|
|
|
14
|
+
require_file = File.join(p, 'pg.rb')
|
|
15
|
+
|
|
16
|
+
if File.expand_path(require_file) == File.expand_path(__FILE__)
|
|
17
|
+
after_current_file = true
|
|
18
|
+
next
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if after_current_file && File.exist?(require_file)
|
|
22
|
+
load require_file
|
|
23
|
+
break
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/pom.xml
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
2
|
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
3
|
+
<modelVersion>4.0.0</modelVersion>
|
|
4
|
+
<groupId>org.jruby.activerecord-jdbc</groupId>
|
|
5
|
+
<artifactId>activerecord-jdbc</artifactId>
|
|
6
|
+
<packaging>jar</packaging>
|
|
7
|
+
<version>1.0.0</version>
|
|
8
|
+
<name>activerecord-jdbc</name>
|
|
9
|
+
<description>
|
|
10
|
+
This POM for activerecord-jdbc is just for bootstrapping IDEs. You
|
|
11
|
+
can't use it to build the project at the moment.
|
|
12
|
+
</description>
|
|
13
|
+
<url>http://activerecord-jdbc.kenai.com/</url>
|
|
14
|
+
|
|
15
|
+
<issueManagement>
|
|
16
|
+
<system>JIRA</system>
|
|
17
|
+
<url>http://kenai.com/jira/browse/ACTIVERECORD_JDBC</url>
|
|
18
|
+
</issueManagement>
|
|
19
|
+
|
|
20
|
+
<scm>
|
|
21
|
+
<connection>scm:git:git://github.com/nicksieger/activerecord-jdbc-adapter.git</connection>
|
|
22
|
+
<developerConnection>scm:git:git@github.com:nicksieger/activerecord-jdbc-adapter.git</developerConnection>
|
|
23
|
+
<url>http://github.com/nicksieger/activerecord-jdbc-adapter</url>
|
|
24
|
+
</scm>
|
|
25
|
+
|
|
26
|
+
<licenses>
|
|
27
|
+
<license>
|
|
28
|
+
<name>BSD</name>
|
|
29
|
+
<url>http://www.opensource.org/licenses/bsd-license.php</url>
|
|
30
|
+
<distribution>repo</distribution>
|
|
31
|
+
</license>
|
|
32
|
+
</licenses>
|
|
33
|
+
|
|
34
|
+
<dependencies>
|
|
35
|
+
<dependency>
|
|
36
|
+
<groupId>org.jruby</groupId>
|
|
37
|
+
<artifactId>jruby-complete</artifactId>
|
|
38
|
+
<version>1.5.3</version>
|
|
39
|
+
</dependency>
|
|
40
|
+
</dependencies>
|
|
41
|
+
|
|
42
|
+
<build>
|
|
43
|
+
<outputDirectory>pkg/classes</outputDirectory>
|
|
44
|
+
<sourceDirectory>src/java</sourceDirectory>
|
|
45
|
+
<plugins>
|
|
46
|
+
<plugin>
|
|
47
|
+
<groupId>org.apache.maven.plugins</groupId>
|
|
48
|
+
<artifactId>maven-compiler-plugin</artifactId>
|
|
49
|
+
<configuration>
|
|
50
|
+
<source>1.5</source>
|
|
51
|
+
<target>1.5</target>
|
|
52
|
+
</configuration>
|
|
53
|
+
</plugin>
|
|
54
|
+
</plugins>
|
|
55
|
+
</build>
|
|
56
|
+
|
|
57
|
+
</project>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class JdbcGenerator < Rails::Generator::Base
|
|
2
|
+
def manifest
|
|
3
|
+
record do |m|
|
|
4
|
+
m.directory 'config/initializers'
|
|
5
|
+
m.template 'config/initializers/jdbc.rb', File.join('config', 'initializers', 'jdbc.rb')
|
|
6
|
+
m.directory 'lib/tasks'
|
|
7
|
+
m.template 'lib/tasks/jdbc.rake', File.join('lib', 'tasks', 'jdbc.rake')
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
protected
|
|
12
|
+
def banner
|
|
13
|
+
"Usage: #{$0} jdbc\nGenerate JDBC bootstrapping files for your Rails application."
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# This file was generated by the "jdbc" generator, which is provided
|
|
2
|
+
# by the activerecord-jdbc-adapter gem.
|
|
3
|
+
#
|
|
4
|
+
# This file allows the JDBC drivers to be hooked into ActiveRecord
|
|
5
|
+
# such that you don't have to change anything else in your Rails
|
|
6
|
+
# application.
|
|
7
|
+
require 'arjdbc' if defined?(JRUBY_VERSION)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# This file was generated by the "jdbc" generator, which is provided
|
|
2
|
+
# by the activerecord-jdbc-adapter gem.
|
|
3
|
+
#
|
|
4
|
+
# This file allows you to use Rails' various db:* tasks with JDBC.
|
|
5
|
+
if defined?(JRUBY_VERSION)
|
|
6
|
+
require 'arjdbc'
|
|
7
|
+
require 'arjdbc/jdbc/rake_tasks'
|
|
8
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
jar_file = File.join(*%w(lib arjdbc jdbc adapter_java.jar))
|
|
2
|
+
begin
|
|
3
|
+
require 'ant'
|
|
4
|
+
directory "pkg/classes"
|
|
5
|
+
CLEAN << "pkg"
|
|
6
|
+
|
|
7
|
+
file jar_file => FileList['src/java/**/*.java', 'pkg/classes'] do
|
|
8
|
+
rm_rf FileList['pkg/classes/**/*']
|
|
9
|
+
ant.javac :srcdir => "src/java", :destdir => "pkg/classes",
|
|
10
|
+
:source => "1.5", :target => "1.5", :debug => true,
|
|
11
|
+
:classpath => "${java.class.path}:${sun.boot.class.path}",
|
|
12
|
+
:includeantRuntime => false
|
|
13
|
+
|
|
14
|
+
ant.jar :basedir => "pkg/classes", :destfile => jar_file, :includes => "**/*.class"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
desc "Compile the native Java code."
|
|
18
|
+
task :jar => jar_file
|
|
19
|
+
rescue LoadError
|
|
20
|
+
task :jar do
|
|
21
|
+
puts "Run 'jar' with JRuby to re-compile the agent extension class"
|
|
22
|
+
end
|
|
23
|
+
end
|
data/rakelib/db.rake
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
namespace :db do
|
|
2
|
+
desc "Creates the test database for MySQL."
|
|
3
|
+
task :mysql do
|
|
4
|
+
load 'test/db/mysql.rb' rescue nil
|
|
5
|
+
t = Tempfile.new("mysql")
|
|
6
|
+
t.puts <<-SQL
|
|
7
|
+
DROP DATABASE IF EXISTS `#{MYSQL_CONFIG[:database]}`;
|
|
8
|
+
CREATE DATABASE `#{MYSQL_CONFIG[:database]}` DEFAULT CHARACTER SET `utf8`;
|
|
9
|
+
GRANT ALL PRIVILEGES ON `#{MYSQL_CONFIG[:database]}`.* TO #{MYSQL_CONFIG[:username]}@localhost;
|
|
10
|
+
GRANT ALL PRIVILEGES ON `test\_%`.* TO #{MYSQL_CONFIG[:username]}@localhost;
|
|
11
|
+
SET PASSWORD FOR #{MYSQL_CONFIG[:username]}@localhost = PASSWORD('#{MYSQL_CONFIG[:password]}');
|
|
12
|
+
SQL
|
|
13
|
+
t.close
|
|
14
|
+
at_exit { t.unlink }
|
|
15
|
+
password = ""
|
|
16
|
+
if ENV['DATABASE_YML']
|
|
17
|
+
require 'yaml'
|
|
18
|
+
password = YAML.load(File.new(ENV['DATABASE_YML']))["production"]["password"]
|
|
19
|
+
password_arg = " --password=#{password}"
|
|
20
|
+
end
|
|
21
|
+
sh "cat #{t.path} | mysql -u root#{password_arg}", :verbose => false # so password is not echoed
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
desc "Creates the test database for PostgreSQL."
|
|
25
|
+
task :postgres do
|
|
26
|
+
fail unless have_postgres?
|
|
27
|
+
load 'test/db/postgres.rb' rescue nil
|
|
28
|
+
t = Tempfile.new("psql")
|
|
29
|
+
t.puts <<-SQL
|
|
30
|
+
DROP DATABASE IF EXISTS #{POSTGRES_CONFIG[:database]};
|
|
31
|
+
DROP USER IF EXISTS #{POSTGRES_CONFIG[:username]};
|
|
32
|
+
CREATE USER #{POSTGRES_CONFIG[:username]} CREATEDB SUPERUSER LOGIN PASSWORD '#{POSTGRES_CONFIG[:password]}';
|
|
33
|
+
CREATE DATABASE #{POSTGRES_CONFIG[:database]} OWNER #{POSTGRES_CONFIG[:username]};
|
|
34
|
+
SQL
|
|
35
|
+
t.close
|
|
36
|
+
at_exit { t.unlink }
|
|
37
|
+
sh "cat #{t.path} | psql -U postgres"
|
|
38
|
+
end
|
|
39
|
+
end
|
data/rakelib/rails.rake
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
namespace :rails do
|
|
2
|
+
def _adapter(n)
|
|
3
|
+
case n
|
|
4
|
+
when /postgres/
|
|
5
|
+
'postgresql'
|
|
6
|
+
else
|
|
7
|
+
n
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def _driver(n)
|
|
12
|
+
case n
|
|
13
|
+
when /postgres/
|
|
14
|
+
'postgres'
|
|
15
|
+
else
|
|
16
|
+
n
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def _target(n)
|
|
21
|
+
case n
|
|
22
|
+
when /postgres/
|
|
23
|
+
'test_jdbcpostgresql'
|
|
24
|
+
else
|
|
25
|
+
"test_jdbc#{n}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
task :test => :jar do
|
|
30
|
+
driver = ENV['DRIVER']
|
|
31
|
+
raise "need a DRIVER" unless driver
|
|
32
|
+
activerecord = ENV['RAILS']
|
|
33
|
+
raise "need location of RAILS source code" unless activerecord
|
|
34
|
+
activerecord = File.join(activerecord, 'activerecord') unless activerecord =~ /activerecord$/
|
|
35
|
+
ar_jdbc = File.expand_path(File.dirname(__FILE__) + '/..')
|
|
36
|
+
rubylib = "#{ar_jdbc}/lib:#{ar_jdbc}/jdbc-#{_driver(driver)}/lib:#{ar_jdbc}/activerecord-jdbc#{_adapter(driver)}-adapter/lib"
|
|
37
|
+
Dir.chdir(activerecord) do
|
|
38
|
+
rake "RUBYLIB=#{rubylib}", "#{_target(driver)}"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/*
|
|
2
|
+
**** BEGIN LICENSE BLOCK *****
|
|
3
|
+
* Copyright (c) 2006-2010 Nick Sieger <nick@nicksieger.com>
|
|
4
|
+
* Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
|
|
5
|
+
* Copyright (c) 2008-2009 Thomas E Enebo <enebo@acm.org>
|
|
6
|
+
*
|
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining
|
|
8
|
+
* a copy of this software and associated documentation files (the
|
|
9
|
+
* "Software"), to deal in the Software without restriction, including
|
|
10
|
+
* without limitation the rights to use, copy, modify, merge, publish,
|
|
11
|
+
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
12
|
+
* permit persons to whom the Software is furnished to do so, subject to
|
|
13
|
+
* the following conditions:
|
|
14
|
+
*
|
|
15
|
+
* The above copyright notice and this permission notice shall be
|
|
16
|
+
* included in all copies or substantial portions of the Software.
|
|
17
|
+
*
|
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
19
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
20
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
21
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
22
|
+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
23
|
+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
24
|
+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
25
|
+
***** END LICENSE BLOCK *****/
|
|
26
|
+
package arjdbc.db2;
|
|
27
|
+
|
|
28
|
+
import org.jruby.Ruby;
|
|
29
|
+
import org.jruby.RubyClass;
|
|
30
|
+
import org.jruby.runtime.ObjectAllocator;
|
|
31
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
|
32
|
+
|
|
33
|
+
import arjdbc.jdbc.RubyJdbcConnection;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
*
|
|
37
|
+
* @author mikestone
|
|
38
|
+
*/
|
|
39
|
+
public class DB2RubyJdbcConnection extends RubyJdbcConnection {
|
|
40
|
+
private static final String[] TABLE_TYPES = new String[]{"TABLE", "VIEW", "SYNONYM", "MATERIALIZED QUERY TABLE", "ALIAS"};
|
|
41
|
+
|
|
42
|
+
protected DB2RubyJdbcConnection(Ruby runtime, RubyClass metaClass) {
|
|
43
|
+
super(runtime, metaClass);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@Override
|
|
47
|
+
protected String[] getTableTypes() {
|
|
48
|
+
return TABLE_TYPES;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@Override
|
|
52
|
+
protected boolean databaseSupportsSchemas() {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public static RubyClass createDB2JdbcConnectionClass(Ruby runtime, RubyClass jdbcConnection) {
|
|
57
|
+
RubyClass clazz = RubyJdbcConnection.getConnectionAdapters(runtime).defineClassUnder("DB2JdbcConnection",
|
|
58
|
+
jdbcConnection, DB2_JDBCCONNECTION_ALLOCATOR);
|
|
59
|
+
clazz.defineAnnotatedMethods(DB2RubyJdbcConnection.class);
|
|
60
|
+
|
|
61
|
+
return clazz;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private static ObjectAllocator DB2_JDBCCONNECTION_ALLOCATOR = new ObjectAllocator() {
|
|
65
|
+
public IRubyObject allocate(Ruby runtime, RubyClass klass) {
|
|
66
|
+
return new DB2RubyJdbcConnection(runtime, klass);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/***** BEGIN LICENSE BLOCK *****
|
|
2
|
+
* Copyright (c) 2006-2011 Nick Sieger <nick@nicksieger.com>
|
|
3
|
+
* Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
|
|
4
|
+
*
|
|
5
|
+
* Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
* a copy of this software and associated documentation files (the
|
|
7
|
+
* "Software"), to deal in the Software without restriction, including
|
|
8
|
+
* without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
* permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
* the following conditions:
|
|
12
|
+
*
|
|
13
|
+
* The above copyright notice and this permission notice shall be
|
|
14
|
+
* included in all copies or substantial portions of the Software.
|
|
15
|
+
*
|
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
+
***** END LICENSE BLOCK *****/
|
|
24
|
+
|
|
25
|
+
package arjdbc.derby;
|
|
26
|
+
|
|
27
|
+
import java.sql.SQLException;
|
|
28
|
+
|
|
29
|
+
import arjdbc.jdbc.RubyJdbcConnection;
|
|
30
|
+
|
|
31
|
+
import org.jruby.Ruby;
|
|
32
|
+
import org.jruby.RubyBoolean;
|
|
33
|
+
import org.jruby.RubyModule;
|
|
34
|
+
import org.jruby.RubyObjectAdapter;
|
|
35
|
+
import org.jruby.RubyRange;
|
|
36
|
+
import org.jruby.RubyString;
|
|
37
|
+
import org.jruby.anno.JRubyMethod;
|
|
38
|
+
import org.jruby.runtime.ThreadContext;
|
|
39
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
|
40
|
+
import org.jruby.util.ByteList;
|
|
41
|
+
|
|
42
|
+
public class DerbyModule {
|
|
43
|
+
private static RubyObjectAdapter rubyApi;
|
|
44
|
+
public static void load(RubyModule arJdbc, RubyObjectAdapter adapter) {
|
|
45
|
+
RubyModule derby = arJdbc.defineModuleUnder("Derby");
|
|
46
|
+
derby.defineAnnotatedMethods(DerbyModule.class);
|
|
47
|
+
RubyModule column = derby.defineModuleUnder("Column");
|
|
48
|
+
column.defineAnnotatedMethods(Column.class);
|
|
49
|
+
rubyApi = adapter;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public static class Column {
|
|
53
|
+
@JRubyMethod(name = "type_cast", required = 1)
|
|
54
|
+
public static IRubyObject type_cast(IRubyObject recv, IRubyObject value) {
|
|
55
|
+
Ruby runtime = recv.getRuntime();
|
|
56
|
+
|
|
57
|
+
if (value.isNil() || ((value instanceof RubyString) && value.toString().trim().equalsIgnoreCase("null"))) {
|
|
58
|
+
return runtime.getNil();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
String type = rubyApi.getInstanceVariable(recv, "@type").toString();
|
|
62
|
+
|
|
63
|
+
switch (type.charAt(0)) {
|
|
64
|
+
case 's': //string
|
|
65
|
+
return value;
|
|
66
|
+
case 't': //text, timestamp, time
|
|
67
|
+
if (type.equals("text")) {
|
|
68
|
+
return value;
|
|
69
|
+
} else if (type.equals("timestamp")) {
|
|
70
|
+
return rubyApi.callMethod(recv.getMetaClass(), "string_to_time", value);
|
|
71
|
+
} else { //time
|
|
72
|
+
return rubyApi.callMethod(recv.getMetaClass(), "string_to_dummy_time", value);
|
|
73
|
+
}
|
|
74
|
+
case 'i': //integer
|
|
75
|
+
case 'p': //primary key
|
|
76
|
+
if (value.respondsTo("to_i")) {
|
|
77
|
+
return rubyApi.callMethod(value, "to_i");
|
|
78
|
+
} else {
|
|
79
|
+
return runtime.newFixnum(value.isTrue() ? 1 : 0);
|
|
80
|
+
}
|
|
81
|
+
case 'd': //decimal, datetime, date
|
|
82
|
+
if (type.equals("datetime")) {
|
|
83
|
+
return rubyApi.callMethod(recv.getMetaClass(), "string_to_time", value);
|
|
84
|
+
} else if (type.equals("date")) {
|
|
85
|
+
return rubyApi.callMethod(recv.getMetaClass(), "string_to_date", value);
|
|
86
|
+
} else {
|
|
87
|
+
return rubyApi.callMethod(recv.getMetaClass(), "value_to_decimal", value);
|
|
88
|
+
}
|
|
89
|
+
case 'f': //float
|
|
90
|
+
return rubyApi.callMethod(value, "to_f");
|
|
91
|
+
case 'b': //binary, boolean
|
|
92
|
+
if (type.equals("binary")) {
|
|
93
|
+
return rubyApi.callMethod(recv.getMetaClass(), "binary_to_string", value);
|
|
94
|
+
} else {
|
|
95
|
+
return rubyApi.callMethod(recv.getMetaClass(), "value_to_boolean", value);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return value;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@JRubyMethod(name = "quote", required = 1, optional = 1)
|
|
103
|
+
public static IRubyObject quote(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
|
|
104
|
+
Ruby runtime = recv.getRuntime();
|
|
105
|
+
IRubyObject value = args[0];
|
|
106
|
+
if (args.length > 1) {
|
|
107
|
+
IRubyObject col = args[1];
|
|
108
|
+
String type = rubyApi.callMethod(col, "type").toString();
|
|
109
|
+
// intercept and change value, maybe, if the column type is :text or :string
|
|
110
|
+
if (type.equals("text") || type.equals("string")) {
|
|
111
|
+
value = make_ruby_string_for_text_column(context, recv, runtime, value);
|
|
112
|
+
}
|
|
113
|
+
String metaClass = value.getMetaClass().getName();
|
|
114
|
+
|
|
115
|
+
if (value instanceof RubyString) {
|
|
116
|
+
if (type.equals("string")) {
|
|
117
|
+
return quote_string_with_surround(runtime, "'", (RubyString)value, "'");
|
|
118
|
+
} else if (type.equals("text")) {
|
|
119
|
+
return quote_string_with_surround(runtime, "CAST('", (RubyString)value, "' AS CLOB)");
|
|
120
|
+
} else if (type.equals("binary")) {
|
|
121
|
+
return hexquote_string_with_surround(runtime, "CAST(X'", (RubyString)value, "' AS BLOB)");
|
|
122
|
+
} else {
|
|
123
|
+
// column type :integer or other numeric or date version
|
|
124
|
+
if (only_digits((RubyString)value)) {
|
|
125
|
+
return value;
|
|
126
|
+
} else {
|
|
127
|
+
return super_quote(context, recv, runtime, value, col);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
} else if (metaClass.equals("Float") || metaClass.equals("Fixnum") || metaClass.equals("Bignum")) {
|
|
131
|
+
if (type.equals("string")) {
|
|
132
|
+
return quote_string_with_surround(runtime, "'", RubyString.objAsString(context, value), "'");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return super_quote(context, recv, runtime, value, runtime.getNil());
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/*
|
|
140
|
+
* Derby is not permissive like MySql. Try and send an Integer to a CLOB or VARCHAR column and Derby will vomit.
|
|
141
|
+
* This method turns non stringy things into strings.
|
|
142
|
+
*/
|
|
143
|
+
private static IRubyObject make_ruby_string_for_text_column(ThreadContext context, IRubyObject recv, Ruby runtime, IRubyObject value) {
|
|
144
|
+
RubyModule multibyteChars = (RubyModule)
|
|
145
|
+
((RubyModule) ((RubyModule) runtime.getModule("ActiveSupport")).getConstant("Multibyte")).getConstantAt("Chars");
|
|
146
|
+
if (value instanceof RubyString || rubyApi.isKindOf(value, multibyteChars) || value.isNil()) {
|
|
147
|
+
return value;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
String metaClass = value.getMetaClass().getName();
|
|
151
|
+
|
|
152
|
+
if (value instanceof RubyBoolean) {
|
|
153
|
+
return value.isTrue() ? runtime.newString("1") : runtime.newString("0");
|
|
154
|
+
} else if (metaClass.equals("Float") || metaClass.equals("Fixnum") || metaClass.equals("Bignum")) {
|
|
155
|
+
return RubyString.objAsString(context, value);
|
|
156
|
+
} else if (metaClass.equals("BigDecimal")) {
|
|
157
|
+
return rubyApi.callMethod(value, "to_s", runtime.newString("F"));
|
|
158
|
+
} else {
|
|
159
|
+
if (rubyApi.callMethod(value, "acts_like?", runtime.newString("date")).isTrue() || rubyApi.callMethod(value, "acts_like?", runtime.newString("time")).isTrue()) {
|
|
160
|
+
return (RubyString)rubyApi.callMethod(recv, "quoted_date", value);
|
|
161
|
+
} else {
|
|
162
|
+
return (RubyString)rubyApi.callMethod(value, "to_yaml");
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private final static ByteList NULL = new ByteList("NULL".getBytes());
|
|
168
|
+
|
|
169
|
+
private static IRubyObject super_quote(ThreadContext context, IRubyObject recv, Ruby runtime, IRubyObject value, IRubyObject col) {
|
|
170
|
+
if (value.respondsTo("quoted_id")) {
|
|
171
|
+
return rubyApi.callMethod(value, "quoted_id");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
String metaClass = value.getMetaClass().getName();
|
|
175
|
+
|
|
176
|
+
IRubyObject type = (col.isNil()) ? col : rubyApi.callMethod(col, "type");
|
|
177
|
+
RubyModule multibyteChars = (RubyModule)
|
|
178
|
+
((RubyModule) ((RubyModule) runtime.getModule("ActiveSupport")).getConstant("Multibyte")).getConstantAt("Chars");
|
|
179
|
+
if (value instanceof RubyString || rubyApi.isKindOf(value, multibyteChars)) {
|
|
180
|
+
RubyString svalue = RubyString.objAsString(context, value);
|
|
181
|
+
if (type == runtime.newSymbol("binary") && col.getType().respondsTo("string_to_binary")) {
|
|
182
|
+
return quote_string_with_surround(runtime, "'", (RubyString)(rubyApi.callMethod(col.getType(), "string_to_binary", svalue)), "'");
|
|
183
|
+
} else if (type == runtime.newSymbol("integer") || type == runtime.newSymbol("float")) {
|
|
184
|
+
return RubyString.objAsString(context, ((type == runtime.newSymbol("integer")) ?
|
|
185
|
+
rubyApi.callMethod(svalue, "to_i") :
|
|
186
|
+
rubyApi.callMethod(svalue, "to_f")));
|
|
187
|
+
} else {
|
|
188
|
+
return quote_string_with_surround(runtime, "'", svalue, "'");
|
|
189
|
+
}
|
|
190
|
+
} else if (value.isNil()) {
|
|
191
|
+
return runtime.newString(NULL);
|
|
192
|
+
} else if (value instanceof RubyBoolean) {
|
|
193
|
+
return (value.isTrue() ?
|
|
194
|
+
(type == runtime.newSymbol(":integer")) ? runtime.newString("1") : rubyApi.callMethod(recv, "quoted_true") :
|
|
195
|
+
(type == runtime.newSymbol(":integer")) ? runtime.newString("0") : rubyApi.callMethod(recv, "quoted_false"));
|
|
196
|
+
} else if (metaClass.equals("Float") || metaClass.equals("Fixnum") || metaClass.equals("Bignum")) {
|
|
197
|
+
return RubyString.objAsString(context, value);
|
|
198
|
+
} else if (metaClass.equals("BigDecimal")) {
|
|
199
|
+
return rubyApi.callMethod(value, "to_s", runtime.newString("F"));
|
|
200
|
+
} else if (rubyApi.callMethod(value, "acts_like?", runtime.newString("date")).isTrue() || rubyApi.callMethod(value, "acts_like?", runtime.newString("time")).isTrue()) {
|
|
201
|
+
return quote_string_with_surround(runtime, "'", (RubyString)(rubyApi.callMethod(recv, "quoted_date", value)), "'");
|
|
202
|
+
} else {
|
|
203
|
+
return quote_string_with_surround(runtime, "'", (RubyString)(rubyApi.callMethod(value, "to_yaml")), "'");
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
private final static ByteList TWO_SINGLE = new ByteList(new byte[]{'\'','\''});
|
|
208
|
+
|
|
209
|
+
private static IRubyObject quote_string_with_surround(Ruby runtime, String before, RubyString string, String after) {
|
|
210
|
+
ByteList input = string.getByteList();
|
|
211
|
+
ByteList output = new ByteList(before.getBytes());
|
|
212
|
+
for(int i = input.begin; i< input.begin + input.realSize; i++) {
|
|
213
|
+
switch(input.bytes[i]) {
|
|
214
|
+
case '\'':
|
|
215
|
+
output.append(input.bytes[i]);
|
|
216
|
+
//FALLTHROUGH
|
|
217
|
+
default:
|
|
218
|
+
output.append(input.bytes[i]);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
output.append(after.getBytes());
|
|
224
|
+
|
|
225
|
+
return runtime.newString(output);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
private final static byte[] HEX = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
|
229
|
+
|
|
230
|
+
private static IRubyObject hexquote_string_with_surround(Ruby runtime, String before, RubyString string, String after) {
|
|
231
|
+
ByteList input = string.getByteList();
|
|
232
|
+
ByteList output = new ByteList(before.getBytes());
|
|
233
|
+
int written = 0;
|
|
234
|
+
for(int i = input.begin; i< input.begin + input.realSize; i++) {
|
|
235
|
+
byte b1 = input.bytes[i];
|
|
236
|
+
byte higher = HEX[(((char)b1)>>4)%16];
|
|
237
|
+
byte lower = HEX[((char)b1)%16];
|
|
238
|
+
output.append(higher);
|
|
239
|
+
output.append(lower);
|
|
240
|
+
written += 2;
|
|
241
|
+
if(written >= 16334) { // max hex length = 16334
|
|
242
|
+
output.append("'||X'".getBytes());
|
|
243
|
+
written = 0;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
output.append(after.getBytes());
|
|
248
|
+
return runtime.newStringShared(output);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
private static boolean only_digits(RubyString inp) {
|
|
252
|
+
ByteList input = inp.getByteList();
|
|
253
|
+
for(int i = input.begin; i< input.begin + input.realSize; i++) {
|
|
254
|
+
if(input.bytes[i] < '0' || input.bytes[i] > '9') {
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return true;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
@JRubyMethod(name = "quote_string", required = 1)
|
|
262
|
+
public static IRubyObject quote_string(IRubyObject recv, IRubyObject string) {
|
|
263
|
+
boolean replacementFound = false;
|
|
264
|
+
ByteList bl = ((RubyString) string).getByteList();
|
|
265
|
+
|
|
266
|
+
for(int i = bl.begin; i < bl.begin + bl.realSize; i++) {
|
|
267
|
+
switch (bl.bytes[i]) {
|
|
268
|
+
case '\'': break;
|
|
269
|
+
default: continue;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// On first replacement allocate a different bytelist so we don't manip original
|
|
273
|
+
if(!replacementFound) {
|
|
274
|
+
i-= bl.begin;
|
|
275
|
+
bl = new ByteList(bl);
|
|
276
|
+
replacementFound = true;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
bl.replace(i, 1, TWO_SINGLE);
|
|
280
|
+
i+=1;
|
|
281
|
+
}
|
|
282
|
+
if(replacementFound) {
|
|
283
|
+
return recv.getRuntime().newStringShared(bl);
|
|
284
|
+
} else {
|
|
285
|
+
return string;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
@JRubyMethod(name = "select_all", rest = true)
|
|
290
|
+
public static IRubyObject select_all(IRubyObject recv, IRubyObject[] args) {
|
|
291
|
+
return rubyApi.callMethod(recv, "execute", args);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
@JRubyMethod(name = "select_one", rest = true)
|
|
295
|
+
public static IRubyObject select_one(IRubyObject recv, IRubyObject[] args) {
|
|
296
|
+
IRubyObject limit = rubyApi.getInstanceVariable(recv, "@limit");
|
|
297
|
+
if (limit == null || limit.isNil()) {
|
|
298
|
+
rubyApi.setInstanceVariable(recv, "@limit", recv.getRuntime().newFixnum(1));
|
|
299
|
+
}
|
|
300
|
+
try {
|
|
301
|
+
IRubyObject result = rubyApi.callMethod(recv, "execute", args);
|
|
302
|
+
return rubyApi.callMethod(result, "first");
|
|
303
|
+
} finally {
|
|
304
|
+
rubyApi.setInstanceVariable(recv, "@limit", recv.getRuntime().getNil());
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
@JRubyMethod(name = "_execute", required = 1, optional = 1)
|
|
309
|
+
public static IRubyObject _execute(ThreadContext context, IRubyObject recv, IRubyObject[] args) throws SQLException, java.io.IOException {
|
|
310
|
+
Ruby runtime = recv.getRuntime();
|
|
311
|
+
RubyJdbcConnection conn = (RubyJdbcConnection) rubyApi.getInstanceVariable(recv, "@connection");
|
|
312
|
+
String sql = args[0].toString().trim().toLowerCase();
|
|
313
|
+
if (sql.charAt(0) == '(') {
|
|
314
|
+
sql = sql.substring(1).trim();
|
|
315
|
+
}
|
|
316
|
+
if (sql.startsWith("insert")) {
|
|
317
|
+
return conn.execute_insert(context, args[0]);
|
|
318
|
+
} else if (sql.startsWith("select") || sql.startsWith("show") || sql.startsWith("values")) {
|
|
319
|
+
return conn.execute_query(context, args[0]);
|
|
320
|
+
} else {
|
|
321
|
+
return conn.execute_update(context, args[0]);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|