activerecord-jdbc-adapter-ficoh 1.3.21-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 (191) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +35 -0
  3. data/.travis.yml +462 -0
  4. data/.yardopts +4 -0
  5. data/Appraisals +36 -0
  6. data/CONTRIBUTING.md +49 -0
  7. data/Gemfile +68 -0
  8. data/History.md +1191 -0
  9. data/LICENSE.txt +25 -0
  10. data/README.md +277 -0
  11. data/RUNNING_TESTS.md +88 -0
  12. data/Rakefile +298 -0
  13. data/Rakefile.jdbc +20 -0
  14. data/activerecord-jdbc-adapter.gemspec +63 -0
  15. data/lib/active_record/connection_adapters/as400_adapter.rb +2 -0
  16. data/lib/active_record/connection_adapters/db2_adapter.rb +1 -0
  17. data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
  18. data/lib/active_record/connection_adapters/firebird_adapter.rb +1 -0
  19. data/lib/active_record/connection_adapters/h2_adapter.rb +1 -0
  20. data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -0
  21. data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
  22. data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -0
  23. data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
  24. data/lib/active_record/connection_adapters/mariadb_adapter.rb +1 -0
  25. data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
  26. data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -0
  27. data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
  28. data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
  29. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
  30. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
  31. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
  32. data/lib/activerecord-jdbc-adapter.rb +1 -0
  33. data/lib/arel/visitors/compat.rb +64 -0
  34. data/lib/arel/visitors/db2.rb +137 -0
  35. data/lib/arel/visitors/derby.rb +112 -0
  36. data/lib/arel/visitors/firebird.rb +79 -0
  37. data/lib/arel/visitors/h2.rb +25 -0
  38. data/lib/arel/visitors/hsqldb.rb +32 -0
  39. data/lib/arel/visitors/postgresql_jdbc.rb +6 -0
  40. data/lib/arel/visitors/sql_server.rb +225 -0
  41. data/lib/arel/visitors/sql_server/ng42.rb +293 -0
  42. data/lib/arjdbc.rb +22 -0
  43. data/lib/arjdbc/db2.rb +4 -0
  44. data/lib/arjdbc/db2/adapter.rb +802 -0
  45. data/lib/arjdbc/db2/as400.rb +137 -0
  46. data/lib/arjdbc/db2/column.rb +177 -0
  47. data/lib/arjdbc/db2/connection_methods.rb +45 -0
  48. data/lib/arjdbc/derby.rb +3 -0
  49. data/lib/arjdbc/derby/active_record_patch.rb +13 -0
  50. data/lib/arjdbc/derby/adapter.rb +567 -0
  51. data/lib/arjdbc/derby/connection_methods.rb +16 -0
  52. data/lib/arjdbc/derby/schema_creation.rb +15 -0
  53. data/lib/arjdbc/discover.rb +104 -0
  54. data/lib/arjdbc/firebird.rb +4 -0
  55. data/lib/arjdbc/firebird/adapter.rb +468 -0
  56. data/lib/arjdbc/firebird/connection_methods.rb +20 -0
  57. data/lib/arjdbc/h2.rb +3 -0
  58. data/lib/arjdbc/h2/adapter.rb +335 -0
  59. data/lib/arjdbc/h2/connection_methods.rb +22 -0
  60. data/lib/arjdbc/hsqldb.rb +3 -0
  61. data/lib/arjdbc/hsqldb/adapter.rb +304 -0
  62. data/lib/arjdbc/hsqldb/connection_methods.rb +23 -0
  63. data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
  64. data/lib/arjdbc/hsqldb/schema_creation.rb +11 -0
  65. data/lib/arjdbc/informix.rb +5 -0
  66. data/lib/arjdbc/informix/adapter.rb +160 -0
  67. data/lib/arjdbc/informix/connection_methods.rb +9 -0
  68. data/lib/arjdbc/jdbc.rb +62 -0
  69. data/lib/arjdbc/jdbc/adapter.rb +997 -0
  70. data/lib/arjdbc/jdbc/adapter_require.rb +46 -0
  71. data/lib/arjdbc/jdbc/arel_support.rb +149 -0
  72. data/lib/arjdbc/jdbc/base_ext.rb +34 -0
  73. data/lib/arjdbc/jdbc/callbacks.rb +52 -0
  74. data/lib/arjdbc/jdbc/column.rb +83 -0
  75. data/lib/arjdbc/jdbc/connection.rb +26 -0
  76. data/lib/arjdbc/jdbc/connection_methods.rb +59 -0
  77. data/lib/arjdbc/jdbc/driver.rb +44 -0
  78. data/lib/arjdbc/jdbc/error.rb +75 -0
  79. data/lib/arjdbc/jdbc/extension.rb +69 -0
  80. data/lib/arjdbc/jdbc/java.rb +13 -0
  81. data/lib/arjdbc/jdbc/type_cast.rb +154 -0
  82. data/lib/arjdbc/jdbc/type_converter.rb +142 -0
  83. data/lib/arjdbc/mssql.rb +7 -0
  84. data/lib/arjdbc/mssql/adapter.rb +822 -0
  85. data/lib/arjdbc/mssql/column.rb +207 -0
  86. data/lib/arjdbc/mssql/connection_methods.rb +72 -0
  87. data/lib/arjdbc/mssql/explain_support.rb +99 -0
  88. data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
  89. data/lib/arjdbc/mssql/lock_methods.rb +77 -0
  90. data/lib/arjdbc/mssql/types.rb +343 -0
  91. data/lib/arjdbc/mssql/utils.rb +82 -0
  92. data/lib/arjdbc/mysql.rb +3 -0
  93. data/lib/arjdbc/mysql/adapter.rb +998 -0
  94. data/lib/arjdbc/mysql/bulk_change_table.rb +150 -0
  95. data/lib/arjdbc/mysql/column.rb +167 -0
  96. data/lib/arjdbc/mysql/connection_methods.rb +137 -0
  97. data/lib/arjdbc/mysql/explain_support.rb +82 -0
  98. data/lib/arjdbc/mysql/schema_creation.rb +58 -0
  99. data/lib/arjdbc/oracle.rb +4 -0
  100. data/lib/arjdbc/oracle/adapter.rb +968 -0
  101. data/lib/arjdbc/oracle/column.rb +136 -0
  102. data/lib/arjdbc/oracle/connection_methods.rb +21 -0
  103. data/lib/arjdbc/postgresql.rb +3 -0
  104. data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +21 -0
  105. data/lib/arjdbc/postgresql/adapter.rb +1498 -0
  106. data/lib/arjdbc/postgresql/base/array_parser.rb +95 -0
  107. data/lib/arjdbc/postgresql/base/oid.rb +412 -0
  108. data/lib/arjdbc/postgresql/base/pgconn.rb +8 -0
  109. data/lib/arjdbc/postgresql/base/schema_definitions.rb +132 -0
  110. data/lib/arjdbc/postgresql/column.rb +640 -0
  111. data/lib/arjdbc/postgresql/connection_methods.rb +44 -0
  112. data/lib/arjdbc/postgresql/explain_support.rb +53 -0
  113. data/lib/arjdbc/postgresql/oid/bytea.rb +3 -0
  114. data/lib/arjdbc/postgresql/oid_types.rb +265 -0
  115. data/lib/arjdbc/postgresql/schema_creation.rb +60 -0
  116. data/lib/arjdbc/railtie.rb +11 -0
  117. data/lib/arjdbc/sqlite3.rb +3 -0
  118. data/lib/arjdbc/sqlite3/adapter.rb +654 -0
  119. data/lib/arjdbc/sqlite3/connection_methods.rb +36 -0
  120. data/lib/arjdbc/sqlite3/explain_support.rb +29 -0
  121. data/lib/arjdbc/sybase.rb +2 -0
  122. data/lib/arjdbc/sybase/adapter.rb +47 -0
  123. data/lib/arjdbc/tasks.rb +13 -0
  124. data/lib/arjdbc/tasks/database_tasks.rb +66 -0
  125. data/lib/arjdbc/tasks/databases.rake +91 -0
  126. data/lib/arjdbc/tasks/databases3.rake +239 -0
  127. data/lib/arjdbc/tasks/databases4.rake +39 -0
  128. data/lib/arjdbc/tasks/db2_database_tasks.rb +104 -0
  129. data/lib/arjdbc/tasks/derby_database_tasks.rb +95 -0
  130. data/lib/arjdbc/tasks/h2_database_tasks.rb +31 -0
  131. data/lib/arjdbc/tasks/hsqldb_database_tasks.rb +70 -0
  132. data/lib/arjdbc/tasks/jdbc_database_tasks.rb +169 -0
  133. data/lib/arjdbc/tasks/mssql_database_tasks.rb +46 -0
  134. data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +297 -0
  135. data/lib/arjdbc/tasks/oracle_database_tasks.rb +65 -0
  136. data/lib/arjdbc/util/quoted_cache.rb +60 -0
  137. data/lib/arjdbc/util/serialized_attributes.rb +98 -0
  138. data/lib/arjdbc/util/table_copier.rb +108 -0
  139. data/lib/arjdbc/version.rb +8 -0
  140. data/lib/generators/jdbc/USAGE +9 -0
  141. data/lib/generators/jdbc/jdbc_generator.rb +17 -0
  142. data/pom.xml +285 -0
  143. data/rails_generators/jdbc_generator.rb +15 -0
  144. data/rails_generators/templates/config/initializers/jdbc.rb +10 -0
  145. data/rails_generators/templates/lib/tasks/jdbc.rake +11 -0
  146. data/rakelib/01-tomcat.rake +51 -0
  147. data/rakelib/02-test.rake +151 -0
  148. data/rakelib/bundler_ext.rb +11 -0
  149. data/rakelib/db.rake +58 -0
  150. data/rakelib/rails.rake +77 -0
  151. data/src/java/arjdbc/ArJdbcModule.java +288 -0
  152. data/src/java/arjdbc/db2/DB2Module.java +77 -0
  153. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +128 -0
  154. data/src/java/arjdbc/derby/DerbyModule.java +180 -0
  155. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +153 -0
  156. data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +190 -0
  157. data/src/java/arjdbc/h2/H2Module.java +50 -0
  158. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +86 -0
  159. data/src/java/arjdbc/hsqldb/HSQLDBModule.java +74 -0
  160. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +76 -0
  161. data/src/java/arjdbc/jdbc/AdapterJavaService.java +43 -0
  162. data/src/java/arjdbc/jdbc/Callable.java +44 -0
  163. data/src/java/arjdbc/jdbc/ConnectionFactory.java +77 -0
  164. data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +156 -0
  165. data/src/java/arjdbc/jdbc/DriverConnectionFactory.java +63 -0
  166. data/src/java/arjdbc/jdbc/DriverWrapper.java +128 -0
  167. data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +32 -0
  168. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +4541 -0
  169. data/src/java/arjdbc/jdbc/SQLBlock.java +54 -0
  170. data/src/java/arjdbc/jdbc/WithResultSet.java +37 -0
  171. data/src/java/arjdbc/mssql/MSSQLModule.java +91 -0
  172. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +193 -0
  173. data/src/java/arjdbc/mysql/MySQLModule.java +140 -0
  174. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +456 -0
  175. data/src/java/arjdbc/oracle/OracleModule.java +81 -0
  176. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +477 -0
  177. data/src/java/arjdbc/postgresql/ByteaUtils.java +171 -0
  178. data/src/java/arjdbc/postgresql/DriverImplementation.java +78 -0
  179. data/src/java/arjdbc/postgresql/PGDriverImplementation.java +535 -0
  180. data/src/java/arjdbc/postgresql/PostgreSQLModule.java +189 -0
  181. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +489 -0
  182. data/src/java/arjdbc/sqlite3/SQLite3Module.java +93 -0
  183. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +405 -0
  184. data/src/java/arjdbc/util/CallResultSet.java +826 -0
  185. data/src/java/arjdbc/util/DateTimeUtils.java +517 -0
  186. data/src/java/arjdbc/util/NumberUtils.java +50 -0
  187. data/src/java/arjdbc/util/ObjectSupport.java +65 -0
  188. data/src/java/arjdbc/util/QuotingUtils.java +139 -0
  189. data/src/java/arjdbc/util/StringCache.java +60 -0
  190. data/src/java/arjdbc/util/StringHelper.java +155 -0
  191. metadata +288 -0
@@ -0,0 +1,8 @@
1
+ module ActiveRecord::ConnectionAdapters::PostgreSQL::OID
2
+ class PGconn # emulate PGconn#unescape_bytea due #652
3
+ # NOTE: on pg gem ... PGconn = (class) PG::Connection
4
+ def self.unescape_bytea(escaped)
5
+ ArJdbc::PostgreSQL.unescape_bytea(escaped)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,132 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module PostgreSQL
4
+ class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition
5
+ attr_accessor :array
6
+ def array?; !!@array; end
7
+ end
8
+
9
+ # @private
10
+ module ColumnHelpers
11
+ def xml(*args)
12
+ options = args.extract_options!
13
+ column(args[0], 'xml', options)
14
+ end
15
+
16
+ def tsvector(*args)
17
+ options = args.extract_options!
18
+ column(args[0], 'tsvector', options)
19
+ end
20
+
21
+ def int4range(name, options = {})
22
+ column(name, 'int4range', options)
23
+ end
24
+
25
+ def int8range(name, options = {})
26
+ column(name, 'int8range', options)
27
+ end
28
+
29
+ def tsrange(name, options = {})
30
+ column(name, 'tsrange', options)
31
+ end
32
+
33
+ def tstzrange(name, options = {})
34
+ column(name, 'tstzrange', options)
35
+ end
36
+
37
+ def numrange(name, options = {})
38
+ column(name, 'numrange', options)
39
+ end
40
+
41
+ def daterange(name, options = {})
42
+ column(name, 'daterange', options)
43
+ end
44
+
45
+ def hstore(name, options = {})
46
+ column(name, 'hstore', options)
47
+ end
48
+
49
+ def ltree(name, options = {})
50
+ column(name, 'ltree', options)
51
+ end
52
+
53
+ def inet(name, options = {})
54
+ column(name, 'inet', options)
55
+ end
56
+
57
+ def cidr(name, options = {})
58
+ column(name, 'cidr', options)
59
+ end
60
+
61
+ def macaddr(name, options = {})
62
+ column(name, 'macaddr', options)
63
+ end
64
+
65
+ def uuid(name, options = {})
66
+ column(name, 'uuid', options)
67
+ end
68
+
69
+ def json(name, options = {})
70
+ column(name, 'json', options)
71
+ end
72
+
73
+ def jsonb(name, options = {})
74
+ column(name, :jsonb, options)
75
+ end
76
+
77
+ def bit(name, options)
78
+ column(name, 'bit', options)
79
+ end
80
+
81
+ def bit_varying(name, options)
82
+ column(name, 'bit varying', options)
83
+ end
84
+ end
85
+
86
+ class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
87
+ include ColumnHelpers
88
+
89
+ def primary_key(name, type = :primary_key, options = {})
90
+ return super unless type == :uuid
91
+ options[:default] = options.fetch(:default, 'uuid_generate_v4()')
92
+ options[:primary_key] = true
93
+ column name, type, options
94
+ end if ::ActiveRecord::VERSION::MAJOR > 3 # 3.2 super expects (name)
95
+
96
+ def column(name, type = nil, options = {})
97
+ super
98
+ column = self[name]
99
+ # NOTE: <= 3.1 no #new_column_definition hard-coded ColumnDef.new :
100
+ # column = self[name] || ColumnDefinition.new(@base, name, type)
101
+ # thus we simply do not support array column definitions on <= 3.1
102
+ column.array = options[:array] if column.is_a?(ColumnDefinition)
103
+ self
104
+ end
105
+
106
+ private
107
+
108
+ if ::ActiveRecord::VERSION::MAJOR > 3
109
+
110
+ def create_column_definition(name, type)
111
+ ColumnDefinition.new name, type
112
+ end
113
+
114
+ else # no #create_column_definition on 3.2
115
+
116
+ def new_column_definition(base, name, type)
117
+ definition = ColumnDefinition.new base, name, type
118
+ @columns << definition
119
+ @columns_hash[name] = definition
120
+ definition
121
+ end
122
+
123
+ end
124
+
125
+ end
126
+
127
+ class Table < ActiveRecord::ConnectionAdapters::Table
128
+ include ColumnHelpers
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,640 @@
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(ColumnMethods) } ]
7
+ end
8
+
9
+ # @private these are defined on the Adapter class since 4.2
10
+ module ColumnHelpers
11
+
12
+ def extract_limit(sql_type) # :nodoc:
13
+ case sql_type
14
+ when /^bigint/i, /^int8/i then 8
15
+ when /^smallint/i then 2
16
+ when /^timestamp/i then nil
17
+ else
18
+ super
19
+ end
20
+ end
21
+
22
+ # Extracts the value from a PostgreSQL column default definition.
23
+ def extract_value_from_default(oid, default) # :nodoc:
24
+ case default
25
+ # Quoted types
26
+ when /\A[\(B]?'(.*)'::/m
27
+ $1.gsub(/''/, "'")
28
+ # Boolean types
29
+ when 'true', 'false'
30
+ default
31
+ # Numeric types
32
+ when /\A\(?(-?\d+(\.\d*)?)\)?(::bigint)?\z/
33
+ $1
34
+ # Object identifier types
35
+ when /\A-?\d+\z/
36
+ $1
37
+ else
38
+ # Anything else is blank, some user type, or some function
39
+ # and we can't know the value of that, so return nil.
40
+ nil
41
+ end
42
+ end
43
+
44
+ def extract_default_function(default_value, default) # :nodoc:
45
+ default if ! default_value && ( %r{\w+\(.*\)} === default )
46
+ end
47
+
48
+ end
49
+
50
+ # Column behavior based on PostgreSQL adapter in Rails.
51
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn
52
+ module ColumnMethods
53
+
54
+ attr_accessor :array
55
+ alias array? array
56
+
57
+ def initialize(name, default, cast_type, sql_type = nil, null = true, default_function = nil,
58
+ oid = nil, adapter = nil) # added arguments
59
+ if sql_type.to_s[-2, 2] == '[]'
60
+ @array = true
61
+ super(name, default, cast_type, sql_type[0..-3], null)
62
+ else
63
+ @array = false
64
+ super(name, default, cast_type, sql_type, null)
65
+ end
66
+
67
+ @oid = oid # used on Java side - expects @oid on Column instances
68
+ #@adapter = adapter
69
+
70
+ @default_function = default_function
71
+ end
72
+
73
+ end if AR42
74
+
75
+ # @private (AR < 4.2 version) documented above
76
+ module ColumnMethods
77
+
78
+ def initialize(name, default, oid_type = nil, sql_type = nil, null = true,
79
+ fmod = nil, adapter = nil) # added due resolving #oid_type
80
+ if oid_type.is_a?(Integer) # the "main" if branch (on AR 4.x)
81
+ @oid = oid_type; @fmod = fmod; @adapter = adapter # see Column#oid_type
82
+ elsif oid_type.respond_to?(:type_cast) # MRI compatibility
83
+ @oid_type = oid_type; # @fmod = fmod; @adapter = adapter
84
+ else # NOTE: AR <= 3.2 : (name, default, sql_type = nil, null = true)
85
+ null, sql_type, oid_type = !! sql_type, oid_type, nil
86
+ end
87
+ if sql_type.to_s[-2, 2] == '[]' && AR40
88
+ @array = true if respond_to?(:array)
89
+ super(name, default, sql_type[0..-3], null)
90
+ else
91
+ @array = false if respond_to?(:array)
92
+ super(name, default, sql_type, null)
93
+ end
94
+
95
+ @default_function = extract_default_function(@default, default)
96
+ end
97
+
98
+ def self.included(base)
99
+ # NOTE: assumes a standalone PostgreSQLColumn class
100
+ base_meta = class << base; self end
101
+ base_meta.send :attr_accessor, :money_precision
102
+
103
+ # Loads pg_array_parser if available. String parsing can be
104
+ # performed quicker by a native extension, which will not create
105
+ # a large amount of Ruby objects that will need to be garbage
106
+ # collected. pg_array_parser has a C and Java extension
107
+ begin
108
+ require 'pg_array_parser'
109
+ base_meta.send :include, PgArrayParser
110
+ rescue LoadError
111
+ if AR42
112
+ require 'active_record/connection_adapters/postgresql/array_parser'
113
+ else
114
+ require 'arjdbc/postgresql/base/array_parser'
115
+ end
116
+ base_meta.send :include, ActiveRecord::ConnectionAdapters::PostgreSQL::ArrayParser
117
+ end if AR40
118
+
119
+ base_meta.send :include, Cast
120
+
121
+ base.send :include, ColumnHelpers
122
+ end
123
+
124
+ if AR40 && ! AR42
125
+
126
+ # @private
127
+ def oid_type
128
+ @oid_type ||= begin
129
+ raise "oid not defined" unless oid = (@oid ||= nil)
130
+ @adapter.get_oid_type(oid.to_i, @fmod.to_i, name)
131
+ end
132
+ end
133
+
134
+ # @private
135
+ def accessor; oid_type.accessor end
136
+
137
+ end
138
+
139
+ ( attr_accessor :array; def array?; array; end ) if AR40
140
+
141
+ def number?; !array && super end if AR40
142
+ def text?; !array && super end if AR40
143
+
144
+ # Extracts the value from a PostgreSQL column default definition.
145
+ #
146
+ # @override JdbcColumn#default_value
147
+ # NOTE: based on `self.extract_value_from_default(default)` code
148
+ def default_value(default)
149
+ # This is a performance optimization for Ruby 1.9.2 in development.
150
+ # If the value is nil, we return nil straight away without checking
151
+ # the regular expressions. If we check each regular expression,
152
+ # Regexp#=== will call NilClass#to_str, which will trigger
153
+ # method_missing (defined by whiny nil in ActiveSupport) which
154
+ # makes this method very very slow.
155
+ return default unless default
156
+
157
+ case default
158
+ when /\A'(.*)'::(num|date|tstz|ts|int4|int8)range\z/m
159
+ $1
160
+ # Numeric types
161
+ when /\A\(?(-?\d+(\.\d*)?\)?(::bigint)?)\z/
162
+ $1
163
+ # Character types
164
+ when /\A\(?'(.*)'::.*\b(?:character varying|bpchar|text)\z/m
165
+ $1
166
+ # Binary data types
167
+ when /\A'(.*)'::bytea\z/m
168
+ $1
169
+ # Date/time types
170
+ when /\A'(.+)'::(?:time(?:stamp)? with(?:out)? time zone|date)\z/
171
+ $1
172
+ when /\A'(.*)'::interval\z/
173
+ $1
174
+ # Boolean type
175
+ when 'true'
176
+ true
177
+ when 'false'
178
+ false
179
+ # Geometric types
180
+ when /\A'(.*)'::(?:point|line|lseg|box|"?path"?|polygon|circle)\z/
181
+ $1
182
+ # Network address types
183
+ when /\A'(.*)'::(?:cidr|inet|macaddr)\z/
184
+ $1
185
+ # Bit string types
186
+ when /\AB'(.*)'::"?bit(?: varying)?"?\z/
187
+ $1
188
+ # XML type
189
+ when /\A'(.*)'::xml\z/m
190
+ $1
191
+ # Arrays
192
+ when /\A'(.*)'::"?\D+"?\[\]\z/
193
+ $1
194
+ when /\AARRAY\[(.*)\](::\D+)?\z/
195
+ "{#{$1.gsub(/'(.*?)'::[a-z]+(,)?\s?/, '\1\2')}}"
196
+ # Hstore
197
+ when /\A'(.*)'::hstore\z/
198
+ $1
199
+ # JSON
200
+ when /\A'(.*)'::json\z/
201
+ $1
202
+ # JSONB
203
+ when /\A'(.*)'::jsonb\z/
204
+ $1
205
+ # Object identifier types
206
+ when /\A-?\d+\z/
207
+ $1
208
+ else
209
+ # Anything else is blank, some user type, or some function
210
+ # and we can't know the value of that, so return nil.
211
+ nil
212
+ end
213
+ end
214
+
215
+ # Casts value (which is a String) to an appropriate instance.
216
+ # @private
217
+ def type_cast(value) # AR < 4.0 version
218
+ return if value.nil?
219
+ return super if respond_to?(:encoded?) && encoded? # since AR-3.2
220
+
221
+ case sql_type
222
+ when 'money'
223
+ self.class.string_to_money(value)
224
+ else super
225
+ end
226
+ end
227
+
228
+ # Casts value (which is a String) to an appropriate instance.
229
+ def type_cast(value, type = false) # AR >= 4.0 version
230
+ return if value.nil?
231
+ return super(value) if encoded?
232
+
233
+ # NOTE: we do not use OID::Type
234
+ # @oid_type.type_cast value
235
+
236
+ return self.class.string_to_array(value, self) if array? && type == false
237
+
238
+ case type ||= self.type
239
+ when :hstore then self.class.string_to_hstore value
240
+ when :json then self.class.string_to_json value
241
+ when :jsonb then self.class.string_to_json value
242
+ when :cidr, :inet then self.class.string_to_cidr value
243
+ when :macaddr then value
244
+ when :tsvector then value
245
+ when :datetime, :timestamp then self.class.string_to_time value
246
+ else
247
+ if ( sql_type = self.sql_type.to_s ) == 'money'
248
+ self.class.string_to_money(value)
249
+ elsif sql_type.start_with?('point')
250
+ value.is_a?(String) ? self.class.string_to_point(value) : value
251
+ elsif sql_type.start_with?('bit') || sql_type.start_with?('varbit')
252
+ value.is_a?(String) ? self.class.string_to_bit(value) : value
253
+ elsif sql_type.end_with?('range')
254
+ return if value.nil? || value == 'empty'
255
+ return value if value.is_a?(::Range)
256
+
257
+ extracted = extract_bounds(value)
258
+
259
+ case sql_type[0...-5] # range sub-type
260
+ when 'date' # :date
261
+ from = self.class.value_to_date(extracted[:from])
262
+ from += 1.day if extracted[:exclude_start]
263
+ to = self.class.value_to_date(extracted[:to])
264
+ when 'num' # :decimal
265
+ from = ::BigDecimal.new(extracted[:from].to_s)
266
+ # FIXME: add exclude start for ::Range, same for timestamp ranges
267
+ to = ::BigDecimal.new(extracted[:to].to_s)
268
+ when 'ts', 'tstz' # :time
269
+ from = self.class.string_to_time(extracted[:from])
270
+ to = self.class.string_to_time(extracted[:to])
271
+ when 'int4', 'int8' # :integer
272
+ from = extracted[:from]
273
+ unless (from.respond_to?(:infinite?) && from.infinite?)
274
+ from = from.respond_to?(:to_i) ? from.to_i : ( value ? 1 : 0 )
275
+ end
276
+ from += 1 if extracted[:exclude_start]
277
+ to = extracted[:to]
278
+ unless (to.respond_to?(:infinite?) && to.infinite?)
279
+ to = to.respond_to?(:to_i) ? to.to_i : ( value ? 1 : 0 )
280
+ end
281
+ else
282
+ return value
283
+ end
284
+
285
+ ::Range.new(from, to, extracted[:exclude_end])
286
+ else
287
+ super(value)
288
+ end
289
+ end
290
+ end if AR40
291
+
292
+ private
293
+
294
+ # Extracts the scale from PostgreSQL-specific data types.
295
+ def extract_scale(sql_type)
296
+ # Money type has a fixed scale of 2.
297
+ sql_type =~ /^money/ ? 2 : super
298
+ end
299
+
300
+ # Extracts the precision from PostgreSQL-specific data types.
301
+ def extract_precision(sql_type)
302
+ if sql_type == 'money'
303
+ self.class.money_precision
304
+ elsif sql_type =~ /timestamp/i
305
+ $1.to_i if sql_type =~ /\((\d+)\)/
306
+ else
307
+ super
308
+ end
309
+ end
310
+
311
+ # Maps PostgreSQL-specific data types to logical Rails types.
312
+ def simplified_type(field_type)
313
+ case field_type
314
+ # Numeric and monetary types
315
+ when /^(?:real|double precision)$/ then :float
316
+ # Monetary types
317
+ when 'money' then :decimal
318
+ # Character types
319
+ when /^(?:character varying|bpchar)(?:\(\d+\))?$/ then :string
320
+ # Binary data types
321
+ when 'bytea' then :binary
322
+ # Date/time types
323
+ when /^timestamp with(?:out)? time zone$/ then :datetime
324
+ when 'interval' then :string
325
+ # Geometric types
326
+ when /^(?:point|line|lseg|box|"?path"?|polygon|circle)$/ then :string
327
+ # Network address types
328
+ when /^(?:cidr|inet|macaddr)$/ then :string
329
+ # Bit strings
330
+ when /^bit(?: varying)?(?:\(\d+\))?$/ then :string
331
+ # XML type
332
+ when 'xml' then :xml
333
+ # tsvector type
334
+ when 'tsvector' then :tsvector
335
+ # Arrays
336
+ when /^\D+\[\]$/ then :string
337
+ # Object identifier types
338
+ when 'oid' then :integer
339
+ # UUID type
340
+ when 'uuid' then :string
341
+ # Small and big integer types
342
+ when /^(?:small|big)int$/ then :integer
343
+ # AR-JDBC added :
344
+ when 'bool' then :boolean
345
+ when 'char' then :string
346
+ when 'serial' then :integer
347
+ # Pass through all types that are not specific to PostgreSQL.
348
+ else
349
+ super
350
+ end
351
+ end
352
+
353
+ # @private
354
+ def simplified_type(field_type)
355
+ case field_type
356
+ # Numeric and monetary types
357
+ when /^(?:real|double precision)$/ then :float
358
+ # Monetary types
359
+ when 'money' then :decimal
360
+ when 'hstore' then :hstore
361
+ when 'ltree' then :ltree
362
+ # Network address types
363
+ when 'inet' then :inet
364
+ when 'cidr' then :cidr
365
+ when 'macaddr' then :macaddr
366
+ # Character types
367
+ when /^(?:character varying|bpchar)(?:\(\d+\))?$/ then :string
368
+ # Binary data types
369
+ when 'bytea' then :binary
370
+ # Date/time types
371
+ when /^timestamp with(?:out)? time zone$/ then :datetime
372
+ when /^interval(?:|\(\d+\))$/ then :string
373
+ # Geometric types
374
+ when /^(?:point|line|lseg|box|"?path"?|polygon|circle)$/ then :string
375
+ # Bit strings
376
+ when /^bit(?: varying)?(?:\(\d+\))?$/ then :string
377
+ # XML type
378
+ when 'xml' then :xml
379
+ # tsvector type
380
+ when 'tsvector' then :tsvector
381
+ # Arrays
382
+ when /^\D+\[\]$/ then :string
383
+ # Object identifier types
384
+ when 'oid' then :integer
385
+ # UUID type
386
+ when 'uuid' then :uuid
387
+ # JSON type
388
+ when 'json' then :json
389
+ when 'jsonb' then :jsonb
390
+ # Small and big integer types
391
+ when /^(?:small|big)int$/ then :integer
392
+ when /(num|date|tstz|ts|int4|int8)range$/
393
+ field_type.to_sym
394
+ # AR-JDBC added :
395
+ when 'bool' then :boolean
396
+ when 'char' then :string
397
+ when 'serial' then :integer
398
+ # Pass through all types that are not specific to PostgreSQL.
399
+ else
400
+ super
401
+ end
402
+ end if AR40
403
+
404
+ # OID Type::Range helpers :
405
+
406
+ def extract_bounds(value)
407
+ f, t = value[1..-2].split(',')
408
+ {
409
+ :from => (value[1] == ',' || f == '-infinity') ? infinity(:negative => true) : f,
410
+ :to => (value[-2] == ',' || t == 'infinity') ? infinity : t,
411
+ :exclude_start => (value[0] == '('), :exclude_end => (value[-1] == ')')
412
+ }
413
+ end if AR40
414
+
415
+ def infinity(options = {})
416
+ ::Float::INFINITY * (options[:negative] ? -1 : 1)
417
+ end if AR40
418
+
419
+ private
420
+
421
+ # TODO marshaling worked in 1.3.7 ,,, got broken in 1.3.8 (due @adapter)
422
+ # but the fix introduced in 1.3.10 causes backwards (1.3) incompatibility
423
+ # ... for now should be fine - there's likely more refactoring to happen!
424
+
425
+ def marshal_dump
426
+ # NOTE: disabled oid_type ... due range warnings (maybe they're fine) :
427
+ # unknown OID 3904: failed to recognize type of 'int4_range'. It will be treated as String.
428
+ #oid_type if respond_to?(:oid_type)
429
+ @adapter = nil
430
+ instance_variables.map { |var| [ var, instance_variable_get(var) ] }
431
+ end
432
+
433
+ def marshal_load(data)
434
+ data.each { |pair| instance_variable_set( pair[0], pair[1] ) }
435
+ end
436
+
437
+ # @note Based on *active_record/connection_adapters/postgresql/cast.rb* (4.0).
438
+ module Cast
439
+
440
+ def string_to_money(string)
441
+ return string unless String === string
442
+
443
+ # Because money output is formatted according to the locale, there
444
+ # are two cases to consider (note the decimal separators) :
445
+ # (1) $12,345,678.12
446
+ # (2) $12.345.678,12
447
+ # Negative values are represented as follows:
448
+ # (3) -$2.55
449
+ # (4) ($2.55)
450
+ string = string.sub(/^\((.+)\)$/, '-\1') # (4)
451
+ case string
452
+ when /^-?\D+[\d,]+\.\d{2}$/ # (1)
453
+ string.gsub!(/[^-\d.]/, '')
454
+ when /^-?\D+[\d.]+,\d{2}$/ # (2)
455
+ string.gsub!(/[^-\d,]/, '')
456
+ string.sub!(/,/, '.')
457
+ end
458
+ value_to_decimal string
459
+ end
460
+
461
+ def point_to_string(point)
462
+ "(#{point[0]},#{point[1]})"
463
+ end
464
+
465
+ def string_to_point(string)
466
+ if string[0] == '(' && string[-1] == ')'
467
+ string = string[1...-1]
468
+ end
469
+ string.split(',').map { |v| Float(v) }
470
+ end
471
+
472
+ def string_to_time(string)
473
+ return string unless String === string
474
+
475
+ case string
476
+ when 'infinity' then 1.0 / 0.0
477
+ when '-infinity' then -1.0 / 0.0
478
+ when / BC$/
479
+ super("-#{string.sub(/ BC$/, "")}")
480
+ else
481
+ super
482
+ end
483
+ end
484
+
485
+ def string_to_bit(value)
486
+ case value
487
+ when /^[01]*$/ then value # Bit-string notation
488
+ when /^[0-9A-F]*$/i then value.hex.to_s(2) # Hexadecimal notation
489
+ end
490
+ end
491
+
492
+ def string_to_bit(value)
493
+ case value
494
+ when /^0x/i
495
+ value[2..-1].hex.to_s(2) # Hexadecimal notation
496
+ else
497
+ value # Bit-string notation
498
+ end
499
+ end if AR40
500
+
501
+ def hstore_to_string(object, array_member = false)
502
+ if Hash === object
503
+ string = object.map { |k, v| "#{escape_hstore(k)}=>#{escape_hstore(v)}" }.join(',')
504
+ string = escape_hstore(string) if array_member
505
+ string
506
+ else
507
+ object
508
+ end
509
+ end
510
+
511
+ def string_to_hstore(string)
512
+ if string.nil?
513
+ nil
514
+ elsif String === string
515
+ Hash[string.scan(HstorePair).map { |k, v|
516
+ v = v.upcase == 'NULL' ? nil : v.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1')
517
+ k = k.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1')
518
+ [k, v]
519
+ }]
520
+ else
521
+ string
522
+ end
523
+ end
524
+
525
+ def json_to_string(object)
526
+ if Hash === object || Array === object
527
+ ActiveSupport::JSON.encode(object)
528
+ else
529
+ object
530
+ end
531
+ end
532
+
533
+ def array_to_string(value, column, adapter)
534
+ casted_values = value.map do |val|
535
+ if String === val
536
+ if val == "NULL"
537
+ "\"#{val}\""
538
+ else
539
+ quote_and_escape(adapter.type_cast(val, column, true))
540
+ end
541
+ else
542
+ adapter.type_cast(val, column, true)
543
+ end
544
+ end
545
+ "{#{casted_values.join(',')}}"
546
+ end
547
+
548
+ def range_to_string(object)
549
+ from = object.begin.respond_to?(:infinite?) && object.begin.infinite? ? '' : object.begin
550
+ to = object.end.respond_to?(:infinite?) && object.end.infinite? ? '' : object.end
551
+ "[#{from},#{to}#{object.exclude_end? ? ')' : ']'}"
552
+ end
553
+
554
+ def string_to_json(string)
555
+ if String === string
556
+ ActiveSupport::JSON.decode(string)
557
+ else
558
+ string
559
+ end
560
+ end
561
+
562
+ def string_to_cidr(string)
563
+ if string.nil?
564
+ nil
565
+ elsif String === string
566
+ begin
567
+ IPAddr.new(string)
568
+ rescue ArgumentError
569
+ nil
570
+ end
571
+ else
572
+ string
573
+ end
574
+ end
575
+
576
+ def cidr_to_string(object)
577
+ if IPAddr === object
578
+ "#{object.to_s}/#{object.instance_variable_get(:@mask_addr).to_s(2).count('1')}"
579
+ else
580
+ object
581
+ end
582
+ end
583
+
584
+ # @note Only used for default values - we get a "parsed" array from JDBC.
585
+ def string_to_array(string, column_or_oid)
586
+ return string unless String === string
587
+ parse_pg_array(string).map { |val| type_cast_array(column_or_oid, val) }
588
+ end
589
+
590
+ private
591
+
592
+ # @private
593
+ HstorePair = begin
594
+ quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"/
595
+ unquoted_string = /(?:\\.|[^\s,])[^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*/
596
+ /(#{quoted_string}|#{unquoted_string})\s*=>\s*(#{quoted_string}|#{unquoted_string})/
597
+ end
598
+
599
+ def escape_hstore(value)
600
+ if value.nil?
601
+ 'NULL'
602
+ else
603
+ if value == ""
604
+ '""'
605
+ else
606
+ '"%s"' % value.to_s.gsub(/(["\\])/, '\\\\\1')
607
+ end
608
+ end
609
+ end
610
+
611
+ ARRAY_ESCAPE = "\\" * 2 * 2 # escape the backslash twice for PG arrays
612
+
613
+ def quote_and_escape(value)
614
+ case value
615
+ when "NULL", Numeric
616
+ value
617
+ else
618
+ value = value.gsub(/\\/, ARRAY_ESCAPE)
619
+ value.gsub!(/"/,"\\\"")
620
+ "\"#{value}\""
621
+ end
622
+ end
623
+
624
+ def type_cast_array(oid, value)
625
+ if ::Array === value
626
+ value.map { |item| type_cast_array(oid, item) }
627
+ else
628
+ if oid.is_a?(ColumnMethods)
629
+ oid.type_cast value, oid.type # column.type
630
+ else
631
+ oid.type_cast value
632
+ end
633
+ end
634
+ end
635
+
636
+ end
637
+
638
+ end unless AR42
639
+ end
640
+ end