oracle c++ call interface
TRANSCRIPT
Geoff LeeSr. Product ManagerOracle Corporation
Oracle C++ Call Interface A New API for High-Performance Internet Applications
Agenda
Survey Customer Requirements Meeting the Needs Realizing the Benefits Summary Q & A
Agenda
Survey Customer Requirements Meeting the Needs Realizing the Benefits Summary Q & A
Customer Requirements
Comprehensive Support– Oracle Relational and Object-Relational
access
High performance and Scalable API– Reduce round-trip access, minimize data
copying, caching, connection pooling, etc.
High Productivity– Simple: hiding complexity– Easy: familiar constructs
Agenda
Survey Customer Requirements Meeting the Needs Realizing the Benefits Summary Q & A
Meeting the Needs
Comprehensive Support (OCI)– Oracle Relational and Object-Relational
access
High performance and Scalable API (OCI)– Reduce round-trip access, minimize data
copying, cacheing, connection pooling, etc.
High Productivity (C++/Java)– Simple: hiding complexity– Easy: familiar constructs
Oracle C++ Call Interface
Built on top of OCI– Comprehensive Support
Oracle Relational and Object-Relational access
– High performance and scalable API Reduce round-trip access, minimize data
copying, cacheing, connection pooling, etc.
C++ API modeled after JDBC– High Productivity (C++)
Simple: encapsulation Easy: JDBC-like constructs
Agenda
Survey Customer Requirements Meeting the Needs
– Associative Relational Access– Objects Access– Metadata Access
Realizing the Benefits Summary Q & A
Using OCCI
setup and connection executing SQL statements using objects
– Navigational Interface – Associative (SQL) Interface
Conn
Env
ConnPool
Stmt
ResultSet
MetaData
CreateCreate
CreategetMD
getMD
getResultSet
Create
OCCI Factory Hierarchy
executeUpdate() Example
Creating a Table Statement *stmt = conn->createStatement();stmt->executeUpdate(“ CREATE TABLE basket ( fruit VARCHAR2(20), quantity NUMBER)”);
SQL DML statementstmt->executeUpdate(“ INSERT INTO basket values (‘MANGO’, 3)”);
Executing Prepared Statement SQL DML statement with IN bind variables
stmt->setSQL(“ INSERT INTO basket VALUES(:1, :2)”);
stmt->setString(1, “BANANA”); // value for first param
stmt->setInt(2, 5); // value for second param
stmt->executeUpdate();
Executing Callable Statements Calling procedures stored on the database
serverint quantity;stmt->setSQL("BEGIN countFruit(:1, :2); END:");// specify the first (IN) parameter of procedurestmt->setString(1, "Apples");// specify the type and size of the second (OUT) parameterstmt->registerOutParam(2, Type::OCCIINT, sizeof(quantity));stmt->executeUpdate(); // get the value of the second (OUT) parameterquantity = stmt->getInt(2);
Executing SQL Queries
ResultSet *rs = stmt->executeQuery(“SELECT quantity FROM basket
WHERE fruit = ‘ORANGE’ “);
rs->next(); // fetch the next row
int quantity = rs->getInt(1); // get first col as int
Executing SQL Queries
rs =stmt->executeQuery(“SELECT * FROM basket”);
cout << “The basket has :” << endl;while (rs->next()){ string fruit = rs->getString(1); int quantity = rs->getInt(2); cout << quantity << “ “ << fruit << endl;}
Committing a Transaction
All SQL DML statements are executed in the context of a transaction
– Changes become permanent by committing the transaction
– Undo changes by performing a rollback– SQL COMMIT and ROLLBACK can be
executed with executeUpdate method– Connection::commit() and
Connection::rollback() methods can also be used
Connection Pooling
Problem – Mid-tier mult-threaded applications need
multiple connections to the database– Opening and closing connection each time is
very expensive– Opening all the necessary connections before
hand is wasteful
Solution– Maintain a pool of connections– Allocate/release a connection for execution– Connection Pool is dynamically configurable
Connection PoolingConnectionPool* createConnectionPool( const string &poolUserName, const string &poolPassword, const string &connectString ="", unsigned int minConn =0,unsigned int maxConn =1, unsigned int incrConn =1);
ConnectionPool* connPool = env->createConnectionPool (“scott”, “tiger”, 1, 5, 1);
void setPoolSize(unsigned int minConn =1, unsigned int maxConn =1, unsigned int incrConn =1);
connPool->setPoolSize(5, 20, 1);
Application Layer OCI Layer Databases
s1
s2
s3
s4
s5
t1
t2
t3
t4
t5
t6
Pool 1
Pool 2
db1
db2s6
c1
c2
c3
c4
Connection Poolingection Pooling
Agenda
Survey Customer Requirements Meeting the Needs
– Associative Relational Access– Objects Access– Metadata Access
Realizing the Benefits Summary Q & A
OCCI Object Features
Access database objects as C++ instances
Oracle Type Translator (OTT 9i) – map object types to C++ classes
client-side caching of C++ objects support all object OCI features
Accessing Objects
Navigational Interface– no SQL – navigate using the object references (REFs)– create/access/lock/delete/flush
Associative Interface – use SQL or PL/SQL– no cost of transporting data to client
Navigational Access
The OCCI navigational interface:– Allows access and modification of
object-relational data as C++ objects without using SQL
– Provides a mechanism to create, access, lock, delete and flush objects
– Accesses object references and navigate through them
Representing Objects
CREATE TYPE ADDRESS AS OBJECT ( state CHAR(2), zip CHAR(2));
class ADDRESS : public PObject {protected : string state; string zip;public : void *operator new(size_t size); // create a transient instance void *operator new(size_t size, Connection *conn,
string& table); // create a persistent instance}
Creating a Persistent ObjectCREATE TABLE ADDRESS_TAB OF ADDRESS;
ADDRESS *addr;addr = new (conn, “ADDRESS_TAB”)
ADDRESS(“CA”, “94002”);
Fetching an Object Reference Object Reference
– logical pointer to an object instance– Ref<T>
ResultSet *rs = stmt->executeQuery( “SELECT REF(address) FROM ADDRESS_TAB address where zip = ‘94065’ “);rs->next();Ref<ADDRESS> addr_ref = rs->getRef(1);
Pinning an Object
string ADDRESS::getState() { return state;}
string state = addr_ref->getState();
Ref<T>::operator ->– overloaded– pins the object instance during the first
time
Client-side Object Cache
REF
Client side cache Server buffer cache
Pin
Network
flush
load
Modifying an Object
void ADDRESS::setState(string new_state) { state = new_state;}
addr_ref->setState(“PA”);
addr_ref->mark_modified(); // mark object as dirty
Flushing Changes to Server PObject::flush
– flush the dirty objectExample: addr->flush();
Connection::commit– commit the transaction– flush all the dirty objects
Complex Object Retrieval (COR) Object-oriented application has a set of graph- or tree-structured objects
COR prefetches multiple objects in one network round trip to improve performance
– The desired root object is explicitly fetched – The depth level is the minimum number of
references to be traversed from the root to an object
– Constrained by available memory in the object cache
Invoking COR
COR is invoked by setting attributes of Ref<T> before de-referencing
– prefetch attributes of the specified type name up to the the specified depthRef<T>::setPrefetch(const string &typeName,
unsigned int depth);– prefetch all the attribute types up to the
specified depthRef<T>::setPrefetch(unsigned int depth);
OTT for Type Inheritance Generates classes from inheritance hierarchy
class <typename> : public <parentTypename> {protected: <OCCItype1> <attributename1>; ...public: void *operator new(size_t size); // transient object void *operator new(size_t size, const Session* sess, const string& table); string getSQLTypeName(size_t size); // persistent object ... virtual void readSQL(AnyData& stream); virtual void writeSQL(AnyData& stream);}
Collections
Collection represented as Vector
CREATE TYPE ADDR_LIST AS VARRAY(5) OF REF ADDRESS;CREATE TYPE PERSON AS OBJECT(name VARCHAR2(20),
addr_list ADDR_LIST);
class PERSON : public PObject { protected :
string name; vector<Ref<ADDRESS> > addr_list;…}
Associative Object AccessResultSet *rs = stmt->executeQuery(
“SELECT VALUE(address) from ADDRESS_TAB address”);
while (rs->next()){ ADDRESS *addr_val = rs->getObject(1); cout << “state : “ << addr_val->getState();}
Example :- (OTT code)
class PERSON : public PObject { protected :
string name; vector<Ref<ADDRESS> > addr_list;…}void RegisterMappings(Environment *env) { Map *map = env->getMap();
map->put(“SCOTT.ADDRESS”,
ADDRESS::readSQL, ADDRESS::writeSQL); map->put(“SCOTT.PERSON”,
PERSON::readSQL, PERSON::writeSQL);
}
Example :- (user class def. )// ADDRESS, PERSON : OTT generated classesclass MyAddress : public ADDRESS { public: MyAddress(string state_i, string zip_i); void displayInfo();}class MyPerson : public PERSON { public: MyPerson(string name, Ref<MyAddress>& addr); void move(const Ref<MyAddress>& new_addr); void displayInfo();}
Example (user class methods)void MyAddress::displayInfo() { cout << "STATE is" << state << endl; cout << "ZIP is" << zip << endl;}void MyPerson::displayInfo() { cout << "NAME is" << name << endl; cout << "Address List: " << endl; for (int i = 0; i < addr_list.size(); i++) // operator [] on vector, operator -> on vector
element, REF addr_list[i]->displayInfo(); }
Example (contd.)
void MyPerson::move(const Ref<MyAddress>& new_addr)
{ addr_list.push_back(new_addr); this->mark_modified(); // mark the object as dirty}
Example (contd.)
int main() { Environment *env = Environment::createEnvironment(); Connection *conn = env->createConnection("scott",
"tiger"); /* Call the OTT generated function to register the
mappings */ RegisterMappings(env);
/* create a persistent object of type ADDRESS */ MyAddress *addr = new(conn, "ADDR_TAB")
MyAddress("CA", "94065");
Example (contd.)
/* create a persistent object of type Person */
MyPerson *person = new(conn, "PERSON_TAB")
MyPerson(“Joe”, addr->getRef());
conn->commit(); // flush newly created objects to server
Statement *stmt = conn->createStatement();
ResultSet *rs = stmt->executeQuery("SELECT REF(Person) from person_tab where name = ‘Bill’ ");
Ref<MyPerson> bill_ref = (Ref<MyPerson>)
rs.getRef(1);
Example (contd.)
// create a new address objectMyAddress *new_addr = new(conn, "ADDR_TAB")
MyAddress("PA", "92140"); // note : object is marked dirty in move()bill_ref->move(new_addr->getRef());
// display the contents of the PERSON objectbill_ref->displayInfo();
conn->commit(); // flush the dirty object
Example (contd.)
// delete the objects from the object cache delete addr; delete person; delete new_addr; conn->closeStatement(stmt); env->terminateConnection(conn); Environment::terminateEnvironment(env); return 0; }
Agenda
Survey Customer Requirements Meeting the Needs
– Associative Relational Access– Objects Access– Metadata Access
Realizing the Benefits Summary Q & A
Metadata
MetaData type_md;
// describe a user defined typetype_md = conn->getMetaData(“ADDRESS”);
// get number of type attributesunsigned int num_attrs = type_md.getInt(ATTR_NUM_TYPE_ATTRS);
Metadata (contd.)
// describe each attribute of the typevector<MetaData> attr_list = type_md.getVector(ATTR_LIST_TYPE_ATTRS);
for (int I = 0; I < attr_list.length(); I++){ MetaData attr_md = attr_list[I];
cout << “Attribute “ << I+1 << “ is “ << attr_md.getString(ATTR_TYPE_NAME) << endl;
}
Agenda
Survey Customer Requirements Meeting the Needs Realizing the Benefits Summary Q & A
Partners and Customers
Major GIS cartridge partners– High performance N-tiered object-relational
data access
A major Telecom partner– High performance N-tiered Oracle database
access
A major research institution– Enormous and complex Oracle database access
Many others…– High performance application mid-tier servers
Agenda
Survey Customer Requirements Meeting the Needs Realizing the Benefits Summary Q & A
Summary
OCCI (Oracle C++ Call Interface)– Simple and easy– High-performance and Scalable API– Comprehensive support of Oracle Database features– Ideal choice for high performance application mid-tier
implementation
Packaging
Oracle Programmer component Both Client and Database Server CD Static and shared library
– libocci9.a
Header files– public/occi.h, etc.
Demos and makefiles– demos/occi.mk
PlatformPlatform O/S O/S C++ C++ CompilerCompiler
Solaris SparcSolaris Sparc 2.62.6 Forte C++ Forte C++ 6.16.1
Solaris 64Solaris 64 2.8 2.8 Forte C++ Forte C++ 6.16.1
HP-UX 64HP-UX 64 11.0 11.0 aC++ aC++ A.03.25A.03.25
IBM AIX 64IBM AIX 64 4.3.3 4.3.3 VA C++ 5.0VA C++ 5.0
LinuxLinux kernel 2.4 kernel 2.4 GNU GCC GNU GCC 2.95.22.95.2
NT NT 4.0 4.0 VC++ 5 & 6VC++ 5 & 6
Tru64Tru64 5.0A 5.0A Compaq C++ Compaq C++ 6.36.3
PlatformPlatform O/S O/S C++ C++ CompilerCompiler
Solaris SparcSolaris Sparc 2.62.6 Forte C++ Forte C++ 6.16.1
Solaris 64Solaris 64 2.8 2.8 Forte C++ Forte C++ 6.16.1
HP-UX 64HP-UX 64 11.0 11.0 aC++ aC++ A.03.25A.03.25
IBM AIX 64IBM AIX 64 4.3.3 4.3.3 VA C++ 5.0VA C++ 5.0
LinuxLinux kernel 2.4 kernel 2.4 GNU GCC GNU GCC 2.95.22.95.2
NT NT 4.0 4.0 VC++ 5 & 6VC++ 5 & 6
Tru64Tru64 5.0A 5.0A Compaq C++ Compaq C++ 6.36.3
Platforms and Compilers
For Further Information . . . Oracle Technology Network
– otn.oracle.com
– Discussion forums Oracle C++ Call Interface
Oracle Technology Network
Complete technical resource for Internet developers
Online technical discussion forum Sample downloads & live demos Whitepapers, technical information,
documentation
http://otn.oracle.com
AQ&Q U E S T I O N SQ U E S T I O N SA N S W E R SA N S W E R S