PostgreSQLProtocol.h



Discussion



ŠP3 Consulting, 2003 All Rights Reserved

This is a Cocoa-wrapper around the libcpg functions for connecting to a PostgreSQL database.

As some of you will notice most of the following API is designed to be - as far as possible - source code compatible with OpenBase Basic API.
This is due to the simple fact that I also used OpenBase and want to migrate as easely as possible some of my own code to PostgreSQL.
In order to support uniqueRowIdForTable functionnality of OpenBase, you have to had a
_rowid BIGSERIAL NOT NULL UNIQUE PRIMARY KEY
field to every table you plan to use with uniqueRowIdForTable.

Differences with OpenBase API: markRow and removeMarkOnRow are not implemented -
LOCKING strategy is not impemented that way in PostgreSQL please refer to PostgreSQL doc and use executeCommand to achieve desired functionality

databaseEncodingName is not implemented

notification mechanism is different
we use LISTEN (and UNLISTEN to disable a notification) to register a PgSQLListener object that will be called by an NSTimer at a user specified interval, if a PostgreSQL notification is detected at that time, the pgSQLNotify method (defined in PgSQLListener protocol) of a user specified object will be called.

large object support has different - but close - API
- Oid are used instead of char[] to hold large object reference
- more functionnality is available including reading and writing part of large object.

****************** DEMO WARNING ******************
demonstration version limited to:
no more than 50 records are returned from any query
methods affected are
nextRow: returns false when 50th record is reached
afterLastRow: position cursor on 50th record
resultAsDictionary: only the first 50 rows are returned


Be careful: rowsAffected method returns the REAL result count from the query


Methods not implemented:
beginTransaction, endTransaction, rollbackTransaction
****************** END DEMO WARNING ******************

PostgreSQL limitation:
resultTableName is not implemented (returns "NOT_SUPPORTED_BY_POSTGRESQL")
I don't have found yet a way to returns the name of the originating table of a query's resulting column


Methods

afterLastRow

- (void)afterLastRow; 


asyncResultAvailable

Abstract: use to check if an asynchronous query has returned results yet.
- (BOOL)asyncResultAvailable; 

Result: YES if data is available ([conn nextRow] will not block).

backendPID

Abstract: returns backend process id of the database server.
- (int)backendPID; 

Result: backend process id.

beginTransaction

Abstract: self explanatory
- (BOOL)beginTransaction; 

DOES NOTHING (and returns YES) IN DEMO VERSION.

Result: YES if successful

bindBIT

- (void)bindBIT:(BOOLARRAY *)var; 

var should point on 6 bytes memory area


bindBIT

- (void)bindBIT:(BOOLARRAY *)var column:(int)col; 

var should point on 6 bytes memory area


bindBinary

- (void)bindBinary:(Oid *)var column:(int)col; 


bindBinary

- (void)bindBinary:(Oid *)var; 


bindBinaryString

- (void)bindBinaryString:(BSTRING *)var; 


bindBinaryString

- (void)bindBinaryString:(BSTRING *)var column:(int)col; 


bindBoolean

- (void)bindBoolean:(BOOL *)var column:(int)col; 


bindBoolean

- (void)bindBoolean:(BOOL *)var; 

Y,y,t,T,1 are converted to YES, any other character to NO


bindBox

- (void)bindBox:(BOX *)var; 


bindBox

- (void)bindBox:(BOX *)var column:(int)col; 


bindCIdr

- (void)bindCIdr:(unsigned char *)var column:(int)col; 

var should point on 12 bytes memory area


bindCIdr

- (void)bindCIdr:(unsigned char *)var; 

var should point on 12 bytes memory area


bindChar

- (void)bindChar:(char *)var; 


bindChar

- (void)bindChar:(char *)var column:(int)col; 


bindCircle

- (void)bindCircle:(CIRCLE *)var column:(int)col; 


bindCircle

- (void)bindCircle:(CIRCLE *)var; 


bindDouble

Abstract: bindDouble binds the double variable var to the next result column.
- (void)bindDouble:(double *)var; 


bindDouble

Abstract: bindDouble binds the double variable var to the specific column col. (column count starts at 0)
- (void)bindDouble:(double *)var column:(int)col; 

In case you skip columns in binding, they will be binded internally to a dummy item in order to avoid crashes or erroneous behavior.


bindFloat

- (void)bindFloat:(float *)var; 


bindFloat

- (void)bindFloat:(float *)var column:(int)col; 


bindInet

- (void)bindInet:(unsigned char *)var; 

var should point on 12 bytes memory area


bindInet

- (void)bindInet:(unsigned char *)var column:(int)col; 

var should point on 12 bytes memory area


bindInteger

- (void)bindInteger:(int *)var; 


bindInteger

- (void)bindInteger:(int *)var column:(int)col; 


bindLSeg

- (void)bindLSeg:(LSEG *)var; 

*var should be deallocated by free(*var) to avoid memory leaks


bindLSeg

- (void)bindLSeg:(LSEG *)var column:(int)col; 


bindLine

- (void)bindLine:(LINE *)var column:(int)col; 


bindLine

- (void)bindLine:(LINE *)var; 

*var should be deallocated by free(*var) to avoid memory leaks


bindLong

- (void)bindLong:(long *)var; 


bindLong

- (void)bindLong:(long *)var column:(int)col; 


bindLongLong

- (void)bindLongLong:(long long *)var; 


bindLongLong

- (void)bindLongLong:(long long *)var column:(int)col; 


bindMACaddr

- (void)bindMACaddr:(unsigned char *)var; 

var should point on 6 bytes memory area


bindMACaddr

- (void)bindMACaddr:(unsigned char *)var column:(int)col; 

var should point on 6 bytes memory area


bindPath

- (void)bindPath:(PATH **)var column:(int)col; 


bindPath

- (void)bindPath:(PATH **)var; 


bindPoint

- (void)bindPoint:(POINT *)var; 

*var should be deallocated by free(*var) to avoid memeory leaks


bindPoint

- (void)bindPoint:(POINT *)var column:(int)col; 


bindPolygon

- (void)bindPolygon:(POLYGON **)var column:(int)col; 


bindPolygon

- (void)bindPolygon:(POLYGON **)var; 


bindShort

- (void)bindShort:(short *)var; 


bindShort

- (void)bindShort:(short *)var column:(int)col; 


bindString

- (void)bindString:(char *)var; 


bindString

- (void)bindString:(char *)var column:(int)col; 


bindText

- (void)bindText:(TEXT *)var; 


bindText

- (void)bindText:(TEXT *)var column:(int)col; 


bufferHasCommands

- (BOOL)bufferHasCommands; 

Result: YES if command buffer contains not yet executed string.

cancelRequest

- (BOOL)cancelRequest; 


clearCommands

Abstract: clears the command buffer
- (void)clearCommands; 


clientEncoding

- (int)clientEncoding; 

Result: client encoding id.

closeCursor

Abstract: close the cursor opened with executeCommandWithCursor
- (BOOL)closeCursor:(const char *)cursorName; 

Parameters

NameDescription
cursorName
Result: YES if successful.

commandBuffer

- (const char *)commandBuffer; 

Result: pointer on command buffer

connectAskingUser

Abstract: present a dialog to let the user fill in fields to connect to a databse.
- (BOOL)connectAskingUser:(int *)returnCode; 

Parameters

NameDescription
pointeran integer buffer o hold result code from backend.
Result: YES if connection successfull, NO otherwise.

connectErrorMessage

- (const char *)connectErrorMessage:(int)errorCode; 

Parameters

NameDescription
errorCodeto be converted into string.
Result: PQresStatus(errorCode)

connectToDatabase

Abstract: specify parameters to start PostgreSQL database connection
- (BOOL)connectToDatabase:(const char *)dbName onHost:(const char *)hostName login:(const char *)loginName password:(const char *)password return:(int *)returnCode; 

The wrapper is disconnected from any opened database before establishing a new one.
Passing nil or empty string to any of the parameters will fail.
Use (BOOL)connectToDatabase:(const char *)connectInfo return:(int *)returnCode if you need to pass different arguments like options or tty or if you want to use less arguments and let PostgreSQL use default ones.

Parameters

NameDescription
dbNamedatabasename as defined in PostgreSQL.
hostNamenetwork name of host computer
loginNameuser name for login
passworduser password for login
returnCodewhere to return int result code for connection
Result: YES if connection successful No otherwise

connectToDatabase

Abstract: specify parameters string to start PostgreSQL database connection. See PostgreSQL doc for more details on param string.
- (BOOL)connectToDatabase:(const char *)connectInfo return:(int *)returnCode; 

Parameters

NameDescription
connectInfocharacter buffer holding the conenction string to be used.
returnpointer an integer buffer o hold result code from backend.
Result: YES if connection successfull, NO otherwise.

databaseName

Abstract: returns database name of the connection.
- (const char *)databaseName; 

Result: pointer on database name string buffer.

delegate

- (id)delegate; 


disconnect

Abstract: disconnect cuurently opened connection.
- (void)disconnect; 

Not strictly necessary in the API since connectTodatabase disconnects automatically from any previously opened connection.


endTransaction

Abstract: self explanatory
- (BOOL)endTransaction; 

DOES NOTHING (and returns YES) IN DEMO VERSION.

Result: YES if successful

escapeBinary

- (NSData *)escapeBinary:(const unsigned char *)inSource length:(size_t)len; 

Result: nil if out of memory
autorelase NSData containing the escaped original

escapeString

- (NSString *)escapeString:(const char *)inSource; 

Result: nil if out of memory
autorelase NSString containing the escaped original

executeAsyncCommand

Abstract: pass the current command buffer to the PostgreSQL server for asynchronous execution
- (BOOL)executeAsyncCommand; 

Result: YES if successful

executeAsyncCommandWithCursor

Abstract: pass the current command buffer to the PostgreSQL server for asynchronous execution inside a cursor declaration
- (BOOL)executeAsyncCommandWithCursor:(const char *)cursorName binary:(BOOL)binary; 

Parameters

NameDescription
cursorNamethe name of the cursor
binaryif cursor should be declared BINARY
Result: YES if successful

executeCommand

Abstract: pass the current command buffer to the PostgreSQL server for execution
- (BOOL)executeCommand; 

Result: YES if successful

executeCommandWithCursor

Abstract: pass the current command buffer to the PostgreSQL server for execution inside a cursor declaration
- (BOOL)executeCommandWithCursor:(const char *)cursorName binary:(BOOL)binary; 

Parameters

NameDescription
cursorNamethe name of the cursor
binaryif cursor should be declared BINARY
Result: YES if successful

exportBinaryToFile

Abstract: Export the BLOB to the file system.
- (int)exportBinaryToFile:(Oid)inOid pathName:(const char *)inPathName; 

Result: the lo_export returned code.

frameworkVersion

Abstract: returns version of the framework.
- (NSString *)frameworkVersion; 

Result: NSString describing the framework version.

getPGconn

Abstract: returns pointer on PGconn record.
- (PGconn *)getPGconn; 

ALWAYS returns NIL in DEMO version. See PostgreSQL for advanced use.
You should never close yourselve a connection by calling PQfinish([pgconn getPGconn]).

Result: pointer on PGconn record.

hostName

Abstract: returns host name of the connection.
- (const char *)hostName; 

Result: pointer on host name string buffer.

importBinaryFromFile

Abstract: insert a BLOB made from a file specified with its pathname.
- (Oid)importBinaryFromFile:(const char *)inPathName; 

Result: the Oid of the created BLOB, 0 if an error occurred.

insertBinary

Abstract: insert a BLOB made from a memory buffer.
- (Oid)insertBinary:(unsigned char *)inData size:(int)size; 

Parameters

NameDescription
inDatapointer on the memory buffer
sizeof the memory buffer
Result: the Oid of the created BLOB, 0 if an error occurred.

insertBinaryFromData

Abstract: insert a BLOB made from NSData
- (Oid)insertBinaryFromData:(NSData *)inData; 

Result: the Oid of the created BLOB, 0 if an error occurred.

insertBinaryFromFile

Abstract: insert a BLOB made from NSFileHandle
- (Oid)insertBinaryFromFile:(NSFileHandle *)inFile; 

Parameters

NameDescription
theNSFileHandle on the file.
Result: the Oid of the created BLOB, 0 if an error occurred.

isColumnNULL

- (BOOL)isColumnNULL:(int)fieldIndex; 

Result: YES if column at fieldIndex is NULL

loginName

Abstract: returns user name of the connection.
- (const char *)loginName; 

Result: pointer on user name string buffer.

makeCommand

Abstract: concat cmd to current command buffer
- (void)makeCommand:(char *)cmd; 

makeCommand family methods don't escape automatically their arguments
Use escapeString if you need to.


makeCommandf

Abstract: same as makeCommand but with a format and variable arguments list (printf-like)
- (void)makeCommandf:(const char *)format, ...; 


nextRow

- (BOOL)nextRow; 


options

Abstract: returns options of the connection.
- (const char *)options; 

Result: pointer on options string buffer.

overWriteBinaryWithDataFromStart

Abstract: overwrite part a of BLOB with bytes from a NSData object from a specified start point.
- (BOOL)overWriteBinaryWithDataFromStart:(Oid)inOid data:(NSData *)inData start:(int)inStart; 

Result: YES if successful (number of bytes written == size of NSData buffer).

password

Abstract: returns password of the connection.
- (const char *)password; 

Result: pointer on password string buffer.

port

Abstract: returns port of the connection.
- (const char *)port; 

Result: pointer on port string buffer.

postgreSQLVersion

Abstract: returns version of the running postmaster.
- (NSString *)postgreSQLVersion; 

returns reulst of executing the SELECT version() query.

Result: NSString containing the postgreSQL version.

previousRow

- (BOOL)previousRow; 


removeNotificationFor

- (void)removeNotificationFor:(PgSQLListener *)listener; 


resultAsDictionary

Abstract: returns a dictionnary [autorelease] build from result of last query
- (NSDictionary *)resultAsDictionary; 


resultAsDictionnary returns a dictionary structured as follows

<dict>
<key>columns/key>
<array>
<dict>
<key>name</key>
<string>columnTitle</string>
<key>typeName</key>
<string>columnTypeName</string>
<key>typeOid</key>
<integer>columnTypeOid</integer>
</dict>
...


</array> <key>fields/key> <array> <string>columnFieldValue</string> ...

</array>
Since PostgreSQL allows creation of new types, we don't provide yet an automatic conversion from the PostgreSQL type to the plist one.

NB
resultAsDictionary preserves the curRowIndex used by nextRow and previousRow methods
This means it can be used inside a
while ([psql nextRow]) {
...
}

loop as a debugging tool (for example if an error condition occurs dump the result as a dict in a file) without changing the behavior of the loop.


resultColumnCount

- (int)resultColumnCount; 

Result: the number of columns of latest executed command.

resultColumnName

- (const char *)resultColumnName:(int)col; 

Result: the name of the column at index col.

resultColumnType

- (Oid)resultColumnType:(int)col; 

Result: the type oid of the column at index col.

resultColumnTypeName

- (const char *)resultColumnTypeName:(int)col; 

Result: the name of the type of the column at index col.

resultReturned

- (BOOL)resultReturned; 

Result: YES if latest command executed returns rows.

resultTableName

Abstract: should return the name of the table of the column at index col in latest result.
Not yet supported byPostgreSQL.
- (const char *)resultTableName:(int)col; 

Result: "NOT_SUPPORTED_BY_POSTGRESQL"

retrieveBinary

Abstract: retrieve a BLOB into an newly created NSData object (autorelease)
- (NSData *)retrieveBinary:(Oid)inOid; 

Parameters

NameDescription
theOid of the BLOB to be retrieved.
Result: NSData object or nil.

retrieveBinaryFromStartLength

Abstract: retrieve part of a BLOB into an newly created NSData object (autorelease)
- (NSData *)retrieveBinaryFromStartLength:(Oid)inOid start:(int)inStart length:(int)length; 

Parameters

NameDescription
theOid of the BLOB to be retrieved.
startposition from which to retrieve data
lengthnumber of bytes to retrieve.
Result: NSData object or nil.

rollbackTransaction

Abstract: self explanatory
- (BOOL)rollbackTransaction; 

DOES NOTHING (and returns YES) IN DEMO VERSION.

Result: YES if successful

rowsAffected

- (int)rowsAffected; 


serverMessage

- (const char *)serverMessage; 

Result: PQerrorMessage()

setClientEncoding

- (int)setClientEncoding:(const char *)encoding; 

Parameters

NameDescription
encodingname

setDebug

Abstract: turns on|off global debugging.
+ (void)setDebug:(BOOL)yn; 

Newly allocated PostgreSQL objects have their instance debug flag set the the global one.

Parameters

NameDescription
ynas you expect.

setDebugMode

Abstract: turns on|off instance debugging.
- (void)setDebugMode:(BOOL)turnOn; 

Parameters

NameDescription
turnOnas you expect.

setDelegate

- (void)setDelegate:(id)newDelegate; 


socket

Abstract: returns socket of the database server.
- (int)socket; 

Result: socket number.

startNotificationFor

- (PgSQLListener *)startNotificationFor:(const char *)inTableName delegate:(id)notificatonDelegate userInfo:(id)userInfo; 


startTracing

Abstract: start tracing to file traceFileName.
- (BOOL)startTracing:(const char *)traceFileName; 

Parameters

NameDescription
traceFileNamefull path name of file to dump tracing information.
Result: YES if successfull

stopTracing

Abstract: turns off tracing.
- (void)stopTracing; 


transactionInProgress

Abstract: self explanatory
- (BOOL)transactionInProgress; 

Result: YES if a transaction is in progress (beginTransaction has been called)

tty

Abstract: returns tty of the connection.
- (const char *)tty; 

Result: pointer on tty string buffer.

unescapeBinary

- (NSData *)unescapeBinary:(const unsigned char *)inSource length:(size_t)len; 

supported in 7.3

Result: nil if out of memory
autorelase NSData containing the unescaped original

uniqueID

Abstract: if you need to insert the PostgreSQL object in a NSDictionary,
this is a convenience method that is guaranted to return a unique string usable as key object. Uniqueness is guaranted for the lifetime of the program duration.
- (NSString *)uniqueID; 

Result: unique id string.

uniqueRowIdForTable

Abstract: uniqueRowIdForTable: requires you have a
_rowid bigserial NOT NULL PRIMARY KEY
field in the table
- (const char *)uniqueRowIdForTable:(const char *)tableName; 

Result: the column value as a string.

uniqueRowIdForTable

Abstract: let you specify the column name to be used for generating the unqiue "rowid".
Next rowid is generated by executing the following SQL statement:
SELECT max(colName)+1 FROM tableName
- (const char *)uniqueRowIdForTable:(const char *)tableName column:(const char *)colName; 

Result: the column value as a string.

unlinkBinary

Abstract: delete a large object
- (int)unlinkBinary:(Oid)inOid; 

Result: result code from lo_unlink

Constants

PgSQLColumnsKeyField

NSString *PgSQLColumnsKeyField ;

key for columns array


PgSQLNameKeyField key for column's name field (string)

NSString *PgSQLNameKeyField  ;


PgSQLRowsKeyField key for fields array

NSString *PgSQLRowsKeyField ;


PgSQLTypeKeyField key for column's type field (integer)

NSString *PgSQLTypeKeyField  ;


PgSQLTypeNameKeyField key for column's type field (integer)

NSString *PgSQLTypeNameKeyField ;


PgSQLconditionNotificationField

NSString *PgSQLconditionNotificationField ;


PgSQLconnectionNotificationField

NSString *PgSQLconnectionNotificationField ;


PgSQLuserInfoNotificationField

NSString *PgSQLuserInfoNotificationField ;


PostgreSQLNotification

NSString *PostgreSQLNotification ;


PostgreSQLResultAvailable

NSString *PostgreSQLResultAvailable ;


(Last Updated 12/27/2002)