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,95 @@
1
+ # based on active_record/connection_adapters/postgresql/array_parser.rb
2
+ # until it's some day shareable with Rails ... this is not public API !
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module PostgreSQL
6
+ module ArrayParser
7
+
8
+ DOUBLE_QUOTE = '"'
9
+ BACKSLASH = "\\"
10
+ COMMA = ','
11
+ BRACKET_OPEN = '{'
12
+ BRACKET_CLOSE = '}'
13
+
14
+ def parse_pg_array(string)
15
+ local_index = 0
16
+ array = []
17
+ while(local_index < string.length)
18
+ case string[local_index]
19
+ when BRACKET_OPEN
20
+ local_index,array = parse_array_contents(array, string, local_index + 1)
21
+ when BRACKET_CLOSE
22
+ return array
23
+ end
24
+ local_index += 1
25
+ end
26
+
27
+ array
28
+ end
29
+
30
+ private
31
+
32
+ def parse_array_contents(array, string, index)
33
+ is_escaping = false
34
+ is_quoted = false
35
+ was_quoted = false
36
+ current_item = ''
37
+
38
+ local_index = index
39
+ while local_index
40
+ token = string[local_index]
41
+ if is_escaping
42
+ current_item << token
43
+ is_escaping = false
44
+ else
45
+ if is_quoted
46
+ case token
47
+ when DOUBLE_QUOTE
48
+ is_quoted = false
49
+ was_quoted = true
50
+ when BACKSLASH
51
+ is_escaping = true
52
+ else
53
+ current_item << token
54
+ end
55
+ else
56
+ case token
57
+ when BACKSLASH
58
+ is_escaping = true
59
+ when COMMA
60
+ add_item_to_array(array, current_item, was_quoted)
61
+ current_item = ''
62
+ was_quoted = false
63
+ when DOUBLE_QUOTE
64
+ is_quoted = true
65
+ when BRACKET_OPEN
66
+ internal_items = []
67
+ local_index,internal_items = parse_array_contents(internal_items, string, local_index + 1)
68
+ array.push(internal_items)
69
+ when BRACKET_CLOSE
70
+ add_item_to_array(array, current_item, was_quoted)
71
+ return local_index,array
72
+ else
73
+ current_item << token
74
+ end
75
+ end
76
+ end
77
+
78
+ local_index += 1
79
+ end
80
+ return local_index,array
81
+ end
82
+
83
+ def add_item_to_array(array, current_item, quoted)
84
+ return if !quoted && current_item.length == 0
85
+
86
+ if !quoted && current_item == 'NULL'
87
+ array.push nil
88
+ else
89
+ array.push current_item
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,412 @@
1
+ # copied from active_record/connection_adapters/postgresql/oid.rb
2
+ # until it's some day shareable with Rails ... this is not public API !
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module PostgreSQL
6
+ module OID
7
+ class Type
8
+ def type; end
9
+ end
10
+
11
+ class Identity < Type
12
+ def type_cast(value)
13
+ value
14
+ end
15
+ end
16
+
17
+ class Bit < Type
18
+ def type_cast(value)
19
+ if String === value
20
+ ConnectionAdapters::PostgreSQLColumn.string_to_bit value
21
+ else
22
+ value
23
+ end
24
+ end
25
+ end
26
+
27
+ class Bytea < Type
28
+ def type_cast(value)
29
+ return if value.nil?
30
+ PGconn.unescape_bytea value
31
+ end
32
+ end
33
+
34
+ class Money < Type
35
+ def type_cast(value)
36
+ return if value.nil?
37
+ return value unless String === value
38
+
39
+ # Because money output is formatted according to the locale, there are two
40
+ # cases to consider (note the decimal separators):
41
+ # (1) $12,345,678.12
42
+ # (2) $12.345.678,12
43
+ # Negative values are represented as follows:
44
+ # (3) -$2.55
45
+ # (4) ($2.55)
46
+
47
+ value.sub!(/^\((.+)\)$/, '-\1') # (4)
48
+ case value
49
+ when /^-?\D+[\d,]+\.\d{2}$/ # (1)
50
+ value.gsub!(/[^-\d.]/, '')
51
+ when /^-?\D+[\d.]+,\d{2}$/ # (2)
52
+ value.gsub!(/[^-\d,]/, '').sub!(/,/, '.')
53
+ end
54
+
55
+ ConnectionAdapters::Column.value_to_decimal value
56
+ end
57
+ end
58
+
59
+ class Vector < Type
60
+ attr_reader :delim, :subtype
61
+
62
+ # +delim+ corresponds to the `typdelim` column in the pg_types
63
+ # table. +subtype+ is derived from the `typelem` column in the
64
+ # pg_types table.
65
+ def initialize(delim, subtype)
66
+ @delim = delim
67
+ @subtype = subtype
68
+ end
69
+
70
+ # FIXME: this should probably split on +delim+ and use +subtype+
71
+ # to cast the values. Unfortunately, the current Rails behavior
72
+ # is to just return the string.
73
+ def type_cast(value)
74
+ value
75
+ end
76
+ end
77
+
78
+ class Point < Type
79
+ def type_cast(value)
80
+ if ::String === value
81
+ ConnectionAdapters::PostgreSQLColumn.string_to_point value
82
+ else
83
+ value
84
+ end
85
+ end
86
+ end
87
+
88
+ class Array < Type
89
+ attr_reader :subtype
90
+ def initialize(subtype)
91
+ @subtype = subtype
92
+ end
93
+
94
+ def type_cast(value)
95
+ if ::String === value
96
+ ConnectionAdapters::PostgreSQLColumn.string_to_array value, @subtype
97
+ else
98
+ value
99
+ end
100
+ end
101
+ end
102
+
103
+ class Range < Type
104
+ attr_reader :subtype
105
+ def initialize(subtype)
106
+ @subtype = subtype
107
+ end
108
+
109
+ def extract_bounds(value)
110
+ from, to = value[1..-2].split(',')
111
+ {
112
+ from: (value[1] == ',' || from == '-infinity') ? infinity(:negative => true) : from,
113
+ to: (value[-2] == ',' || to == 'infinity') ? infinity : to,
114
+ exclude_start: (value[0] == '('),
115
+ exclude_end: (value[-1] == ')')
116
+ }
117
+ end
118
+
119
+ def infinity(options = {})
120
+ ::Float::INFINITY * (options[:negative] ? -1 : 1)
121
+ end
122
+
123
+ def infinity?(value)
124
+ value.respond_to?(:infinite?) && value.infinite?
125
+ end
126
+
127
+ def to_integer(value)
128
+ infinity?(value) ? value : value.to_i
129
+ end
130
+
131
+ def type_cast(value)
132
+ return if value.nil? || value == 'empty'
133
+ return value if value.is_a?(::Range)
134
+
135
+ extracted = extract_bounds(value)
136
+
137
+ case @subtype
138
+ when :date
139
+ from = ConnectionAdapters::Column.value_to_date(extracted[:from])
140
+ from += 1.day if extracted[:exclude_start]
141
+ to = ConnectionAdapters::Column.value_to_date(extracted[:to])
142
+ when :decimal
143
+ from = BigDecimal.new(extracted[:from].to_s)
144
+ # FIXME: add exclude start for ::Range, same for timestamp ranges
145
+ to = BigDecimal.new(extracted[:to].to_s)
146
+ when :time
147
+ from = ConnectionAdapters::Column.string_to_time(extracted[:from])
148
+ to = ConnectionAdapters::Column.string_to_time(extracted[:to])
149
+ when :integer
150
+ from = to_integer(extracted[:from]) rescue value ? 1 : 0
151
+ from += 1 if extracted[:exclude_start]
152
+ to = to_integer(extracted[:to]) rescue value ? 1 : 0
153
+ else
154
+ return value
155
+ end
156
+
157
+ ::Range.new(from, to, extracted[:exclude_end])
158
+ end
159
+ end
160
+
161
+ class Integer < Type
162
+ def type_cast(value)
163
+ return if value.nil?
164
+
165
+ ConnectionAdapters::Column.value_to_integer value
166
+ end
167
+ end
168
+
169
+ class Boolean < Type
170
+ def type_cast(value)
171
+ return if value.nil?
172
+
173
+ ConnectionAdapters::Column.value_to_boolean value
174
+ end
175
+ end
176
+
177
+ class Timestamp < Type
178
+ def type; :timestamp; end
179
+
180
+ def type_cast(value)
181
+ return if value.nil?
182
+
183
+ # FIXME: probably we can improve this since we know it is PG
184
+ # specific
185
+ ConnectionAdapters::PostgreSQLColumn.string_to_time value
186
+ end
187
+ end
188
+
189
+ class Date < Type
190
+ def type; :datetime; end
191
+
192
+ def type_cast(value)
193
+ return if value.nil?
194
+
195
+ # FIXME: probably we can improve this since we know it is PG
196
+ # specific
197
+ ConnectionAdapters::Column.value_to_date value
198
+ end
199
+ end
200
+
201
+ class Time < Type
202
+ def type_cast(value)
203
+ return if value.nil?
204
+
205
+ # FIXME: probably we can improve this since we know it is PG
206
+ # specific
207
+ ConnectionAdapters::Column.string_to_dummy_time value
208
+ end
209
+ end
210
+
211
+ class Float < Type
212
+ def type_cast(value)
213
+ case value
214
+ when nil; nil
215
+ when 'Infinity'; ::Float::INFINITY
216
+ when '-Infinity'; -::Float::INFINITY
217
+ when 'NaN'; ::Float::NAN
218
+ else
219
+ value.to_f
220
+ end
221
+ end
222
+ end
223
+
224
+ class Decimal < Type
225
+ def type_cast(value)
226
+ return if value.nil?
227
+
228
+ ConnectionAdapters::Column.value_to_decimal value
229
+ end
230
+ end
231
+
232
+ class Hstore < Type
233
+ def type_cast_for_write(value)
234
+ # roundtrip to ensure uniform uniform types
235
+ # TODO: This is not an efficient solution.
236
+ stringified = ConnectionAdapters::PostgreSQLColumn.hstore_to_string(value)
237
+ type_cast(stringified)
238
+ end
239
+
240
+ def type_cast(value)
241
+ return if value.nil?
242
+
243
+ ConnectionAdapters::PostgreSQLColumn.string_to_hstore value
244
+ end
245
+
246
+ def accessor
247
+ ActiveRecord::Store::StringKeyedHashAccessor
248
+ end
249
+ end
250
+
251
+ class Cidr < Type
252
+ def type_cast(value)
253
+ return if value.nil?
254
+
255
+ ConnectionAdapters::PostgreSQLColumn.string_to_cidr value
256
+ end
257
+ end
258
+
259
+ class Json < Type
260
+ def type_cast_for_write(value)
261
+ # roundtrip to ensure uniform uniform types
262
+ # TODO: This is not an efficient solution.
263
+ stringified = ConnectionAdapters::PostgreSQLColumn.json_to_string(value)
264
+ type_cast(stringified)
265
+ end
266
+
267
+ def type_cast(value)
268
+ return if value.nil?
269
+
270
+ ConnectionAdapters::PostgreSQLColumn.string_to_json value
271
+ end
272
+
273
+ def accessor
274
+ ActiveRecord::Store::StringKeyedHashAccessor
275
+ end
276
+ end
277
+
278
+ class Jsonb < Type
279
+ def type_cast_for_write(value)
280
+ # roundtrip to ensure uniform uniform types
281
+ # TODO: This is not an efficient solution.
282
+ stringified = ConnectionAdapters::PostgreSQLColumn.json_to_string(value)
283
+ type_cast(stringified)
284
+ end
285
+
286
+ def type_cast(value)
287
+ return if value.nil?
288
+
289
+ ConnectionAdapters::PostgreSQLColumn.string_to_json value
290
+ end
291
+
292
+ def accessor
293
+ ActiveRecord::Store::StringKeyedHashAccessor
294
+ end
295
+ end
296
+
297
+ class TypeMap
298
+ def initialize
299
+ @mapping = {}
300
+ end
301
+
302
+ def []=(oid, type)
303
+ @mapping[oid] = type
304
+ end
305
+
306
+ def [](oid)
307
+ @mapping[oid]
308
+ end
309
+
310
+ def clear
311
+ @mapping.clear
312
+ end
313
+
314
+ def key?(oid)
315
+ @mapping.key? oid
316
+ end
317
+
318
+ def fetch(ftype, fmod)
319
+ # The type for the numeric depends on the width of the field,
320
+ # so we'll do something special here.
321
+ #
322
+ # When dealing with decimal columns:
323
+ #
324
+ # places after decimal = fmod - 4 & 0xffff
325
+ # places before decimal = (fmod - 4) >> 16 & 0xffff
326
+ if ftype == 1700 && (fmod - 4 & 0xffff).zero?
327
+ ftype = 23
328
+ end
329
+
330
+ @mapping.fetch(ftype) { |oid| yield oid, fmod }
331
+ end
332
+ end
333
+
334
+ # When the PG adapter connects, the pg_type table is queried. The
335
+ # key of this hash maps to the `typname` column from the table.
336
+ # type_map is then dynamically built with oids as the key and type
337
+ # objects as values.
338
+ NAMES = Hash.new { |h,k| # :nodoc:
339
+ h[k] = OID::Identity.new
340
+ }
341
+
342
+ # Register an OID type named +name+ with a typecasting object in
343
+ # +type+. +name+ should correspond to the `typname` column in
344
+ # the `pg_type` table.
345
+ def self.register_type(name, type)
346
+ NAMES[name] = type
347
+ end
348
+
349
+ # Alias the +old+ type to the +new+ type.
350
+ def self.alias_type(new, old)
351
+ NAMES[new] = NAMES[old]
352
+ end
353
+
354
+ # Is +name+ a registered type?
355
+ def self.registered_type?(name)
356
+ NAMES.key? name
357
+ end
358
+
359
+ register_type 'int2', OID::Integer.new
360
+ alias_type 'int4', 'int2'
361
+ alias_type 'int8', 'int2'
362
+ alias_type 'oid', 'int2'
363
+
364
+ register_type 'daterange', OID::Range.new(:date)
365
+ register_type 'numrange', OID::Range.new(:decimal)
366
+ register_type 'tsrange', OID::Range.new(:time)
367
+ register_type 'int4range', OID::Range.new(:integer)
368
+ alias_type 'tstzrange', 'tsrange'
369
+ alias_type 'int8range', 'int4range'
370
+
371
+ register_type 'numeric', OID::Decimal.new
372
+ register_type 'text', OID::Identity.new
373
+ alias_type 'varchar', 'text'
374
+ alias_type 'char', 'text'
375
+ alias_type 'bpchar', 'text'
376
+ alias_type 'xml', 'text'
377
+
378
+ # FIXME: why are we keeping these types as strings?
379
+ alias_type 'tsvector', 'text'
380
+ alias_type 'interval', 'text'
381
+ alias_type 'macaddr', 'text'
382
+ alias_type 'uuid', 'text'
383
+
384
+ register_type 'money', OID::Money.new
385
+ register_type 'bytea', OID::Bytea.new
386
+ register_type 'bool', OID::Boolean.new
387
+ register_type 'bit', OID::Bit.new
388
+ register_type 'varbit', OID::Bit.new
389
+
390
+ register_type 'float4', OID::Float.new
391
+ alias_type 'float8', 'float4'
392
+
393
+ register_type 'timestamp', OID::Timestamp.new
394
+ register_type 'timestamptz', OID::Timestamp.new
395
+ register_type 'date', OID::Date.new
396
+ register_type 'time', OID::Time.new
397
+
398
+ register_type 'path', OID::Identity.new
399
+ register_type 'point', OID::Point.new
400
+ register_type 'polygon', OID::Identity.new
401
+ register_type 'circle', OID::Identity.new
402
+ register_type 'hstore', OID::Hstore.new
403
+ register_type 'json', OID::Json.new
404
+ register_type 'jsonb', OID::Jsonb.new
405
+ register_type 'ltree', OID::Identity.new
406
+
407
+ register_type 'cidr', OID::Cidr.new
408
+ alias_type 'inet', 'cidr'
409
+ end
410
+ end
411
+ end
412
+ end