ydbi 0.5.7 → 0.5.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +4 -0
  3. data/lib/dbi/version.rb +1 -1
  4. data/readme.md +4 -3
  5. data/test/dbi/tc_dbi.rb +1 -1
  6. metadata +7 -125
  7. data/.github/workflows/ruby.yml +0 -35
  8. data/.gitignore +0 -8
  9. data/.travis.yml +0 -15
  10. data/Gemfile +0 -5
  11. data/Rakefile +0 -10
  12. data/TODO +0 -44
  13. data/bench/bench.rb +0 -79
  14. data/build/rake_task_lib.rb +0 -186
  15. data/doc/DBD_SPEC.rdoc +0 -88
  16. data/doc/DBI_SPEC.rdoc +0 -157
  17. data/doc/homepage/contact.html +0 -62
  18. data/doc/homepage/development.html +0 -124
  19. data/doc/homepage/index.html +0 -83
  20. data/doc/homepage/ruby-dbi.css +0 -91
  21. data/lib/dbd/Mysql.rb +0 -137
  22. data/lib/dbd/ODBC.rb +0 -89
  23. data/lib/dbd/Pg.rb +0 -188
  24. data/lib/dbd/SQLite.rb +0 -97
  25. data/lib/dbd/SQLite3.rb +0 -124
  26. data/lib/dbd/mysql/database.rb +0 -405
  27. data/lib/dbd/mysql/driver.rb +0 -125
  28. data/lib/dbd/mysql/statement.rb +0 -188
  29. data/lib/dbd/odbc/database.rb +0 -128
  30. data/lib/dbd/odbc/driver.rb +0 -38
  31. data/lib/dbd/odbc/statement.rb +0 -137
  32. data/lib/dbd/pg/database.rb +0 -504
  33. data/lib/dbd/pg/exec.rb +0 -47
  34. data/lib/dbd/pg/statement.rb +0 -160
  35. data/lib/dbd/pg/tuples.rb +0 -121
  36. data/lib/dbd/pg/type.rb +0 -209
  37. data/lib/dbd/sqlite/database.rb +0 -151
  38. data/lib/dbd/sqlite/statement.rb +0 -125
  39. data/lib/dbd/sqlite3/database.rb +0 -201
  40. data/lib/dbd/sqlite3/statement.rb +0 -78
  41. data/prototypes/types2.rb +0 -237
  42. data/setup.rb +0 -1585
  43. data/test/DBD_TESTS +0 -50
  44. data/test/TESTING +0 -16
  45. data/test/dbd/general/test_database.rb +0 -206
  46. data/test/dbd/general/test_statement.rb +0 -326
  47. data/test/dbd/general/test_types.rb +0 -296
  48. data/test/dbd/mysql/base.rb +0 -26
  49. data/test/dbd/mysql/down.sql +0 -19
  50. data/test/dbd/mysql/test_blob.rb +0 -18
  51. data/test/dbd/mysql/test_new_methods.rb +0 -7
  52. data/test/dbd/mysql/test_patches.rb +0 -111
  53. data/test/dbd/mysql/up.sql +0 -28
  54. data/test/dbd/odbc/base.rb +0 -30
  55. data/test/dbd/odbc/down.sql +0 -19
  56. data/test/dbd/odbc/test_new_methods.rb +0 -12
  57. data/test/dbd/odbc/test_ping.rb +0 -10
  58. data/test/dbd/odbc/test_statement.rb +0 -44
  59. data/test/dbd/odbc/test_transactions.rb +0 -58
  60. data/test/dbd/odbc/up.sql +0 -33
  61. data/test/dbd/postgresql/base.rb +0 -31
  62. data/test/dbd/postgresql/down.sql +0 -31
  63. data/test/dbd/postgresql/test_arrays.rb +0 -179
  64. data/test/dbd/postgresql/test_async.rb +0 -121
  65. data/test/dbd/postgresql/test_blob.rb +0 -36
  66. data/test/dbd/postgresql/test_bytea.rb +0 -87
  67. data/test/dbd/postgresql/test_ping.rb +0 -10
  68. data/test/dbd/postgresql/test_timestamp.rb +0 -77
  69. data/test/dbd/postgresql/test_transactions.rb +0 -58
  70. data/test/dbd/postgresql/testdbipg.rb +0 -307
  71. data/test/dbd/postgresql/up.sql +0 -60
  72. data/test/dbd/sqlite/base.rb +0 -32
  73. data/test/dbd/sqlite/test_database.rb +0 -30
  74. data/test/dbd/sqlite/test_driver.rb +0 -68
  75. data/test/dbd/sqlite/test_statement.rb +0 -112
  76. data/test/dbd/sqlite/up.sql +0 -25
  77. data/test/dbd/sqlite3/base.rb +0 -32
  78. data/test/dbd/sqlite3/test_database.rb +0 -77
  79. data/test/dbd/sqlite3/test_driver.rb +0 -67
  80. data/test/dbd/sqlite3/test_statement.rb +0 -88
  81. data/test/dbd/sqlite3/up.sql +0 -33
  82. data/test/ts_dbd.rb +0 -131
  83. data/ydbi.gemspec +0 -23
@@ -1,137 +0,0 @@
1
- #
2
- # See DBI::BaseStatement.
3
- #
4
- class DBI::DBD::ODBC::Statement < DBI::BaseStatement
5
- def initialize(handle, statement)
6
- @statement = statement
7
- @handle = handle
8
- @params = []
9
- @arr = []
10
- end
11
-
12
- #
13
- # See DBI::BaseStatement#bind_param. This method will also raise
14
- # DBI::InterfaceError if +param+ is not a Fixnum, to prevent incorrect
15
- # binding.
16
- #
17
- def bind_param(param, value, attribs)
18
- raise DBI::InterfaceError, "only ? parameters supported" unless param.is_a? Fixnum
19
- @params[param-1] = value
20
- end
21
-
22
- def execute
23
- @handle.execute(*@params)
24
- rescue DBI::DBD::ODBC::ODBCErr => err
25
- raise DBI::DatabaseError.new(err.message)
26
- end
27
-
28
- def finish
29
- @handle.drop
30
- rescue DBI::DBD::ODBC::ODBCErr => err
31
- raise DBI::DatabaseError.new(err.message)
32
- end
33
-
34
- def cancel
35
- @handle.cancel
36
- rescue DBI::DBD::ODBC::ODBCErr => err
37
- raise DBI::DatabaseError.new(err.message)
38
- end
39
-
40
- def fetch
41
- convert_row(@handle.fetch)
42
- rescue DBI::DBD::ODBC::ODBCErr => err
43
- raise DBI::DatabaseError.new(err.message)
44
- end
45
-
46
- #
47
- # See DBI::BaseStatement#fetch_scroll.
48
- #
49
- # ODBC has a native version of this method and the constnats in the ODBC
50
- # driver themselves are supported. If you'd prefer to use DBI constants
51
- # (recommended), you can use these which map to the ODBC functionality:
52
- #
53
- # * DBI::SQL_FETCH_FIRST
54
- # * DBI::SQL_FETCH_LAST
55
- # * DBI::SQL_FETCH_NEXT
56
- # * DBI::SQL_FETCH_PRIOR
57
- # * DBI::SQL_FETCH_ABSOLUTE
58
- # * DBI::SQL_FETCH_RELATIVE
59
- #
60
- def fetch_scroll(direction, offset)
61
- direction = case direction
62
- when DBI::SQL_FETCH_FIRST then ::ODBC::SQL_FETCH_FIRST
63
- when DBI::SQL_FETCH_LAST then ::ODBC::SQL_FETCH_LAST
64
- when DBI::SQL_FETCH_NEXT then ::ODBC::SQL_FETCH_NEXT
65
- when DBI::SQL_FETCH_PRIOR then ::ODBC::SQL_FETCH_PRIOR
66
- when DBI::SQL_FETCH_ABSOLUTE then ::ODBC::SQL_FETCH_ABSOLUTE
67
- when DBI::SQL_FETCH_RELATIVE then ::ODBC::SQL_FETCH_RELATIVE
68
- else
69
- direction
70
- end
71
-
72
- convert_row(@handle.fetch_scroll(direction, offset))
73
- rescue DBI::DBD::ODBC::ODBCErr => err
74
- raise DBI::DatabaseError.new(err.message)
75
- end
76
-
77
- #
78
- # See DBI::BaseStatement#column_info. These additional attributes are also
79
- # supported:
80
- #
81
- # * table: the table this column came from, if available.
82
- # * nullable: boolean, true if NULL is accepted as a value in this column.
83
- # * searchable: FIXME DOCUMENT
84
- # * length: FIXME DOCUMENT
85
- # * unsigned: For numeric columns, whether or not the result value is signed.
86
- #
87
- def column_info
88
- info = []
89
- @handle.columns(true).each do |col|
90
- info << {
91
- 'name' => col.name,
92
- 'table' => col.table,
93
- 'nullable' => col.nullable,
94
- 'searchable' => col.searchable,
95
- 'precision' => col.precision,
96
- 'scale' => col.scale,
97
- 'sql_type' => col.type,
98
- 'type_name' => DBI::SQL_TYPE_NAMES[col.type],
99
- 'length' => col.length,
100
- 'unsigned' => col.unsigned
101
- }
102
- end
103
- info
104
- rescue DBI::DBD::ODBC::ODBCErr => err
105
- raise DBI::DatabaseError.new(err.message)
106
- end
107
-
108
- #
109
- # See DBI::BaseStatement#rows.
110
- #
111
- # For queries which DBI::SQL.query? returns true, will explicitly return 0.
112
- # Otherwise, it will return the row processed count.
113
- #
114
- def rows
115
- return 0 if DBI::SQL.query?(@statement)
116
- return @handle.nrows
117
- rescue DBI::DBD::ODBC::ODBCErr => err
118
- raise DBI::DatabaseError.new(err.message)
119
- end
120
-
121
- private # -----------------------------------
122
-
123
- # convert the ODBC datatypes to DBI datatypes
124
- def convert_row(row)
125
- return nil if row.nil?
126
- row.collect do |col|
127
- case col
128
- when nil
129
- nil
130
- when ODBC::TimeStamp
131
- DBI::Type::Timestamp.create col.year, col.month, col.day, col.hour, col.minute, col.second
132
- else
133
- col.to_s
134
- end
135
- end
136
- end
137
- end
@@ -1,504 +0,0 @@
1
- #
2
- # See DBI::BaseDatabase.
3
- #
4
- class DBI::DBD::Pg::Database < DBI::BaseDatabase
5
-
6
- # type map
7
- POSTGRESQL_to_XOPEN = {
8
- "boolean" => [DBI::SQL_CHAR, 1, nil],
9
- "character" => [DBI::SQL_CHAR, 1, nil],
10
- "char" => [DBI::SQL_CHAR, 1, nil],
11
- "real" => [DBI::SQL_REAL, 4, 6],
12
- "double precision" => [DBI::SQL_DOUBLE, 8, 15],
13
- "smallint" => [DBI::SQL_SMALLINT, 2],
14
- "integer" => [DBI::SQL_INTEGER, 4],
15
- "bigint" => [DBI::SQL_BIGINT, 8],
16
- "numeric" => [DBI::SQL_NUMERIC, nil, nil],
17
- "time with time zone" => [DBI::SQL_TIME, nil, nil],
18
- "timestamp with time zone" => [DBI::SQL_TIMESTAMP, nil, nil],
19
- "bit varying" => [DBI::SQL_BINARY, nil, nil], #huh??
20
- "character varying" => [DBI::SQL_VARCHAR, nil, nil],
21
- "bit" => [DBI::SQL_TINYINT, nil, nil],
22
- "text" => [DBI::SQL_VARCHAR, nil, nil],
23
- nil => [DBI::SQL_OTHER, nil, nil]
24
- }
25
-
26
- attr_reader :type_map
27
-
28
- #
29
- # See DBI::BaseDatabase#new. These attributes are also supported:
30
- #
31
- # * pg_async: boolean or strings 'true' or 'false'. Indicates if we're to
32
- # use PostgreSQL's asyncrohonous support. 'NonBlocking' is a synonym for
33
- # this.
34
- # * AutoCommit: 'unchained' mode in PostgreSQL. Commits after each
35
- # statement execution.
36
- # * pg_client_encoding: set the encoding for the client.
37
- # * pg_native_binding: Boolean. Indicates whether to use libpq native
38
- # binding or DBI's inline binding. Defaults to true.
39
- #
40
- def initialize(dbname, user, auth, attr)
41
- hash = DBI::Utils.parse_params(dbname)
42
-
43
- if hash['dbname'].nil? and hash['database'].nil?
44
- raise DBI::InterfaceError, "must specify database"
45
- end
46
-
47
- hash['options'] ||= nil
48
- hash['tty'] ||= ''
49
- hash['host'] ||= 'localhost'
50
- hash['port'] = hash['port'].to_i unless hash['port'].nil?
51
-
52
- @connection = PG::Connection.new(hash['host'], hash['port'], hash['options'], hash['tty'],
53
- hash['dbname'] || hash['database'], user, auth)
54
-
55
- @exec_method = :exec
56
- @in_transaction = false
57
-
58
- # set attribute defaults, and look for pg_* attrs in the DSN
59
- @attr = { 'AutoCommit' => true, 'pg_async' => false }
60
- hash.each do |key, value|
61
- @attr[key] = value if key =~ /^pg_./
62
- end
63
- @attr.merge!(attr || {})
64
- if @attr['pg_async'].is_a?(String)
65
- case @attr['pg_async'].downcase
66
- when 'true'
67
- @attr['pg_async'] = true
68
- when 'false'
69
- @attr['pg_async'] = false
70
- else
71
- raise InterfaceError, %q{'pg_async' must be 'true' or 'false'}
72
- end
73
- end
74
-
75
- @attr.each { |k,v| self[k] = v}
76
- @attr["pg_native_binding"] = true unless @attr.has_key? "pg_native_binding"
77
-
78
- load_type_map
79
-
80
- self['AutoCommit'] = true # Postgres starts in unchained mode (AutoCommit=on) by default
81
-
82
- rescue PG::Error => err
83
- raise DBI::OperationalError.new(err.message)
84
- end
85
-
86
- def disconnect
87
- if not @attr['AutoCommit'] and @in_transaction
88
- _exec("ROLLBACK") # rollback outstanding transactions
89
- end
90
- @connection.close
91
- end
92
-
93
- def ping
94
- answer = _exec("SELECT 1")
95
- if answer
96
- return answer.num_tuples == 1
97
- else
98
- return false
99
- end
100
- rescue PG::Error
101
- return false
102
- ensure
103
- answer.clear if answer
104
- end
105
-
106
- def database_name
107
- @connection.db
108
- end
109
-
110
- def tables
111
- stmt = execute("SELECT c.relname FROM pg_catalog.pg_class c WHERE c.relkind IN ('r','v') and pg_catalog.pg_table_is_visible(c.oid)")
112
- res = stmt.fetch_all.collect {|row| row[0]}
113
- stmt.finish
114
- res
115
- end
116
-
117
- #
118
- # See DBI::BaseDatabase.
119
- #
120
- # These additional attributes are also supported:
121
- #
122
- # * nullable: true if NULL values are allowed in this column.
123
- # * indexed: true if this column is a part of an index.
124
- # * primary: true if this column is a part of a primary key.
125
- # * unique: true if this column is a part of a unique key.
126
- # * default: what will be insert if this column is left out of an insert query.
127
- # * array_of_type: true if this is actually an array of this type.
128
- # +dbi_type+ will be the type authority if this is the case.
129
- #
130
- def columns(table)
131
- sql1 = %[
132
- select a.attname, i.indisprimary, i.indisunique
133
- from pg_class bc inner join pg_index i
134
- on bc.oid = i.indrelid
135
- inner join pg_class c
136
- on c.oid = i.indexrelid
137
- inner join pg_attribute a
138
- on c.oid = a.attrelid
139
- where bc.relname = ?
140
- and bc.relkind in ('r', 'v')
141
- and pg_catalog.pg_table_is_visible(bc.oid);
142
- ]
143
-
144
- sql2 = %[
145
- SELECT a.attname, a.atttypid, a.attnotnull, a.attlen, format_type(a.atttypid, a.atttypmod)
146
- FROM pg_catalog.pg_class c, pg_attribute a, pg_type t
147
- WHERE a.attnum > 0 AND a.attrelid = c.oid AND a.atttypid = t.oid AND c.relname = ?
148
- AND c.relkind IN ('r','v')
149
- AND pg_catalog.pg_table_is_visible(c.oid)
150
- ]
151
-
152
- # by Michael Neumann (get default value)
153
- # corrected by Joseph McDonald
154
- sql3 = %[
155
- SELECT pg_attrdef.adsrc, pg_attribute.attname
156
- FROM pg_attribute, pg_attrdef, pg_catalog.pg_class
157
- WHERE pg_catalog.pg_class.relname = ? AND
158
- pg_attribute.attrelid = pg_catalog.pg_class.oid AND
159
- pg_attrdef.adrelid = pg_catalog.pg_class.oid AND
160
- pg_attrdef.adnum = pg_attribute.attnum
161
- AND pg_catalog.pg_class.relkind IN ('r','v')
162
- AND pg_catalog.pg_table_is_visible(pg_catalog.pg_class.oid)
163
- ]
164
-
165
- dbh = DBI::DatabaseHandle.new(self)
166
- dbh.driver_name = DBI::DBD::Pg.driver_name
167
- indices = {}
168
- default_values = {}
169
-
170
- dbh.select_all(sql3, table) do |default, name|
171
- default_values[name] = default
172
- end
173
-
174
- dbh.select_all(sql1, table) do |name, primary, unique|
175
- indices[name] = [primary, unique]
176
- end
177
-
178
- ##########
179
-
180
- ret = []
181
- dbh.execute(sql2, table) do |sth|
182
- ret = sth.collect do |row|
183
- name, pg_type, notnullable, len, ftype = row
184
- #name = row[2]
185
- indexed = false
186
- primary = nil
187
- unique = nil
188
- if indices.has_key?(name)
189
- indexed = true
190
- primary, unique = indices[name]
191
- end
192
-
193
- typeinfo = DBI::DBD::Pg.parse_type(ftype)
194
- typeinfo[:size] ||= len
195
-
196
- if POSTGRESQL_to_XOPEN.has_key?(typeinfo[:type])
197
- sql_type = POSTGRESQL_to_XOPEN[typeinfo[:type]][0]
198
- else
199
- sql_type = POSTGRESQL_to_XOPEN[nil][0]
200
- end
201
-
202
- row = {}
203
- row['name'] = name
204
- row['sql_type'] = sql_type
205
- row['type_name'] = typeinfo[:type]
206
- row['nullable'] = ! notnullable
207
- row['indexed'] = indexed
208
- row['primary'] = primary
209
- row['unique'] = unique
210
- row['precision'] = typeinfo[:size]
211
- row['scale'] = typeinfo[:decimal]
212
- row['default'] = default_values[name]
213
- row['array_of_type'] = typeinfo[:array]
214
-
215
- if typeinfo[:array]
216
- row['dbi_type'] =
217
- DBI::DBD::Pg::Type::Array.new(
218
- DBI::TypeUtil.type_name_to_module(typeinfo[:type])
219
- )
220
- end
221
- row
222
- end # collect
223
- end # execute
224
-
225
- return ret
226
- end
227
-
228
- def prepare(statement)
229
- DBI::DBD::Pg::Statement.new(self, statement)
230
- end
231
-
232
- def [](attr)
233
- case attr
234
- when 'pg_client_encoding'
235
- @connection.client_encoding
236
- when 'NonBlocking'
237
- @attr['pg_async']
238
- else
239
- @attr[attr]
240
- end
241
- end
242
-
243
- def []=(attr, value)
244
- case attr
245
- when 'AutoCommit'
246
- if @attr['AutoCommit'] != value then
247
- if value # turn AutoCommit ON
248
- if @in_transaction
249
- # TODO: commit outstanding transactions?
250
- _exec("COMMIT")
251
- @in_transaction = false
252
- end
253
- else # turn AutoCommit OFF
254
- @in_transaction = false
255
- end
256
- end
257
- # value is assigned below
258
- when 'NonBlocking', 'pg_async'
259
- # booleanize input
260
- value = value ? true : false
261
- @pgexec = (value ? DBI::DBD::Pg::PgExecutorAsync : DBI::DBD::Pg::PgExecutor).new(@connection)
262
- # value is assigned to @attr below
263
- when 'pg_client_encoding'
264
- @connection.set_client_encoding(value)
265
- when 'pg_native_binding'
266
- @attr[attr] = value
267
- else
268
- if attr =~ /^pg_/ or attr != /_/
269
- raise DBI::NotSupportedError, "Option '#{attr}' not supported"
270
- else # option for some other driver - quitly ignore
271
- return
272
- end
273
- end
274
- @attr[attr] = value
275
- end
276
-
277
- def commit
278
- if @in_transaction
279
- _exec("COMMIT")
280
- @in_transaction = false
281
- else
282
- # TODO: Warn?
283
- end
284
- end
285
-
286
- def rollback
287
- if @in_transaction
288
- _exec("ROLLBACK")
289
- @in_transaction = false
290
- else
291
- # TODO: Warn?
292
- end
293
- end
294
-
295
- #
296
- # Are we in an transaction?
297
- #
298
- def in_transaction?
299
- @in_transaction
300
- end
301
-
302
- #
303
- # Forcibly initializes a new transaction.
304
- #
305
- def start_transaction
306
- _exec("BEGIN")
307
- @in_transaction = true
308
- end
309
-
310
- def _exec(sql, *parameters)
311
- @pgexec.exec(sql, parameters)
312
- end
313
-
314
- def _exec_prepared(stmt_name, *parameters)
315
- @pgexec.exec_prepared(stmt_name, parameters)
316
- end
317
-
318
- def _prepare(stmt_name, sql)
319
- @pgexec.prepare(stmt_name, sql)
320
- end
321
-
322
- private
323
-
324
- def parse_type_name(type_name)
325
- case type_name
326
- when 'bool' then DBI::Type::Boolean
327
- when 'int8', 'int4', 'int2' then DBI::Type::Integer
328
- when 'varchar' then DBI::Type::Varchar
329
- when 'float4','float8' then DBI::Type::Float
330
- when 'time', 'timetz' then DBI::Type::Timestamp
331
- when 'timestamp', 'timestamptz' then DBI::Type::Timestamp
332
- when 'date' then DBI::Type::Timestamp
333
- when 'decimal', 'numeric' then DBI::Type::Decimal
334
- when 'bytea' then DBI::DBD::Pg::Type::ByteA
335
- when 'enum' then DBI::Type::Varchar
336
- end
337
- end
338
-
339
- #
340
- # Gathers the types from the postgres database and attempts to
341
- # locate matching DBI::Type objects for them.
342
- #
343
- def load_type_map
344
- @type_map = Hash.new
345
-
346
- res = _exec("SELECT oid, typname, typelem FROM pg_type WHERE typtype IN ('b', 'e')")
347
-
348
- res.each do |row|
349
- rowtype = parse_type_name(row["typname"])
350
- @type_map[row["oid"].to_i] =
351
- {
352
- "type_name" => row["typname"],
353
- "dbi_type" =>
354
- if rowtype
355
- rowtype
356
- elsif row["typname"] =~ /^_/ and row["typelem"].to_i > 0 then
357
- # arrays are special and have a subtype, as an
358
- # oid held in the "typelem" field.
359
- # Since we may not have a mapping for the
360
- # subtype yet, defer by storing the typelem
361
- # integer as a base type in a constructed
362
- # Type::Array object. dirty, i know.
363
- #
364
- # These array objects will be reconstructed
365
- # after all rows are processed and therefore
366
- # the oid -> type mapping is complete.
367
- #
368
- DBI::DBD::Pg::Type::Array.new(row["typelem"].to_i)
369
- else
370
- DBI::Type::Varchar
371
- end
372
- }
373
- end
374
- # additional conversions
375
- @type_map[705] ||= DBI::Type::Varchar # select 'hallo'
376
- @type_map[1114] ||= DBI::Type::Timestamp # TIMESTAMP WITHOUT TIME ZONE
377
-
378
- # remap array subtypes
379
- @type_map.each_key do |key|
380
- if @type_map[key]["dbi_type"].class == DBI::DBD::Pg::Type::Array
381
- oid = @type_map[key]["dbi_type"].base_type
382
- if @type_map[oid]
383
- @type_map[key]["dbi_type"] = DBI::DBD::Pg::Type::Array.new(@type_map[oid]["dbi_type"])
384
- else
385
- # punt
386
- @type_map[key] = DBI::DBD::Pg::Type::Array.new(DBI::Type::Varchar)
387
- end
388
- end unless key.is_a?(Integer)
389
- end
390
- end
391
-
392
- public
393
-
394
- # return the postgresql types for this session. returns an oid -> type name mapping.
395
- def __types(force=nil)
396
- load_type_map if (!@type_map or force)
397
- @type_map
398
- end
399
-
400
- # deprecated.
401
- def __types_old
402
- h = { }
403
-
404
- _exec('select oid, typname from pg_type').each do |row|
405
- h[row["oid"].to_i] = row["typname"]
406
- end
407
-
408
- return h
409
- end
410
-
411
- #
412
- # Import a BLOB from a file.
413
- #
414
- def __blob_import(file)
415
- start_transaction unless @in_transaction
416
- @connection.lo_import(file)
417
- rescue PG::Error => err
418
- raise DBI::DatabaseError.new(err.message)
419
- end
420
-
421
- #
422
- # Export a BLOB to a file.
423
- #
424
- def __blob_export(oid, file)
425
- start_transaction unless @in_transaction
426
- @connection.lo_export(oid.to_i, file)
427
- rescue PG::Error => err
428
- raise DBI::DatabaseError.new(err.message)
429
- end
430
-
431
- #
432
- # Create a BLOB.
433
- #
434
- def __blob_create(mode=PG::Connection::INV_READ)
435
- start_transaction unless @in_transaction
436
- @connection.lo_creat(mode)
437
- rescue PG::Error => err
438
- raise DBI::DatabaseError.new(err.message)
439
- end
440
-
441
- #
442
- # Open a BLOB.
443
- #
444
- def __blob_open(oid, mode=PG::Connection::INV_READ)
445
- start_transaction unless @in_transaction
446
- @connection.lo_open(oid.to_i, mode)
447
- rescue PG::Error => err
448
- raise DBI::DatabaseError.new(err.message)
449
- end
450
-
451
- #
452
- # Remove a BLOB.
453
- #
454
- def __blob_unlink(oid)
455
- start_transaction unless @in_transaction
456
- @connection.lo_unlink(oid.to_i)
457
- rescue PG::Error => err
458
- raise DBI::DatabaseError.new(err.message)
459
- end
460
-
461
- #
462
- # Read a BLOB and return the data.
463
- #
464
- def __blob_read(oid, length)
465
- blob = @connection.lo_open(oid.to_i, PG::Connection::INV_READ)
466
-
467
- if length.nil?
468
- data = @connection.lo_read(blob)
469
- else
470
- data = @connection.lo_read(blob, length)
471
- end
472
-
473
- # FIXME it doesn't like to close here either.
474
- # @connection.lo_close(blob)
475
- data
476
- rescue PG::Error => err
477
- raise DBI::DatabaseError.new(err.message)
478
- end
479
-
480
- #
481
- # Write the value to the BLOB.
482
- #
483
- def __blob_write(oid, value)
484
- start_transaction unless @in_transaction
485
- blob = @connection.lo_open(oid.to_i, PG::Connection::INV_WRITE)
486
- res = @connection.lo_write(blob, value)
487
- # FIXME not sure why PG doesn't like to close here -- seems to be
488
- # working but we should make sure it's not eating file descriptors
489
- # up before release.
490
- # @connection.lo_close(blob)
491
- return res
492
- rescue PG::Error => err
493
- raise DBI::DatabaseError.new(err.message)
494
- end
495
-
496
- #
497
- # FIXME DOCUMENT
498
- #
499
- def __set_notice_processor(proc)
500
- @connection.set_notice_processor proc
501
- rescue PG::Error => err
502
- raise DBI::DatabaseError.new(err.message)
503
- end
504
- end # Database