activerecord-jdbc-adapter 1.3.0.beta2 → 1.3.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +14 -8
- data/.travis.yml +40 -31
- data/.yardopts +4 -0
- data/Appraisals +2 -5
- data/CONTRIBUTING.md +46 -0
- data/Gemfile +21 -4
- data/Gemfile.lock +42 -17
- data/{History.txt → History.md} +142 -75
- data/README.md +102 -104
- data/RUNNING_TESTS.md +76 -0
- data/Rakefile.jdbc +20 -0
- data/activerecord-jdbc-adapter.gemspec +35 -18
- data/gemfiles/rails23.gemfile +4 -3
- data/gemfiles/rails23.gemfile.lock +9 -6
- data/gemfiles/rails30.gemfile +4 -3
- data/gemfiles/rails30.gemfile.lock +9 -6
- data/gemfiles/rails31.gemfile +4 -3
- data/gemfiles/rails31.gemfile.lock +9 -6
- data/gemfiles/rails32.gemfile +4 -3
- data/gemfiles/rails32.gemfile.lock +17 -14
- data/gemfiles/rails40.gemfile +5 -5
- data/gemfiles/rails40.gemfile.lock +17 -69
- data/lib/active_record/connection_adapters/firebird_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
- data/lib/arel/visitors/compat.rb +22 -3
- data/lib/arel/visitors/db2.rb +8 -4
- data/lib/arel/visitors/derby.rb +14 -13
- data/lib/arel/visitors/firebird.rb +5 -4
- data/lib/arel/visitors/hsqldb.rb +11 -9
- data/lib/arel/visitors/sql_server.rb +89 -61
- data/lib/arjdbc.rb +1 -1
- data/lib/arjdbc/db2/adapter.rb +181 -212
- data/lib/arjdbc/db2/as400.rb +31 -18
- data/lib/arjdbc/db2/column.rb +167 -0
- data/lib/arjdbc/db2/connection_methods.rb +2 -0
- data/lib/arjdbc/derby/adapter.rb +206 -107
- data/lib/arjdbc/derby/connection_methods.rb +4 -9
- data/lib/arjdbc/firebird.rb +1 -0
- data/lib/arjdbc/firebird/adapter.rb +202 -64
- data/lib/arjdbc/firebird/connection_methods.rb +20 -0
- data/lib/arjdbc/h2/adapter.rb +56 -36
- data/lib/arjdbc/hsqldb/adapter.rb +99 -68
- data/lib/arjdbc/jdbc/adapter.rb +474 -265
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/adapter_require.rb +8 -7
- data/lib/arjdbc/jdbc/arel_support.rb +132 -0
- data/lib/arjdbc/jdbc/base_ext.rb +8 -7
- data/lib/arjdbc/jdbc/callbacks.rb +16 -10
- data/lib/arjdbc/jdbc/column.rb +25 -3
- data/lib/arjdbc/jdbc/connection.rb +28 -55
- data/lib/arjdbc/jdbc/extension.rb +14 -14
- data/lib/arjdbc/jdbc/java.rb +6 -3
- data/lib/arjdbc/jdbc/jdbc.rake +1 -1
- data/lib/arjdbc/jdbc/quoted_primary_key.rb +2 -2
- data/lib/arjdbc/jdbc/rake_tasks.rb +1 -1
- data/lib/arjdbc/jdbc/type_converter.rb +5 -2
- data/lib/arjdbc/mssql/adapter.rb +160 -280
- data/lib/arjdbc/mssql/column.rb +182 -0
- data/lib/arjdbc/mssql/connection_methods.rb +37 -4
- data/lib/arjdbc/mssql/explain_support.rb +13 -21
- data/lib/arjdbc/mssql/limit_helpers.rb +79 -42
- data/lib/arjdbc/mssql/lock_methods.rb +77 -0
- data/lib/arjdbc/mssql/utils.rb +11 -11
- data/lib/arjdbc/mysql/adapter.rb +165 -247
- data/lib/arjdbc/mysql/column.rb +123 -0
- data/lib/arjdbc/mysql/connection_methods.rb +3 -6
- data/lib/arjdbc/oracle/adapter.rb +282 -288
- data/lib/arjdbc/oracle/column.rb +122 -0
- data/lib/arjdbc/oracle/connection_methods.rb +3 -0
- data/lib/arjdbc/postgresql/adapter.rb +336 -574
- data/lib/arjdbc/postgresql/column.rb +458 -0
- data/lib/arjdbc/postgresql/connection_methods.rb +1 -2
- data/lib/arjdbc/postgresql/schema_creation.rb +38 -0
- data/lib/arjdbc/sqlite3/adapter.rb +189 -145
- data/lib/arjdbc/sqlite3/explain_support.rb +1 -1
- data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +8 -8
- data/lib/arjdbc/util/quoted_cache.rb +60 -0
- data/lib/arjdbc/util/table_copier.rb +110 -0
- data/lib/arjdbc/version.rb +6 -7
- data/pom.xml +56 -2
- data/rakelib/02-test.rake +72 -83
- data/rakelib/db.rake +29 -17
- data/src/java/arjdbc/ArJdbcModule.java +21 -18
- data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +84 -12
- data/src/java/arjdbc/derby/DerbyModule.java +140 -143
- data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +58 -7
- data/src/java/arjdbc/h2/H2Module.java +43 -0
- data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +7 -6
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +1223 -648
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +24 -23
- data/src/java/arjdbc/mysql/MySQLModule.java +33 -32
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +147 -30
- data/src/java/arjdbc/oracle/OracleModule.java +13 -13
- data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +114 -6
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +166 -36
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +101 -19
- data/src/java/arjdbc/util/QuotingUtils.java +19 -19
- metadata +240 -394
- data/bench/bench_attributes.rb +0 -13
- data/bench/bench_attributes_new.rb +0 -14
- data/bench/bench_create.rb +0 -12
- data/bench/bench_find_all.rb +0 -12
- data/bench/bench_find_all_mt.rb +0 -25
- data/bench/bench_model.rb +0 -85
- data/bench/bench_new.rb +0 -12
- data/bench/bench_new_valid.rb +0 -12
- data/bench/bench_valid.rb +0 -13
- data/lib/arel/engines/sql/compilers/db2_compiler.rb +0 -9
- data/lib/arel/engines/sql/compilers/derby_compiler.rb +0 -6
- data/lib/arel/engines/sql/compilers/h2_compiler.rb +0 -6
- data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +0 -15
- data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +0 -6
- data/lib/arel/engines/sql/compilers/mssql_compiler.rb +0 -46
- data/lib/arjdbc/jdbc/missing_functionality_helper.rb +0 -98
- data/lib/arjdbc/mssql/lock_helpers.rb +0 -76
- data/lib/arjdbc/mssql/tsql_methods.rb +0 -58
- data/lib/arjdbc/postgresql/column_cast.rb +0 -134
- data/test/activerecord/connections/native_jdbc_mysql/connection.rb +0 -25
- data/test/activerecord/jall.sh +0 -7
- data/test/activerecord/jtest.sh +0 -3
- data/test/assets/flowers.jpg +0 -0
- data/test/binary.rb +0 -67
- data/test/db/db2.rb +0 -43
- data/test/db/db2/binary_test.rb +0 -6
- data/test/db/db2/has_many_through_test.rb +0 -6
- data/test/db/db2/rake_test.rb +0 -82
- data/test/db/db2/rake_test_data.sql +0 -35
- data/test/db/db2/reset_column_information_test.rb +0 -5
- data/test/db/db2/serialize_test.rb +0 -6
- data/test/db/db2/simple_test.rb +0 -81
- data/test/db/db2/test_helper.rb +0 -6
- data/test/db/db2/unit_test.rb +0 -73
- data/test/db/derby.rb +0 -12
- data/test/db/derby/binary_test.rb +0 -6
- data/test/db/derby/migration_test.rb +0 -74
- data/test/db/derby/rake_test.rb +0 -96
- data/test/db/derby/reset_column_information_test.rb +0 -6
- data/test/db/derby/row_locking_test.rb +0 -20
- data/test/db/derby/schema_dump_test.rb +0 -5
- data/test/db/derby/serialize_test.rb +0 -6
- data/test/db/derby/simple_test.rb +0 -173
- data/test/db/derby/test_helper.rb +0 -6
- data/test/db/derby/unit_test.rb +0 -32
- data/test/db/derby/xml_column_test.rb +0 -17
- data/test/db/h2.rb +0 -11
- data/test/db/h2/binary_test.rb +0 -6
- data/test/db/h2/change_column_test.rb +0 -68
- data/test/db/h2/identity_column_test.rb +0 -35
- data/test/db/h2/offset_test.rb +0 -49
- data/test/db/h2/rake_test.rb +0 -98
- data/test/db/h2/schema_dump_test.rb +0 -29
- data/test/db/h2/serialize_test.rb +0 -6
- data/test/db/h2/simple_test.rb +0 -56
- data/test/db/hsqldb.rb +0 -11
- data/test/db/hsqldb/binary_test.rb +0 -6
- data/test/db/hsqldb/rake_test.rb +0 -101
- data/test/db/hsqldb/schema_dump_test.rb +0 -19
- data/test/db/hsqldb/serialize_test.rb +0 -6
- data/test/db/hsqldb/simple_test.rb +0 -17
- data/test/db/informix.rb +0 -13
- data/test/db/jdbc.rb +0 -16
- data/test/db/jdbc_derby.rb +0 -14
- data/test/db/jdbc_h2.rb +0 -17
- data/test/db/jdbc_mysql.rb +0 -13
- data/test/db/jdbc_postgres.rb +0 -23
- data/test/db/jndi_config.rb +0 -32
- data/test/db/jndi_pooled_config.rb +0 -32
- data/test/db/mssql.rb +0 -11
- data/test/db/mssql/binary_test.rb +0 -6
- data/test/db/mssql/exec_proc_test.rb +0 -46
- data/test/db/mssql/identity_insert_test.rb +0 -18
- data/test/db/mssql/ignore_system_views_test.rb +0 -40
- data/test/db/mssql/limit_offset_test.rb +0 -190
- data/test/db/mssql/multibyte_test.rb +0 -16
- data/test/db/mssql/multiple_connections_test.rb +0 -71
- data/test/db/mssql/rake_test.rb +0 -143
- data/test/db/mssql/reset_column_information_test.rb +0 -6
- data/test/db/mssql/row_locking_test.rb +0 -7
- data/test/db/mssql/serialize_test.rb +0 -6
- data/test/db/mssql/simple_test.rb +0 -140
- data/test/db/mssql/transaction_test.rb +0 -6
- data/test/db/mssql/types_test.rb +0 -205
- data/test/db/mssql/unit_test.rb +0 -249
- data/test/db/mysql.rb +0 -4
- data/test/db/mysql/_rails_test_mysql.32.out +0 -6585
- data/test/db/mysql/binary_test.rb +0 -6
- data/test/db/mysql/connection_test.rb +0 -51
- data/test/db/mysql/index_length_test.rb +0 -58
- data/test/db/mysql/multibyte_test.rb +0 -10
- data/test/db/mysql/nonstandard_primary_key_test.rb +0 -39
- data/test/db/mysql/rake_test.rb +0 -97
- data/test/db/mysql/reset_column_information_test.rb +0 -6
- data/test/db/mysql/schema_dump_test.rb +0 -228
- data/test/db/mysql/serialize_test.rb +0 -6
- data/test/db/mysql/simple_test.rb +0 -187
- data/test/db/mysql/statement_escaping_test.rb +0 -46
- data/test/db/mysql/transaction_test.rb +0 -6
- data/test/db/mysql/types_test.rb +0 -30
- data/test/db/mysql/unit_test.rb +0 -93
- data/test/db/mysql_config.rb +0 -7
- data/test/db/oracle.rb +0 -27
- data/test/db/oracle/binary_test.rb +0 -6
- data/test/db/oracle/limit_test.rb +0 -24
- data/test/db/oracle/multibyte_test.rb +0 -22
- data/test/db/oracle/rake_test.rb +0 -100
- data/test/db/oracle/reset_column_information_test.rb +0 -6
- data/test/db/oracle/serialize_test.rb +0 -6
- data/test/db/oracle/simple_test.rb +0 -140
- data/test/db/oracle/specific_test.rb +0 -180
- data/test/db/oracle/transaction_test.rb +0 -31
- data/test/db/oracle/unit_test.rb +0 -31
- data/test/db/postgres.rb +0 -11
- data/test/db/postgres/_rails_test_postgres.32.out +0 -6405
- data/test/db/postgres/a_custom_primary_key_test.rb +0 -50
- data/test/db/postgres/active_schema_unit_test.rb +0 -68
- data/test/db/postgres/array_type_test.rb +0 -101
- data/test/db/postgres/binary_test.rb +0 -6
- data/test/db/postgres/connection_test.rb +0 -63
- data/test/db/postgres/data_types_test.rb +0 -703
- data/test/db/postgres/hstore_test.rb +0 -200
- data/test/db/postgres/information_schema_leak_test.rb +0 -30
- data/test/db/postgres/json_test.rb +0 -86
- data/test/db/postgres/ltree_test.rb +0 -51
- data/test/db/postgres/mixed_case_test.rb +0 -29
- data/test/db/postgres/native_types_test.rb +0 -124
- data/test/db/postgres/rake_test.rb +0 -117
- data/test/db/postgres/reserved_test.rb +0 -22
- data/test/db/postgres/reset_column_information_test.rb +0 -6
- data/test/db/postgres/row_locking_test.rb +0 -21
- data/test/db/postgres/schema_dump_test.rb +0 -95
- data/test/db/postgres/schema_test.rb +0 -115
- data/test/db/postgres/simple_test.rb +0 -260
- data/test/db/postgres/table_alias_length_test.rb +0 -16
- data/test/db/postgres/transaction_test.rb +0 -6
- data/test/db/postgres/unit_test.rb +0 -31
- data/test/db/postgres_config.rb +0 -10
- data/test/db/sqlite3.rb +0 -6
- data/test/db/sqlite3/_rails_test_sqlite3.32.out +0 -6274
- data/test/db/sqlite3/has_many_though_test.rb +0 -6
- data/test/db/sqlite3/rake_test.rb +0 -71
- data/test/db/sqlite3/reset_column_information_test.rb +0 -6
- data/test/db/sqlite3/schema_dump_test.rb +0 -6
- data/test/db/sqlite3/serialize_test.rb +0 -6
- data/test/db/sqlite3/simple_test.rb +0 -268
- data/test/db/sqlite3/transaction_test.rb +0 -32
- data/test/db/sqlite3/type_conversion_test.rb +0 -104
- data/test/has_many_through.rb +0 -61
- data/test/informix_simple_test.rb +0 -48
- data/test/jdbc/db2.rb +0 -36
- data/test/jdbc/oracle.rb +0 -34
- data/test/jdbc_column_test.rb +0 -23
- data/test/jdbc_common.rb +0 -16
- data/test/jdbc_connection_test.rb +0 -196
- data/test/jndi_callbacks_test.rb +0 -33
- data/test/jndi_test.rb +0 -55
- data/test/manualTestDatabase.rb +0 -191
- data/test/models/add_not_null_column_to_table.rb +0 -9
- data/test/models/auto_id.rb +0 -15
- data/test/models/binary.rb +0 -18
- data/test/models/custom_pk_name.rb +0 -15
- data/test/models/data_types.rb +0 -40
- data/test/models/entry.rb +0 -41
- data/test/models/mixed_case.rb +0 -22
- data/test/models/reserved_word.rb +0 -15
- data/test/models/rights_and_roles.rb +0 -57
- data/test/models/string_id.rb +0 -17
- data/test/models/thing.rb +0 -17
- data/test/models/topic.rb +0 -32
- data/test/models/validates_uniqueness_of_string.rb +0 -19
- data/test/rails/mysql.rb +0 -13
- data/test/rails/sqlite3/version.rb +0 -6
- data/test/rails_stub.rb +0 -31
- data/test/rake_test_support.rb +0 -298
- data/test/row_locking.rb +0 -102
- data/test/schema_dump.rb +0 -182
- data/test/serialize.rb +0 -275
- data/test/shared_helper.rb +0 -35
- data/test/simple.rb +0 -1317
- data/test/sybase_jtds_simple_test.rb +0 -28
- data/test/sybase_reset_column_information_test.rb +0 -6
- data/test/test_helper.rb +0 -304
- data/test/transaction.rb +0 -109
@@ -0,0 +1,458 @@
|
|
1
|
+
module ArJdbc
|
2
|
+
module PostgreSQL
|
3
|
+
|
4
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcColumn#column_types
|
5
|
+
def self.column_selector
|
6
|
+
[ /postgre/i, lambda { |cfg, column| column.extend(Column) } ]
|
7
|
+
end
|
8
|
+
|
9
|
+
# Column behavior based on PostgreSQL adapter in Rails.
|
10
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcColumn
|
11
|
+
module Column
|
12
|
+
|
13
|
+
def self.included(base)
|
14
|
+
# NOTE: assumes a standalone PostgreSQLColumn class
|
15
|
+
class << base
|
16
|
+
include Cast
|
17
|
+
attr_accessor :money_precision
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_accessor :array
|
22
|
+
def array?; array; end # in case we remove the array reader
|
23
|
+
|
24
|
+
# Extracts the value from a PostgreSQL column default definition.
|
25
|
+
#
|
26
|
+
# @override JdbcColumn#default_value
|
27
|
+
# NOTE: based on `self.extract_value_from_default(default)` code
|
28
|
+
def default_value(default)
|
29
|
+
# This is a performance optimization for Ruby 1.9.2 in development.
|
30
|
+
# If the value is nil, we return nil straight away without checking
|
31
|
+
# the regular expressions. If we check each regular expression,
|
32
|
+
# Regexp#=== will call NilClass#to_str, which will trigger
|
33
|
+
# method_missing (defined by whiny nil in ActiveSupport) which
|
34
|
+
# makes this method very very slow.
|
35
|
+
return default unless default
|
36
|
+
|
37
|
+
case default
|
38
|
+
when /\A'(.*)'::(num|date|tstz|ts|int4|int8)range\z/m
|
39
|
+
$1
|
40
|
+
# Numeric types
|
41
|
+
when /\A\(?(-?\d+(\.\d*)?\)?)\z/
|
42
|
+
$1
|
43
|
+
# Character types
|
44
|
+
when /\A\(?'(.*)'::.*\b(?:character varying|bpchar|text)\z/m
|
45
|
+
$1
|
46
|
+
# Binary data types
|
47
|
+
when /\A'(.*)'::bytea\z/m
|
48
|
+
$1
|
49
|
+
# Date/time types
|
50
|
+
when /\A'(.+)'::(?:time(?:stamp)? with(?:out)? time zone|date)\z/
|
51
|
+
$1
|
52
|
+
when /\A'(.*)'::interval\z/
|
53
|
+
$1
|
54
|
+
# Boolean type
|
55
|
+
when 'true'
|
56
|
+
true
|
57
|
+
when 'false'
|
58
|
+
false
|
59
|
+
# Geometric types
|
60
|
+
when /\A'(.*)'::(?:point|line|lseg|box|"?path"?|polygon|circle)\z/
|
61
|
+
$1
|
62
|
+
# Network address types
|
63
|
+
when /\A'(.*)'::(?:cidr|inet|macaddr)\z/
|
64
|
+
$1
|
65
|
+
# Bit string types
|
66
|
+
when /\AB'(.*)'::"?bit(?: varying)?"?\z/
|
67
|
+
$1
|
68
|
+
# XML type
|
69
|
+
when /\A'(.*)'::xml\z/m
|
70
|
+
$1
|
71
|
+
# Arrays
|
72
|
+
when /\A'(.*)'::"?\D+"?\[\]\z/
|
73
|
+
$1
|
74
|
+
when /\AARRAY\[(.*)\](::\D+)?\z/
|
75
|
+
"{#{$1.gsub(/'(.*?)'::[a-z]+(,)?\s?/, '\1\2')}}"
|
76
|
+
# Hstore
|
77
|
+
when /\A'(.*)'::hstore\z/
|
78
|
+
$1
|
79
|
+
# JSON
|
80
|
+
when /\A'(.*)'::json\z/
|
81
|
+
$1
|
82
|
+
# Object identifier types
|
83
|
+
when /\A-?\d+\z/
|
84
|
+
$1
|
85
|
+
else
|
86
|
+
# Anything else is blank, some user type, or some function
|
87
|
+
# and we can't know the value of that, so return nil.
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Casts value (which is a String) to an appropriate instance.
|
93
|
+
def type_cast(value)
|
94
|
+
return if value.nil?
|
95
|
+
return super if encoded? # respond_to?(:encoded?) only since AR-3.2
|
96
|
+
|
97
|
+
# NOTE: we do not use OID::Type
|
98
|
+
# @oid_type.type_cast value
|
99
|
+
|
100
|
+
return value if array? # handled on the connection (JDBC) side
|
101
|
+
|
102
|
+
case type
|
103
|
+
when :hstore then self.class.string_to_hstore value
|
104
|
+
when :json then self.class.string_to_json value
|
105
|
+
when :cidr, :inet then self.class.string_to_cidr value
|
106
|
+
when :macaddr then value
|
107
|
+
when :tsvector then value
|
108
|
+
when :datetime, :timestamp then self.class.string_to_time value
|
109
|
+
else
|
110
|
+
case sql_type
|
111
|
+
when 'money'
|
112
|
+
# Because money output is formatted according to the locale, there
|
113
|
+
# are two cases to consider (note the decimal separators) :
|
114
|
+
# (1) $12,345,678.12
|
115
|
+
# (2) $12.345.678,12
|
116
|
+
case value
|
117
|
+
when /^-?\D+[\d,]+\.\d{2}$/ # (1)
|
118
|
+
value.gsub!(/[^-\d.]/, '')
|
119
|
+
when /^-?\D+[\d.]+,\d{2}$/ # (2)
|
120
|
+
value.gsub!(/[^-\d,]/, '')
|
121
|
+
value.sub!(/,/, '.')
|
122
|
+
end
|
123
|
+
self.class.value_to_decimal value
|
124
|
+
when /^point/
|
125
|
+
value.is_a?(String) ? self.class.string_to_point(value) : value
|
126
|
+
when /^(bit|varbit)/
|
127
|
+
value.is_a?(String) ? self.class.string_to_bit(value) : value
|
128
|
+
when /(.*?)range$/
|
129
|
+
return if value.nil? || value == 'empty'
|
130
|
+
return value if value.is_a?(::Range)
|
131
|
+
|
132
|
+
extracted = extract_bounds(value)
|
133
|
+
|
134
|
+
case $1 # subtype
|
135
|
+
when 'date' # :date
|
136
|
+
from = self.class.value_to_date(extracted[:from])
|
137
|
+
from -= 1.day if extracted[:exclude_start]
|
138
|
+
to = self.class.value_to_date(extracted[:to])
|
139
|
+
when 'num' # :decimal
|
140
|
+
from = BigDecimal.new(extracted[:from].to_s)
|
141
|
+
# FIXME: add exclude start for ::Range, same for timestamp ranges
|
142
|
+
to = BigDecimal.new(extracted[:to].to_s)
|
143
|
+
when 'ts', 'tstz' # :time
|
144
|
+
from = self.class.string_to_time(extracted[:from])
|
145
|
+
to = self.class.string_to_time(extracted[:to])
|
146
|
+
when 'int4', 'int8' # :integer
|
147
|
+
from = to_integer(extracted[:from]) rescue value ? 1 : 0
|
148
|
+
from -= 1 if extracted[:exclude_start]
|
149
|
+
to = to_integer(extracted[:to]) rescue value ? 1 : 0
|
150
|
+
else
|
151
|
+
return value
|
152
|
+
end
|
153
|
+
|
154
|
+
::Range.new(from, to, extracted[:exclude_end])
|
155
|
+
else super
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end if AR4_COMPAT
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
def extract_limit(sql_type)
|
163
|
+
case sql_type
|
164
|
+
when /^bigint/i; 8
|
165
|
+
when /^smallint/i; 2
|
166
|
+
when /^timestamp/i; nil
|
167
|
+
else super
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# Extracts the scale from PostgreSQL-specific data types.
|
172
|
+
def extract_scale(sql_type)
|
173
|
+
# Money type has a fixed scale of 2.
|
174
|
+
sql_type =~ /^money/ ? 2 : super
|
175
|
+
end
|
176
|
+
|
177
|
+
# Extracts the precision from PostgreSQL-specific data types.
|
178
|
+
def extract_precision(sql_type)
|
179
|
+
if sql_type == 'money'
|
180
|
+
self.class.money_precision
|
181
|
+
elsif sql_type =~ /timestamp/i
|
182
|
+
$1.to_i if sql_type =~ /\((\d+)\)/
|
183
|
+
else
|
184
|
+
super
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# Maps PostgreSQL-specific data types to logical Rails types.
|
189
|
+
def simplified_type(field_type)
|
190
|
+
case field_type
|
191
|
+
# Numeric and monetary types
|
192
|
+
when /^(?:real|double precision)$/ then :float
|
193
|
+
# Monetary types
|
194
|
+
when 'money' then :decimal
|
195
|
+
# Character types
|
196
|
+
when /^(?:character varying|bpchar)(?:\(\d+\))?$/ then :string
|
197
|
+
# Binary data types
|
198
|
+
when 'bytea' then :binary
|
199
|
+
# Date/time types
|
200
|
+
when /^timestamp with(?:out)? time zone$/ then :datetime
|
201
|
+
when 'interval' then :string
|
202
|
+
# Geometric types
|
203
|
+
when /^(?:point|line|lseg|box|"?path"?|polygon|circle)$/ then :string
|
204
|
+
# Network address types
|
205
|
+
when /^(?:cidr|inet|macaddr)$/ then :string
|
206
|
+
# Bit strings
|
207
|
+
when /^bit(?: varying)?(?:\(\d+\))?$/ then :string
|
208
|
+
# XML type
|
209
|
+
when 'xml' then :xml
|
210
|
+
# tsvector type
|
211
|
+
when 'tsvector' then :tsvector
|
212
|
+
# Arrays
|
213
|
+
when /^\D+\[\]$/ then :string
|
214
|
+
# Object identifier types
|
215
|
+
when 'oid' then :integer
|
216
|
+
# UUID type
|
217
|
+
when 'uuid' then :string
|
218
|
+
# Small and big integer types
|
219
|
+
when /^(?:small|big)int$/ then :integer
|
220
|
+
# AR-JDBC added :
|
221
|
+
when 'bool' then :boolean
|
222
|
+
when 'char' then :string
|
223
|
+
when 'serial' then :integer
|
224
|
+
# Pass through all types that are not specific to PostgreSQL.
|
225
|
+
else
|
226
|
+
super
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
# @private
|
231
|
+
def simplified_type(field_type)
|
232
|
+
case field_type
|
233
|
+
# Numeric and monetary types
|
234
|
+
when /^(?:real|double precision)$/ then :float
|
235
|
+
# Monetary types
|
236
|
+
when 'money' then :decimal
|
237
|
+
when 'hstore' then :hstore
|
238
|
+
when 'ltree' then :ltree
|
239
|
+
# Network address types
|
240
|
+
when 'inet' then :inet
|
241
|
+
when 'cidr' then :cidr
|
242
|
+
when 'macaddr' then :macaddr
|
243
|
+
# Character types
|
244
|
+
when /^(?:character varying|bpchar)(?:\(\d+\))?$/ then :string
|
245
|
+
# Binary data types
|
246
|
+
when 'bytea' then :binary
|
247
|
+
# Date/time types
|
248
|
+
when /^timestamp with(?:out)? time zone$/ then :datetime
|
249
|
+
when /^interval(?:|\(\d+\))$/ then :string
|
250
|
+
# Geometric types
|
251
|
+
when /^(?:point|line|lseg|box|"?path"?|polygon|circle)$/ then :string
|
252
|
+
# Bit strings
|
253
|
+
when /^bit(?: varying)?(?:\(\d+\))?$/ then :string
|
254
|
+
# XML type
|
255
|
+
when 'xml' then :xml
|
256
|
+
# tsvector type
|
257
|
+
when 'tsvector' then :tsvector
|
258
|
+
# Arrays
|
259
|
+
when /^\D+\[\]$/ then :string
|
260
|
+
# Object identifier types
|
261
|
+
when 'oid' then :integer
|
262
|
+
# UUID type
|
263
|
+
when 'uuid' then :uuid
|
264
|
+
# JSON type
|
265
|
+
when 'json' then :json
|
266
|
+
# Small and big integer types
|
267
|
+
when /^(?:small|big)int$/ then :integer
|
268
|
+
when /(num|date|tstz|ts|int4|int8)range$/
|
269
|
+
field_type.to_sym
|
270
|
+
# AR-JDBC added :
|
271
|
+
when 'bool' then :boolean
|
272
|
+
when 'char' then :string
|
273
|
+
when 'serial' then :integer
|
274
|
+
# Pass through all types that are not specific to PostgreSQL.
|
275
|
+
else
|
276
|
+
super
|
277
|
+
end
|
278
|
+
end if AR4_COMPAT
|
279
|
+
|
280
|
+
# OID Type::Range helpers :
|
281
|
+
|
282
|
+
def extract_bounds(value)
|
283
|
+
f, t = value[1..-2].split(',')
|
284
|
+
{
|
285
|
+
:from => (value[1] == ',' || f == '-infinity') ? infinity(:negative => true) : f,
|
286
|
+
:to => (value[-2] == ',' || t == 'infinity') ? infinity : t,
|
287
|
+
:exclude_start => (value[0] == '('), :exclude_end => (value[-1] == ')')
|
288
|
+
}
|
289
|
+
end if AR4_COMPAT
|
290
|
+
|
291
|
+
def infinity(options = {})
|
292
|
+
::Float::INFINITY * (options[:negative] ? -1 : 1)
|
293
|
+
end if AR4_COMPAT
|
294
|
+
|
295
|
+
def to_integer(value)
|
296
|
+
(value.respond_to?(:infinite?) && value.infinite?) ? value : value.to_i
|
297
|
+
end if AR4_COMPAT
|
298
|
+
|
299
|
+
# @note Based on *active_record/connection_adapters/postgresql/cast.rb* (4.0).
|
300
|
+
module Cast
|
301
|
+
|
302
|
+
def point_to_string(point)
|
303
|
+
"(#{point[0]},#{point[1]})"
|
304
|
+
end
|
305
|
+
|
306
|
+
def string_to_point(string)
|
307
|
+
if string[0] == '(' && string[-1] == ')'
|
308
|
+
string = string[1...-1]
|
309
|
+
end
|
310
|
+
string.split(',').map { |v| Float(v) }
|
311
|
+
end
|
312
|
+
|
313
|
+
def string_to_time(string)
|
314
|
+
return string unless String === string
|
315
|
+
|
316
|
+
case string
|
317
|
+
when 'infinity' then 1.0 / 0.0
|
318
|
+
when '-infinity' then -1.0 / 0.0
|
319
|
+
when / BC$/
|
320
|
+
super("-" + string.sub(/ BC$/, ""))
|
321
|
+
else
|
322
|
+
super
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
def string_to_bit(value)
|
327
|
+
case value
|
328
|
+
when /^[01]*$/ then value # Bit-string notation
|
329
|
+
when /^[0-9A-F]*$/i then value.hex.to_s(2) # Hexadecimal notation
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
def string_to_bit(value)
|
334
|
+
case value
|
335
|
+
when /^0x/i
|
336
|
+
value[2..-1].hex.to_s(2) # Hexadecimal notation
|
337
|
+
else
|
338
|
+
value # Bit-string notation
|
339
|
+
end
|
340
|
+
end if AR4_COMPAT
|
341
|
+
|
342
|
+
def hstore_to_string(object)
|
343
|
+
if Hash === object
|
344
|
+
object.map { |k,v| "#{escape_hstore(k)}=>#{escape_hstore(v)}" }.join(',')
|
345
|
+
else
|
346
|
+
object
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
def string_to_hstore(string)
|
351
|
+
if string.nil?
|
352
|
+
nil
|
353
|
+
elsif String === string
|
354
|
+
Hash[string.scan(HstorePair).map { |k,v|
|
355
|
+
v = v.upcase == 'NULL' ? nil : v.gsub(/^"(.*)"$/,'\1').gsub(/\\(.)/, '\1')
|
356
|
+
k = k.gsub(/^"(.*)"$/,'\1').gsub(/\\(.)/, '\1')
|
357
|
+
[k,v]
|
358
|
+
}]
|
359
|
+
else
|
360
|
+
string
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
def json_to_string(object)
|
365
|
+
if Hash === object
|
366
|
+
ActiveSupport::JSON.encode(object)
|
367
|
+
else
|
368
|
+
object
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
def array_to_string(value, column, adapter, should_be_quoted = false)
|
373
|
+
casted_values = value.map do |val|
|
374
|
+
if String === val
|
375
|
+
if val == "NULL"
|
376
|
+
"\"#{val}\""
|
377
|
+
else
|
378
|
+
quote_and_escape(adapter.type_cast(val, column, true))
|
379
|
+
end
|
380
|
+
else
|
381
|
+
adapter.type_cast(val, column, true)
|
382
|
+
end
|
383
|
+
end
|
384
|
+
"{#{casted_values.join(',')}}"
|
385
|
+
end
|
386
|
+
|
387
|
+
def range_to_string(object)
|
388
|
+
from = object.begin.respond_to?(:infinite?) && object.begin.infinite? ? '' : object.begin
|
389
|
+
to = object.end.respond_to?(:infinite?) && object.end.infinite? ? '' : object.end
|
390
|
+
"[#{from},#{to}#{object.exclude_end? ? ')' : ']'}"
|
391
|
+
end
|
392
|
+
|
393
|
+
def string_to_json(string)
|
394
|
+
if String === string
|
395
|
+
ActiveSupport::JSON.decode(string)
|
396
|
+
else
|
397
|
+
string
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
def string_to_cidr(string)
|
402
|
+
if string.nil?
|
403
|
+
nil
|
404
|
+
elsif String === string
|
405
|
+
IPAddr.new(string)
|
406
|
+
else
|
407
|
+
string
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
def cidr_to_string(object)
|
412
|
+
if IPAddr === object
|
413
|
+
"#{object.to_s}/#{object.instance_variable_get(:@mask_addr).to_s(2).count('1')}"
|
414
|
+
else
|
415
|
+
object
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
# NOTE: not used - we get "parsed" array value from connection
|
420
|
+
#def string_to_array(string, oid)
|
421
|
+
# parse_pg_array(string).map { |val| oid.type_cast val }
|
422
|
+
#end
|
423
|
+
|
424
|
+
private
|
425
|
+
|
426
|
+
# @private
|
427
|
+
HstorePair = begin
|
428
|
+
quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"/
|
429
|
+
unquoted_string = /(?:\\.|[^\s,])[^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*/
|
430
|
+
/(#{quoted_string}|#{unquoted_string})\s*=>\s*(#{quoted_string}|#{unquoted_string})/
|
431
|
+
end
|
432
|
+
|
433
|
+
def escape_hstore(value)
|
434
|
+
if value.nil?
|
435
|
+
'NULL'
|
436
|
+
else
|
437
|
+
if value == ""
|
438
|
+
'""'
|
439
|
+
else
|
440
|
+
'"%s"' % value.to_s.gsub(/(["\\])/, '\\\\\1')
|
441
|
+
end
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
def quote_and_escape(value)
|
446
|
+
case value
|
447
|
+
when "NULL"
|
448
|
+
value
|
449
|
+
else
|
450
|
+
"\"#{value.gsub(/(["\\])/, '\\\\\1')}\""
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
end
|
455
|
+
|
456
|
+
end
|
457
|
+
end
|
458
|
+
end
|