tina4ruby 3.13.16 → 3.13.17
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.
- checksums.yaml +4 -4
- data/lib/tina4/drivers/postgres_driver.rb +51 -0
- data/lib/tina4/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 198d9905bf51e280f45f2bba90aac40fd64ea1bdf0c0f0b29e9a80d5e95020c9
|
|
4
|
+
data.tar.gz: 74c01ef1ac870c47aebf57e686a9b3bd7efa46f5c56c1d78df4c378102ee39f2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 03a840227106a3e2c12a78bde6c5d62ff8e4eb3041bc443fe73cad5e5d6d1dbd366ffa5458d34faeffe8448ad8fb19ce9bd74c821a4d3ec436ab80aa984b58fc
|
|
7
|
+
data.tar.gz: deefa98487ff855b8ad66beaa13b2e70f2b9f71677c0e317b52fc9153f43782a40723dc5519e814a2d65a29685fae18647f0bc84c124763aa8e5e7dcbddd07ca
|
|
@@ -25,6 +25,8 @@ module Tina4
|
|
|
25
25
|
url = uri.to_s
|
|
26
26
|
end
|
|
27
27
|
@connection = PG.connect(url)
|
|
28
|
+
apply_result_type_map(@connection)
|
|
29
|
+
@connection
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
def close
|
|
@@ -151,6 +153,55 @@ module Tina4
|
|
|
151
153
|
|
|
152
154
|
private
|
|
153
155
|
|
|
156
|
+
# Decode result columns to native Ruby types (parity with SQLite, and
|
|
157
|
+
# with Python psycopg2 / Node node-postgres which both return native
|
|
158
|
+
# types). Without this the pg gem hands back EVERY column as a String —
|
|
159
|
+
# ``id: "1"``, ``active: "t"``, timestamps as strings — so an app
|
|
160
|
+
# written on SQLite silently changes behaviour on PostgreSQL.
|
|
161
|
+
#
|
|
162
|
+
# PG::BasicTypeMapForResults decodes by column OID:
|
|
163
|
+
# int2/int4/int8/serial -> Integer
|
|
164
|
+
# bool -> true / false
|
|
165
|
+
# float4/float8 -> Float
|
|
166
|
+
# numeric -> BigDecimal
|
|
167
|
+
# timestamp/timestamptz -> Time
|
|
168
|
+
# date -> Date
|
|
169
|
+
# text/varchar -> String (unchanged)
|
|
170
|
+
#
|
|
171
|
+
# The map is set on the *connection*, so it applies uniformly to both
|
|
172
|
+
# ``exec`` and ``exec_params`` and therefore to every fetch / fetch_one /
|
|
173
|
+
# columns path that flows through execute_query.
|
|
174
|
+
#
|
|
175
|
+
# uuid / json / jsonb / regclass have no built-in coder; left alone the
|
|
176
|
+
# map prints a noisy "no type cast defined" warning to stderr and falls
|
|
177
|
+
# back to a raw string anyway. We register explicit text decoders for them
|
|
178
|
+
# so they stay plain strings (the documented behaviour) without the
|
|
179
|
+
# warning — regclass matters because table_exists? selects to_regclass().
|
|
180
|
+
# bytea is already handled by the map as an ASCII-8BIT binary string,
|
|
181
|
+
# which is what decode_blobs expects.
|
|
182
|
+
def apply_result_type_map(conn)
|
|
183
|
+
type_map = PG::BasicTypeMapForResults.new(conn)
|
|
184
|
+
register_text_decoders(conn, type_map, %w[uuid json jsonb regclass])
|
|
185
|
+
conn.type_map_for_results = type_map
|
|
186
|
+
rescue PG::Error, NameError
|
|
187
|
+
# If the type map can't be built (e.g. a minimal pg build without
|
|
188
|
+
# BasicTypeMapForResults, or a connection that can't resolve OIDs),
|
|
189
|
+
# leave results as strings rather than breaking the connection.
|
|
190
|
+
nil
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Register a plain-text decoder for each named PostgreSQL type so the
|
|
194
|
+
# result map returns it unchanged as a String instead of warning that no
|
|
195
|
+
# cast is defined. Unknown type names are skipped silently.
|
|
196
|
+
def register_text_decoders(conn, type_map, type_names)
|
|
197
|
+
type_names.each do |name|
|
|
198
|
+
oid = conn.exec_params("SELECT $1::regtype::oid", [name]).getvalue(0, 0).to_i
|
|
199
|
+
type_map.add_coder(PG::TextDecoder::String.new(oid: oid, name: name, format: 0))
|
|
200
|
+
rescue PG::Error
|
|
201
|
+
next
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
154
205
|
def convert_placeholders(sql)
|
|
155
206
|
counter = 0
|
|
156
207
|
sql.gsub("?") { counter += 1; "$#{counter}" }
|
data/lib/tina4/version.rb
CHANGED