1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
module DBI
# Provides the core-level functionality for DatabaseHandles.
#
# If the method description says "DBD Required", it's the DBD's
# responsibility to create this method.
#
# Required methods unimplemented by the DBD will raise
# DBD::NotImplementedError.
#
# "DBD Optional" methods are methods that do not have a default
# implementation but are optional due to the fact that many databases may
# not support these features (and emulating them would be prohibitive).
#
# These methods raise DBI::NotSupportedError.
#
# Otherwise, DBI will provide a general alternative which should meet the
# expectations of the documentation. However, DBDs can override every
# method in this class.
#
class BaseDatabase < Base
def initialize(handle, attr)
@handle = handle
@attr = {}
attr.each {|k,v| self[k] = v}
end
# Disconnect from the database. DBD Required.
def disconnect
raise NotImplementedError
end
# Ping the database to ensure the connection is still alive. Boolean
# return, true for success. DBD Required.
def ping
raise NotImplementedError
end
# Prepare a cached statement, returning a StatementHandle. DBD
# Required.
def prepare(statement)
raise NotImplementedError
end
#
# Return a map of the columns that exist in the provided table name.
# DBD Required.
#
# The result should be an array of DBI::ColumnInfo objects which have,
# at minimum, the following fields:
#
# * name:: the name of the column.
# * type:: This is not a field name in itself. You have two options:
# * type_name:: The name of the type as returned by the database
# * dbi_type:: A DBI::Type-conforming class that can be used to convert to a native type.
# * precision:: the precision (generally length) of the column
# * scale:: the scale (generally a secondary attribute to precision
# that helps indicate length) of the column
#
def columns(table)
raise NotImplementedError
end
#============================================
# OPTIONAL
#============================================
# Schedule a commit to the database immediately. DBD Optional.
def commit
raise NotSupportedError
end
# Schedule a rollback to the database immediately. DBD Optional.
def rollback
raise NotSupportedError
end
# Return the tables available to the database connection.
#
# Note:: the basic implementation returns an empty array.
def tables
[]
end
#
# Execute a statement with the binds provided. Returns the statement
# handle unfinished.
#
# This is roughly equivalent to:
#
# sth = dbh.prepare("my statement")
# sth.execute(my, bind, vars)
#
def execute(statement, *bindvars)
stmt = prepare(statement)
stmt.bind_params(*bindvars)
stmt.execute
stmt
end
#
# Execute and complete the statement with the binds provided. Returns
# the row modified count (via BaseStatement#rows). Finishes the
# statement handle for you.
#
# Roughly equivalent to:
#
# sth = dbh.prepare("my statement")
# sth.execute(my, bind, vars)
# result = sth.rows
# sth.finish
#
# Returning the value stored in `result`.
def do(statement, *bindvars)
stmt = execute(statement, *bindvars)
res = stmt.rows
stmt.finish
return res
end
#
# Get an attribute from the DatabaseHandle. These are DBD specific and
# embody things like Auto-Commit support for transactional databases.
#
# DBD Authors:: This messes with @attr directly.
#
def [](attr)
@attr[attr]
end
# Set an attribute on the DatabaseHandle. DBD Optional.
def []=(attr, value)
raise NotSupportedError
end
end # class BaseDatabase
end
|