#include <rw/db/cursor.h> RWDBCursor cursor = myDbase.cursor(mySelector); RWDBCursor cursor = myDbase.cursor("SQL String"); RWDBCursor cursor = myTable.cursor();
RWDBCursor is an encapsulation of a database cursor. It is a relatively low-level construct that maps directly onto a database cursor.
Despite the efforts of various standards bodies, cursor capabilities vary widely among database vendors. DBTools.h++ makes no attempt to emulate functionality that is not supported by the underlying database engine. For example, if a database vendor's implementation does not support scrollable cursors, an application requesting a scrollable RWDBCursor from that RWDBDatabase receives an RWDBCursor with a status of RWDBStatus::notSupported. The remainder of this section assumes that all features are supported. See the DBTools.h++ access library guide for details concerning RWDBCursor restrictions for a particular database.
RWDBCursor captures common features of database cursors.
Specifically:
There can be multiple RWDBCursors open on a single connection.
RWDBCursor provides row-by-row access to data.
RWDBCursor supports index entry and positioned deletes.
RWDBCursor may be read-only or read-write.
RWDBCursor may be scrollable or sequential.
RWDBCursor operates on application-supplied buffers. It is pointer-based rather than value-based.
The insertion operator << is used to supply an RWDBCursor with pointers to application variables. When possible, RWDBCursor performs a cursor bind operation directly on the pointer provided. This is always possible for pointers to primitive C++ types. Otherwise, the RWDBCursor allocates enough space internally to do the required type conversion, binds to its internal buffers, and arranges for results to be copied into the buffers supplied by the application.
An application continues to own the memory supplied to an RWDBCursor, and it is the application's responsibility to ensure that a pointer remains valid for as long as the RWDBCursor requires it. The unbind() method can be used to dissociate program memory from the RWDBCursor.
RWDBCursor has a notion of the current column position within the current row. Each time the cursor is advanced to a new row, the column position is set to 0. Each insertion increments the column position by 1. The indexing operators [] set the position to a specified index, column, or column name. They return a reference to self, so that any of the following notations may be used:
cursor << &x; cursor[i] << &x; cursor["columnName"] << &x; cursor[table["columnName"]] << &x;
RWDBCursor is designed around the Interface/Implementation paradigm. An RWDBCursor instance is an interface to a reference-counted implementation; copy constructors and assignment operators produce additional references to a shared implementation. RWDBCursor implementations are base classes from which a family of database-specific cursor implementations are derived.
Assume there are database tables Inventory and Suppliers. The Inventory table has partNumber, Supplier, and onHand columns; the Suppliers table has Supplier and toOrder columns. This example uses two RWDBCursors to examine the Inventory table for any parts that have fewer than 10 on hand, and increment the order column in the Suppliers table for each such part.
RWDBConnection session = myDbase.connection(); RWDBTable inventory = myDbase.table("Inventory"); RWDBTable suppliers = myDbase.table("Suppliers"); RWDBSelector shortage = myDbase.selector(); shortage << inventory; RWDBSelector order = myDbase.selector(); order << suppliers; shortage.where(inventory["onHand"] < 10); RWDBCursor invCsr = shortage.cursor(session); int partNumber; RWCString supplier; int onHand; int toOrder; invCsr << &partNumber << &supplier << &onHand; while (invCsr.fetchRow().isValid()) { order.where(suppliers["Supplier"] == supplier); session.beginTransaction(); RWDBCursor ordCsr = order.cursor(session, RWDBCursor::Sequential, RWDBCursor::Write); ordCsr << &supplier << &toOrder; while (ordCsr.fetchRow().isValid()) { ++toOrder; ordCsr.updateRow(suppliers.name()); } session.commitTransaction(); }
enum CursorAccess { Read, Write };
A Read cursor can only be used to select data. A Write cursor can also be used for updates, inserts, and deletes.
enum CursorPosition { First, Last, Next, Previous, Absolute, Relative };
The cursorPosition is used by the fetchRow() method to identify the row to be fetched. A Scrolling cursor can fetch any row in a set of result rows. A Sequential cursor can only fetch the Next row.
enum CursorType { Sequential, Scrolling };
A Sequential cursor can only advance to the Next row. A Scrolling cursor can move to the First, Last, Next, or Previous row; to a row number Relative to the current row; or to an Absolute row number.
RWDBValueManip rwdbNull;
rwdbNull is used to represent a literal NULL value. A NULL value can be inserted through an RWDBCursor by calling insertRow after shifting in rwdbNull:
cursor << rwdbNull;
RWDBValueManip is a typedef:
typedef void (*RWDBValueManip)(RWDBValue&);
RWDBCursor();
The default constructor creates an RWDBCursor whose status is RWDBStatus::notInitialized. This constructor is provided as a convenience, for example, for declaring an array of RWDBCursors. Usable RWDBCursors are obtained from RWDBDatabases, RWDBTables, and RWDBSelectors.
RWDBCursor(const RWDBCursor& csr);
Copy constructor. Self shares an implementation with csr.
RWDBCursor& operator=(const RWDBCursor& csr);
Assignment operator. Self shares an implementation with csr.
RWDBCursor& operator[](const RWDBColumn& column);
Changes the current row position to the index of the first column in self's result set whose name matches the name of the given column. If there is no such column, sets self's status to RWDBStatus::invalidPosition. Returns a reference to self.
RWDBCursor& operator[](const RWCString& colName);
Changes the current row position to the index of the first column in self's result set whose name matches colName. If there is no such column, sets self's status to RWDBStatus::invalidPosition. Returns a reference to self.
RWDBCursor& operator[](size_t index);
Changes the current row position to index. If index is out of range, self's status is set to RWDBStatus::invalidPosition. Returns a reference to self.
RWDBCursor& operator<<(short* val); RWDBCursor& operator<<(unsigned short* val); RWDBCursor& operator<<(int* val); RWDBCursor& operator<<(unsigned int* val); RWDBCursor& operator<<(long* val); RWDBCursor& operator<<(unsigned long* val); RWDBCursor& operator<<(float* val); RWDBCursor& operator<<(double* val); RWDBCursor& operator<<(RWCString* val); RWDBCursor& operator<<(RWDate* val); RWDBCursor& operator<<(RWDBBlob* val); RWDBCursor& operator<<(RWDBDateTime* val); RWDBCursor& operator<<(RWDBDuration* val); RWDBCursor& operator<<(RWDecimalPortable* val); RWDBCursor& operator<<(RWDBMBString* val); RWDBCursor& operator<<(RWWString* val);
The insertion operator is used to bind application variables to an RWDBCursor. Each call to fetchRow() populates the application variables with data from the fetch. Each call to insertRow() inserts the current contents of the relevant application variables into a database table. Each call to updateRow() updates a database table with the current contents of the relevant application variables. Returns a reference to self.
RWDBCursor& operator<<(RWDBValueManip);
Uses the valueManip rwdbNull to insert a NULL value into a database table. Returns a reference to self.
NOTE:This function is deprecated, and may be removed from future versions of DBTools.h++. Please use the function setNull(size_t colPosition) instead.
RWDBCursor::CursorAccess access() const;
Returns self's cursor access. The cursor access is specified when an RWDBCursor is first obtained. The default is RWDBCursor::Read.
void acquire() const;
Attempts to acquire the internal mutex lock. If the mutex is already locked by another thread, the function blocks until the mutex is released. This function can be called from a const object. Note: in nonmultithreaded builds, this function evaluates to a no-op.
RWDBConnection connection() const;
Returns the database connection used by self. An RWDBCursor holds an RWDBConnection until the RWDBCursor is destroyed. There may be more than one RWDBCursor opened using the same RWDBConnection.
RWDBStatus deleteRow(const RWCString& tablename);
Encapsulates the database-specific equivalent of the SQL statement:
DELETE tableName WHERE CURRENT OF CURSOR
You can check the return value's isValid() method to see if the operation succeeded. If the cursor is associated with an asynchronous connection, this function behaves asynchronously.
RWDBStatus::ErrorHandler errorHandler() const;
Returns the error handler attached to self.
RWDBStatus fetchRow(CursorPosition position = Next, int offset = 1);
Fetches a row into self. Returns RWDBStatus::endOfFetch if there are no more rows. If the cursor is associated with an asynchronous connection, this function behaves asynchronously.
If self is a Sequential cursor, the only allowable value for position is Next; offset is ignored and the next row is fetched. Returns a status of RWDBStatus::invalidUsage if position is not Next.
If self is a Scrollable cursor and position is First, Last, Next, or Previous, offset is ignored and the specified row is fetched. If self is a Scrollable cursor and position is Relative, the row at the current position + offset is fetched. If self is a Scrollable cursor and position is Absolute, the row number identified by offset is fetched. Returns a database-specific error if the specified row does not exist.
RWDBStatus insertRow(const RWCString& tableName);
Encapsulates the database-specific equivalent of the SQL statement:
INSERT tableName WHERE CURRENT OF CURSOR
You can check the return value's isValid() method to see if the operation succeeded. If the cursor is associated with an asynchronous connection, this function behaves asynchronously.
RWBoolean isNull(size_t index) const;
Returns TRUE if the last value fetched into self at column position index was NULL, otherwise returns FALSE.
RWBoolean isReady() const;
Returns TRUE if the object is in ready state, indicating that accessing the object will not block. Accessing a nonready object may potentially block.
RWBoolean isValid() const;
Returns TRUE if self's status is RWDBStatus::ok, otherwise returns FALSE.
RWCString name() const;
Returns self's name. DBTools.h++ generates a unique name for every RWDBCursor. The name is used if the underlying database requires cursors to be named.
void release() const;
Releases a previously acquired mutex. This function can be called from a const object. Note: in nonmultithreaded builds, this function evaluates to a no-op.
RWDBSchema schema() const;
Returns a deep copy of self's RWDBSchema containing all column information. The copy is made so that an application can modify the returned RWDBSchema without changing self's schema.
void setErrorHandler(RWDBStatus::ErrorHandler handler);
Installs handler as self's error handler. The supplied handler is inherited by all objects produced by self. By default, the error handler of an RWDBCursor is inherited from the object which produced it; this method overrides the default. ErrorHandler is declared as a typedef within the scope of RWDBStatus:
typedef void (*ErrorHandler)(const RWDBStatus&);
void setNull(size_t colPosition);
Sets the value at column colPosition to NULL, so that the next update or insert will make the corresponding field NULL.
RWDBStatus status() const;
Returns the current status of self.
RWDBCursor::CursorType type() const;
Returns self's cursor type. The cursor type is specified when an RWDBCursor is first obtained. The default is RWDBCursor:Sequential.
RWDBStatus unbind();
Releases all pointers to external buffers that self holds. If the cursor is associated with an asynchronous connection, this function behaves asynchronously.
RWDBStatus updateRow(const RWCString& tableName);
Encapsulates the database-specific equivalent of:
UPDATE tableName SET <set-clause> WHERE CURRENT OF CURSOR
where <set-clause> refers to the values in self which belong to tableName. You can check the return value's isValid() method to see if the operation succeeded. If the cursor is associated with an asynchronous connection, this function behaves asynchronously.
void unsetNull(size_t colPosition);
Unsets NULL from the value at column colPosition, so that the bound-in value for this column is used on the next update or insert.
©Copyright 1999, Rogue Wave Software, Inc.
Contact Rogue Wave about documentation or support issues.