From: Michael N. <mne...@us...> - 2002-10-02 18:10:40
|
Update of /cvsroot/ruby-dbi/src/doc In directory usw-pr-cvs1:/tmp/cvs-serv15432 Added Files: DBD_SPEC DBI_SPEC ToDo Log Message: moved from ../lib/dbi/doc --- NEW FILE: DBD_SPEC --- =begin = DBD Specification Version 0.2.2 (Draft) by Michael Neumann (ne...@s-...) $Id: DBD_SPEC,v 1.1 2002/10/02 18:10:37 mneumann Exp $ == DBD Directory Layout The directory layout is the following: DBD/ DBD/Driver1 DBD/Driver1/Driver1.rb DBD/Driver1/helper.rb . . DBD/Driver2 . . . Where "Driver1" and "Driver2" are the names of DBD driver. For example if you have two drivers installed, "Oracle" and "Sybase" it would look like: DBD/ DBD/Oracle DBD/Oracle/Oracle.rb # <== this is the main driver DBD/Oracle/oracle.so # <== is used by Oracle.rb DBD/Sybase/Sybase.so # <== this is the main driver # has no helper files When DBI loads a DBD driver it search all "DBD" directories in Ruby's LOAD_PATH ($:). Database dependent functions, that should be callable with DBI::func, must use the prefix "__" before their method names, to prevent nameclashes with further versions of Ruby/DBI! == Driver Name The DBD driver is simply named after the Database, e.g. Oracle, DB2 etc. The suffix will normally be ".rb" but can be any other valid suffix, which Ruby is possible to load, e.g. ".so", ".sl" or ".dll", and depends for non-Ruby DBD driver on the underlying operating system. When I refer to the driver name, then I speak of the filename without the suffix, e.g. Oracle or DB2. The name specified in the DSN ((-Data Source Name, e.g. "dbi:Oracle:oracle.neumann"-)) must be the same as the driver name. == Classes provided by a DBD A DBD driver has to provide three classes in the namespace (({DBI::DBD::}))((*DriverName*)) where ((*DriverName*)) is the name of the driver, e.g. Oracle or DB2. The three classes must be named (({Driver})), (({Database})) and (({Statement})). == Class Driver This class must inherit from (({DBI::BaseDriver})). === Methods which must be provided by (({Driver})) --- connect( dbname, user, auth, attr ) Connect to a database and return a newly created (({Database})) object. === Optional methods which can be specified by (({Driver})) --- default_user Return an array of the form (({['username', 'password']})) which represent the default user when no user and password was specified. Defaults to (({['', '']})) if not implemented. --- default_attributes Return a (({Hash})) containing the default attributes which are used in (({connect})) additional to the ones the user specify. Defaults to (({{}})) (empty hash) if not implemented. --- data_sources Return an array of all valid DSN this driver can access. Defaults to (({[]})) (empty array) if not implemented. --- disconnect_all Disconnect all connections made with this driver. Defaults to raise a NotImplementedError. == Class Database This class must inherit from (({DBI::BaseDatabase})). === Methods which must be provided by (({Database})) --- disconnect Disconnect from database. But before you have to rollback all outstanding transactions, so all changes not yet commited get lost. --- prepare( statement ) Prepare the SQL ((*statement*)) and return an object of class (({Statement})). --- ping Ping the database, and check if the connection is alive. This can be implemented by executing a SQL statement like "SELECT 1 FROM DUAL" for Oracle database, or for other databases this should be query on a table which normally always exists. Return (({true})) if the connection is alive, otherwise (({false})). === Optional methods which can be specified by (({Database})) --- commit --- rollback Commit or roll back the current transaction. Defauls to raise a NotSupportedError, so if the database do not implement transactions (mSQL, mySQL, CSV) do not overwrite this method. --- tables Return an Array of all tables and views. Defaults to return the empty Array []. --- columns( table ) Return more information about the columns of table ((*table*)). Return an Array of Hashes, like Statement#column_info do. Defaults to return an empty Array []. --- execute( statement, *bindvars ) Immediate execution (without preparation) of SQL ((*statement*)) with binding of placeholders to values given in ((*bindvars*)) before. Return a (({Statement})) object. Defaults to the call sequence of Database#prepare(), Statement#bind_params() and Statement#execute(). --- do( statement, *bindvars ) Execution of SQL ((*statement*)) with binding of placeholders to values given in ((*bindvars*)) before, but without returning a (({Statement})) object. So this is used for 'INSERT', 'UPDATE', 'DELETE' as well as for DCL, which do not return a result-set. Return the RPC (Row Processed Count) or (({nil})) if no RPC is available. Defaults to Database#execute() and Statement#rows() followed by Statement#finish(). --- quote( value ) Quote the given value ((*value*)) database specific and return the result. NOTE: This method is not really useful, because of Statement#bind_param. --- []( attr ) Return value of attribute ((*attr*)). Defauls to return the value of (({@attr[attr]})). --- []=( attr, value ) Set value of attribute ((*attr*)) to ((*value*)). An attribute is e.g. "AutoCommit". Raise a NotSupportedError, if the database do not support an attribute. The default implementation is to raise a NotSupportedError. == Class Statement This class must inherit from (({DBI::BaseStatement})). === Methods which must be provided by (({Statement})) --- bind_param( param, value, attribs ) Bind ((|param|)) which is either a (({String})) which is then the name of the placeholder used in the SQL statement (e.g. Oracle: "SELECT * FROM EMP WHERE ENAME = :ename") or it is a (({Fixnum})) which is then the number of the placeholder where counting starts at 1. ((|value|)) is the value which is bound to the placeholder. If ((|value|)) is a (({String})), then the default SQL type is (({VARCHAR})) or (({CHAR})). If ((|value|)) is a (({Fixnum})) or (({Bignum})), the default SQL type is (({INT})). If ((|value|)) is a (({Float})), the default SQL type is (({FLOAT})). ((*attribs*)) is not yet used in this version but could be a hash containing more information like parameter type etc. --- execute Execute the statement. --- finish Free all the resources for the statement. After calling (({finish})) no other operation on this statement is valid. --- fetch Fetch the current row. Return a (({Array})) containing all column-data or (({nil})) if the last column has been read. Note: This method should return not a newly created object on each call, instead you should return one and the same Array object but with changed data. --- column_info Return an (({Array})) of (({Hash}))'s, one for each column. Each (({Hash})) object must have at least one key 'name' which value is the name of that column. Further possible values are 'sql_type' (integer, e.g. DBI::SQL_INT), 'type_name' (string), 'precision' (= column size), 'scale' (= decimal digits), 'default', 'nullable', 'indexed', 'primary' and 'unique'. --- rows Return the RPC (Row Processed Count) of the last executed statement, or (({nil})) if no such exist. === Optional methods which can be specified by (({Statement})) --- bind_params( *bindvars ) Binds the placeholders in the statement to the values of ((|bindvars|)). Defaults to calling ((<bind_param>)) for each value, with ((*param*)) starting from 1 increasingly. --- cancel Free any result set resources which were made after a call to (({execute})). After calling this method, a call to one of the ((*fetch*)) methods is no more valid. Defaults to do nothing. --- fetch_scroll( direction, offset ) ((*direction*)) is one of the following constants: * SQL_FETCH_NEXT * SQL_FETCH_PRIOR * SQL_FETCH_FIRST * SQL_FETCH_LAST * SQL_FETCH_ABSOLUTE * SQL_FETCH_RELATIVE ((*offset*)) is a positive or negativ number (only when SQL_FETCH_RELATIVE is used). By default only SQL_FETCH_NEXT, SQL_FETCH_LAST, SQL_FETCH_RELATIVE (if positive) are implemented, otherwise it raises NotSupportedError. Note: This method should return not a newly created object on each call, instead you should return one and the same Array object but with changed data. --- fetch_many( cnt ) Return an (({Array})) of the next ((*cnt*)) rows, where a row is itself an (({Array})). Note: Unlike (({fetch})), this method should return a new Array object. If there are no more ((*cnt*)) rows available return the rest. Return (({nil})) if no rows are available. Defaults to multiple calls to (({fetch})). --- fetch_all Return an (({Array})) of all rows which have not yet been fetched, where a row is itself an (({Array})) (see Statement#fetch_many). Note: Unlike (({fetch})), this method should return a new Array object. Return (({nil})) if no rows are available. Defaults to multiple calls to (({fetch})). --- []( attr ) Return value of attribute ((*attr*)). Defauls to return the value of (({@attr[attr]})). --- []=( attr, value ) Set value of attribute ((*attr*)) to ((*value*)). Raise a NotSupportedError, if the database do not support an attribute. The default implementation is to raise a NotSupportedError. =end --- NEW FILE: DBI_SPEC --- =begin = DBI Interface Specification Version 0.2.2 (Draft) by Michael Neumann (ne...@s-...) $Id: DBI_SPEC,v 1.1 2002/10/02 18:10:37 mneumann Exp $ == Module DBD === Constants --- API_VERSION Use this in your DBD driver to ensure it is used with the correct DBD API-Version == Module DBI === Constants --- VERSION Version of the DBI Interface --- SQL_FETCH_NEXT --- SQL_FETCH_PRIOR --- SQL_FETCH_FIRST --- SQL_FETCH_LAST --- SQL_FETCH_ABSOLUTE Constants for (({StatementHandle#fetch_scroll})). --- SQL_BIT --- SQL_TINYINT --- SQL_SMALLINT --- SQL_INTEGER --- SQL_BIGINT --- SQL_FLOAT --- SQL_REAL --- SQL_DOUBLE --- SQL_NUMERIC --- SQL_DECIMAL --- SQL_CHAR --- SQL_VARCHAR --- SQL_LONGVARCHAR --- SQL_DATE --- SQL_TIME --- SQL_TIMESTAMP --- SQL_BINARY --- SQL_VARBINARY --- SQL_LONGVARBINARY --- SQL_OTHER Constant representing SQL types. === Exceptions Exception classes were "borrowed" from Python API 2.0. --- Warning < RuntimeError For important warnings like data truncation etc. --- Error < RuntimeError Base class of all other error exceptions. Use this to catch all errors. --- InterfaceError < Error Exception for errors related to the DBI interface rather than the database itself. --- NotImplementedError < InterfaceError Exception raised if the DBD driver has not specified a mandantory method (not in Python API 2.0). --- DatabaseError < Error Exception for errors related to the database. Has three attributes ((|err|)), ((|errstr|)) and ((|state|)). --- DataError < DatabaseError Exception for errors due to problems with the processed data like division by zero, numeric value out of range etc. --- OperationalError < DatabaseError Exception for errors related to the database's operation which are not necessarily under the control of the programmer like unexpected disconnect, datasource name not found, transaction could not be processed, a memory allocation error occured during processing etc. --- IntegrityError < DatabaseError Exception raised when the relational integrity of the database is affected, e.g. a foreign key check fails --- InternalError < DatabaseError Exception raised when the database encounters an internal error, e.g. the cursor is not valid anymore, the transaction is out of sync. --- ProgrammingError < DatabaseError Exception raised for programming errors, e.g. table not found or already exists, syntax error in SQL statement, wrong number of parameters specified, etc. --- NotSupportedError < DatabaseError Raised if e.g. commit() is called for a database which do not support transactions. === Module functions --- DBI.connect( driver_url, user=nil, auth=nil, params=nil ) Connect to the database specified by ((*driver_url*)), which may look like "dbi:Oracle:oracle.neumann". Returns an (({DBI::DatabaseHandle})) object, or if called with code-block, calls this block with the new (({DBI::DatabaseHandle})) as parameter and calls (({disconnect})) after calling the block if it was not yet disconnected by the user. --- DBI.available_drivers Returns an (({Array})) of all available DBD driver. The strings which represent a DBD driver are partial DSN's (e.g. "dbi:Oracle:"). --- DBI.data_sources( driver ) Returns all available DSN's for the ((*driver*)), which is a partial DSN (e.g. "dbi:Oracle:"). --- DBI.disconnect_all( driver=nil ) Disconnects all active connections of ((*driver*)) or all drivers if ((*driver*)) is (({nil})). --- DBI.trace(mode=nil, output=nil) Set the trace mode for all following created Handles to these values. If a parameter is (({nil})) the value is not changed. ((|mode|)) defaults to 2 if it is (({nil})), and ((|output|)) to (({STDERR})) if a value was not set before. For ((|mode|)) the values 0, 1, 2 or 3 are allowed. Note: Tracing is only activated, if you load the module "dbi/trace", because tracing currently depends on AspectR > 0.3.3. == Class DBI::Handle Abstract base class for all "Handles" (DriverHandle, DatabaseHandle, StatementHandle). === Instance Methods --- func( function, *values ) Calls the driver specific extension function named by ((|function|)) with ((|values|)) as parameters. --- trace(mode=nil, output=nil) Set the trace mode for this handle as well as for all sub-handles (in the case of DriverHandle and DatabaseHandle). If a parameter is (({nil})) the value is not changed. ((|mode|)) defaults to 2 if it is (({nil})), and ((|output|)) to (({STDERR})) if a value was not set before. For ((|mode|)) the values 0, 1, 2 or 3 are allowed. Note: Tracing is only activated, if you load the module "dbi/trace", because tracing currently depends on AspectR > 0.3.3. == Class DBI::DatabaseHandle === Superclass --- DBI::Handle === Instance Methods --- connected? Returns (({true})) if the connection was not yet disconnected by calling ((<disconnect>)), otherwise (({false})). --- disconnect Disconnects the connection. --- prepare( stmt ) --- prepare( stmt ) {|statement_handle| aBlock} Prepare the SQL statement ((|stmt|)) and return a (({DBI::StatementHandle})) or if called with a code-block calls the block with the handle as parameter and after that calls (({#finish})) onto the handle to free all resources --- execute( stmt, *bindvars ) --- execute( stmt, *bindvars ) {|statement_handle| aBlock} Executes immediately the SQL statement ((*stmt*)) with binding the placeholders with values given in ((*bindvars*)) before. Returns a (({DBI::StatementHandle})) or if called with code-block calls the block with the handle as parameter and after that calls (({#finish})) onto the handle to free all resources. --- do( stmt, *bindvars ) Same as ((<execute>)) only that no (({DBI::StatementHandle})) is returned but the RPC (Row Processed Count). --- select_one( stmt, *bindvars) Executes the statement with binding the values to the parameters and returns the first row as a reference to a Row object. --- select_all( stmt, *bindvars) Executes the statement with binding the values to the parameters and returns all resulting rows. If called as iterator the passed (({DBI::Row})) objects are only references. --- tables Returns a list of all tables and views. --- columns( table ) Get more information about the columns of table ((|table|)). Returns an array containing for each column one (({DBI::ColumnInfo})) object. --- ping Returns (({true})) if the connection is active, otherwise (({false})). In contranst to ((<connected?>)), ((<ping>)) tests if the connection is still active by executing some SQL or doing something else. --- quote( value ) Quotes the given value ((*value*)) database specific and returns the result. --- commit Commits current transaction. --- rollback Rolls the current transaction back. --- transaction {|database_handle| aBlock} First commits the current transaction, then executes the given block where the parameter is the object itself (the database handle). If the block raises an exception, then it rolls the transaction back otherwise commits it. --- [](attr) --- []=(attr) Sets or gets the attribute ((*attr*)). An attribute can for example be "AutoCommit", which can be set to (({true})) or (({false})). Attributes are database dependant. == Class DBI::StatementHandle === Superclass --- DBI::Handle === Mixins --- Enumerable === Instance Methods --- bind_param( param, value, attribs=nil ) Bind ((*param*)) which is either a (({String})) which is then the name of the placeholder used in the SQL statement (e.g. Oracle: "SELECT * FROM EMP WHERE ENAME = :ename") or it is an integer which is then the number of the placeholder where counting starts at 1. ((*value*)) is the value which is bound to the placeholder. ((*attribs*)) is not yet used in this version, but could later be a hash containing more information like parameter type etc.. --- execute( *bindvars ) Execute the statement but before binds the placeholders with ((*bindvars*)). --- finish Frees the resources for the statement. After calling ((<finish>)) no other operation on this statement is valid. --- cancel Frees any result set resources which were made after a call to (({execute})). After calling this method, a call to one of the ((*fetch*)) methods is no more valid. --- column_names Returns an (({Array})) of all column names. --- column_info Returns an (({Array})) containing fore each column one (({DBI::ColumnInfo})) object. --- rows Returns the RPC (Row Processed Count) of the last executed statement, or (({nil})) if no such exist. --- fetchable? Returns true if you can fetch rows using fetch etc.. --- fetch Returns a (({DBI::Row})) object, or (({nil})) if there are no more rows to fetch. When called as iterator, the block is called for each row until no more row is available. Each row is passed to the block as (({DBI::Row})) object. Note that the returned or passed (({DBI::Row})) object is only a reference and should be copied (dup) if it is store elsewhere. --- each {|row| aBlock } Same as ((<fetch>)) called as iterator. --- fetch_array Returns the current row as (({Array})) or nil if no more row is available. Can be also called as iterator. --- fetch_hash Returns the current row as (({Hash})) or nil if no more row is available. Can be also called as iterator. --- fetch_many( cnt ) Returns an (({Array})) of the next ((*cnt*)) rows, which are stored as (({DBI::Row})) objects. Returns the empty array (({[]})) if there are no more rows. --- fetch_all Same as ((<fetch_many>)) only that all rows are returned. --- fetch_scroll( direction, offset=1 ) ((*direction*)) is one of the following constants: * SQL_FETCH_NEXT * SQL_FETCH_PRIOR * SQL_FETCH_FIRST * SQL_FETCH_LAST * SQL_FETCH_ABSOLUTE * SQL_FETCH_RELATIVE ((*offset*)) is a positive or negativ number (only when SQL_FETCH_RELATIVE is used). ((<fetch_scroll>)) do not automatically free the result set if no more rows are available if e.g. you get the last row. Returns a (({DBI::Row})) object, if not possible, returns (({nil})). Note that the returned (({DBI::Row})) object is only a reference and should be copied (dup) if it is stored elsewhere. --- [](attr) --- []=(attr) Sets or gets the attribute ((*attr*)). =end --- NEW FILE: ToDo --- =begin = ToDo * SQL statement parser like Perl's SQL::Statement * LDAP DBD * column_info: precision == column_size or == column_size - scale ??? * fetch_many callable as iterator * make SQL::bind preparable (parse SQL statement before) * columns / column_info with more DBDs (DB2, Oracle, Interbase, ODBC) * Tainting * table_info * bind_param_inout * type_info / type_info_all * bind_col ? * Rewrite DBI-dispatching in C? * warn if commit/rollback and AutoCommit is on * bind_out_param/bind_inout_param * tracing/logging for DBDs by calling log(...) * define exact behaviour of fetch_scroll * define exact behaviour of exception classes * do not pass *args paramters to DBD (it's harder for C-extensions to handle them) * thead safety ? * asynchronous execution = Done * version.rb; don't update everytime dbi.rb when version changes * fetch_all should always return an array, as well as select_all etc., fetch_many always [] * get a Driver object, call methods on it * blob_import etc. for DBD::Pg * parameter markers in DB2 =end |