Authors
- Richard Frith-Macdonald (
rfm@gnu.org
)
-
Version: 22982
Date: 2006-05-25 12:34:03 +0100 (Thu, 25 May 2006)
Copyright: (C) 2004 Free Software Foundation, Inc.
The SQLClient library is designed to provide a simple
interface to SQL databases for GNUstep
applications. It does not attempt the sort of
abstraction provided by the much more
sophisticated GDL2 library, but rather allows
applications to directly execute SQL queries and
statements.
SQLClient provides for the Objective-C programmer
much the same thing that JDBC provides for the Java
programmer (though SQLClient is a bit faster,
easier to use, and easier to add new database backends
for than JDBC).
The major features of the SQLClient library are -
-
Simple API for executing queries and statements... a
variable length sequence of comma separated
strings and other objects (NSNumber, NSDate,
NSData) are concatenated into a single SQL
statement and executed.
-
Simple API
SQLTransaction
)for combining multiple SQL statements into a single
transaction which can be used to minimise
client-server interactions to get the best
possible performance from your database.
-
Supports multiple sumultaneous named connections
to a database server in a thread-safe manner.
-
Supports multiple simultaneous connections to
different database servers with backend driver
bundles loaded for different database engines.
Clear, simple subclassing of the abstract base
class to enable easy implementation of new backend
bundles.
-
Configuration for all connections held in
one place and referenced by connection name for ease
of configuration control. Changes via NSUserDefaults
can even allow reconfiguration of client instances
within a running application.
-
Thread safe operation... The base class supports
locking such that a single instance can be shared
between multiple threads.
-
Support for standalone web applications... eg to
allow data to be added to the database by people
posting web forms to the application.
Current backend bundles are -
-
ECPG - a bundle using the embedded SQL interface for
postgres.
This is based on a similar
code which was in production use for over eighteen
months, so it should be reliable, but
inefficient.
-
Postgres - a bundle using the libpq native
interface for postgres.
This is the
preferred backend as it allows 'SELECT FOR
UPDATE', which the ECPG backend cannot support
due to limitations in the postgres implementation of
cursors. The code is now well tested and known
to be efficient.
-
MySQL - a bundle using the mysqlclient library for
*recent* MySQL.
I don't use MySQL... but
the test program ran successfully with a vanilla
install of the MySQL packages for recent Debian
unstable.
-
SQLite - a bundle using the sqlite3 library which
supports an SQL-like API for direct access to a
database file (rather than acting as a client of
a database server process).
Not as functional as
the other backends (doesn't support dates for
instance), but good enough for many purposes
and very 'lightweight'. See http://www.sqlite.org
-
Oracle - a bundle using embedded SQL for Oracle.
Completely untested... may even need some
work to compile... but this *is* based on code which
was working about a year ago.
No support for
BLOBs yet.
The SQLClient library is currently only available via
CVS from the GNUstep CVS repository.
See
<https://savannah.gnu.org/cvs/?group=gnustep>
You need to check out
gnustep/dev-libs/SQLClient
To build this library you must have a basic GNUstep
environment set up...
-
The gnustep-make package must have been built and
installed.
-
The gnustep-base package must have been built and
installed.
-
The Performance library (from the dev-libs area in
GNUstep CVS) must have been built and installed.
-
If this environment is in place, all you should need
to do is run 'make' to configure and build the
library, 'make install' to install it.
-
Then you can run the test programs.
-
Your most likely problems are that the configure
script may not detect the database libraries you
want... Please figure out how to modify
configure.ac
so that it will detect
the required headers and libraries on your system,
and supply na patch.
-
Once the library is installed, you can include the
header file
<SQLClient/SQLClient.h%gt;
and
link your programs with the SQLClient
library to use it.
Bug reports, patches, and contributions (eg a backend
bundle for a new database) should be entered on the
GNUstep project page
<http://savannah.gnu.org/projects/gnustep>
and the bug reporting page
<http://savannah.gnu.org/bugs/?group=gnustep>
- Declared in:
- SQLClient.h
The SQLClient class encapsulates dynamic SQL access to
relational database systems. A shared instance
of the class is used for each database (as identified by
the name of the database), and the number of
simultanous database connections is managed
too.
SQLClient is an abstract base class... when you
create an instance of it, you are actually creating
an instance of a concrete subclass whose implementation
is loaded from a bundle.
Instance Variables
Method summary
+ (NSArray*)
allClients;
Returns an array containing all the SQLClient
instances.
+ (
SQLClient*)
clientWithConfiguration: (NSDictionary*)config
name: (NSString*)reference;
Return an existing SQLClient instance (using
+existingClient:) if possible, or creates
one, initialises it using
-initWithConfiguration:name:
, and returns the new instance (autoreleased).
Returns
nil
on failure.
+ (
SQLClient*)
existingClient: (NSString*)reference;
Return an existing SQLClient instance for the
specified name if one exists, otherwise returns
nil
.
+ (unsigned int)
maxConnections;
Return the maximum number of simultaneous database
connections permitted (set by
+setMaxConnections:
and defaults to 8)
+ (void)
purgeConnections: (NSDate*)since;
Use this method to reduce the number of database
connections currently active so that it is
less than the limit set by the
+setMaxConnections:
method. This mechanism is used internally by the
class to ensure that, when it is about to open a
new connection, the limit is not exceeded.
If since is not nil
, then any
connection which has not been used more
recently than that date is disconnected anyway.
You can (and probably should) use this
periodically to purge idle connections, but
you can also pass a date in the future to close all
connections.
+ (void)
setMaxConnections: (unsigned int)c;
Set the maximum number of simultaneous database
connections permitted (defaults to 8 and may
not be set less than 1).
This value is used by the
+purgeConnections:
method to determine how many connections should be
disconnected when it is called.
- (void)
begin;
Start a transaction for this database client.
You
must match this with either a
-commit
or a
-rollback
.
Normally, if you execute an SQL statement
without using this method first, the
autocommit feature is employed, and the
statement takes effect immediately. Use of this
method permits you to execute several statements
in sequence, and only have them take effect (as a
single operation) when you call the
-commit
method.
NB. You must not execute an SQL
statement which would start a transaction
directly... use only this method.
Where possible, consider using the
SQLTransaction
class rather than calling -begin
-commit
or -rollback
yourself.
- (NSString*)
clientName;
Return the client name for this instance.
Normally this is useful only for
debugging/reporting purposes, but if
you are using multiple instances of this class in your
application, and you are using embedded SQL,
you will need to use this method to fetch the
client/connection name and store its
C-string representation in a variable
'connectionName' declared to the sql
preprocessor, so you can then have statements
of the form - 'exec sql at :connectionName...'.
- (void)
commit;
Complete a transaction for this database client.
This
must match an earlier
-begin
.
NB. You must not execute an SQL
statement which would commit or rollback a
transaction directly... use only this method
or the
-rollback
method.
Where possible, consider using the
SQLTransaction
class rather than calling -begin
-commit
or -rollback
yourself.
- (BOOL)
connect;
If the
connected instance variable is
NO
, this method calls
-backendConnect
to ensure that there is a connection to the database
server established. Returns the result.
Performs any necessary locking for thread safety.
- (BOOL)
connected;
Return a flag to say whether a connection to the
database server is currently live. This is mostly
useful for debug/reporting, but is used internally
to keep track of active connections.
- (NSString*)
database;
Return the database name for this instance (or
nil
).
- (void)
disconnect;
If the
connected instance variable is
YES
, this method calls
-backendDisconnect
to ensure that the connection to the database server is
dropped.
Performs any necessary locking for
thread safety.
- (void)
execute: (NSString*)stmt
,...;
Perform arbitrary operation
which does not return any value. This
arguments to this method are a
nil
terminated list which are concatenated in the
manner of the
-query:,...
method.
Any string arguments are assumed to
have been quoted appropriately already, but non-string
arguments are automatically quoted using the
-quote:
method.
[db execute: @"UPDATE ", table, @" SET Name = ",
myName, " WHERE ID = ", myId, nil];
- (void)
execute: (NSString*)stmt
with: (NSDictionary*)values;
Takes the statement and substitutes in
values from the dictionary where markup of
the format {key} is found.
Passes the result to
the
-execute:,...
method.
[db execute: @"UPDATE {Table} SET Name = {Name} WHERE ID = {ID}"
with: values];
Any non-string
values in the dictionary will
be replaced by the results of the
-quote:
method.
The markup format may also be
{key?default} where
default is a
string to be used if there is no value for the
key in the dictionary.
- (id)
initWithConfiguration: (NSDictionary*)config;
- (id)
initWithConfiguration: (NSDictionary*)config
name: (NSString*)reference;
Initialise using the supplied configuration, or
if that is nil
, try to use values from
NSUserDefaults (and automatically update
when the defaults change).
Uses the
reference name to determine configuration
information... and if a nil
name
is supplied, defaults to the value of SQLClientName in
the configuration dictionary (or in the standard user
defaults). If there is no value for
SQLClientName, uses the string 'Database'.
If a SQLClient instance already exists with
the name used for this instance, the receiver is
deallocated and the existing instance is
retained and returned... there may only ever be
one instance for a particular reference
name.
The config argument
(or the SQLClientReferences user default) is a
dictionary with names as keys and dictionaries
as its values. Configuration entries from the dictionary
corresponding to the database client are used
if possible, general entries are used otherwise.
Database... is the name of the database to use, if
it is missing then 'Database' may be used instead.
User... is the name of the database user to
use, if it is missing then 'User' may be used instead.
Password... is the name of the database user
password, if it is missing then 'Password' may be
used instead.
missing then 'Password' may be
used instead.
ServerType... is the name of the
backend server to be used... by convention the name
of a bundle containing the interface to that backend. If
this is missing then 'Postgres' is used.
- (BOOL)
isInTransaction;
Return the state of the flag indicating whether the
library thinks a transaction is in progress. This
flag is normally maintained by
-begin
,
-commit
, and
-rollback
.
- (NSDate*)
lastOperation;
Returns the date/time stamp of the last database
operation performed by the receiver, or
nil
if no operation has ever been done
by it.
Simply connecting to or disconnecting from
the databsse does not count as an operation.
- (NSString*)
name;
Return the database reference name for this instance
(or nil
).
- (NSString*)
password;
Return the database password for this instance (or
nil
).
- (NSMutableArray*)
query: (NSString*)stmt
,...;
Perform arbitrary query
which returns values.
This method has at least one argument, the string
starting the statement to be executed (which
must have the prefix 'select ').
Additional arguments are a nil
terminated list which also be strings, and
these are appended to the statement.
Any
string arguments are assumed to have been quoted
appropriately already, but non-string
arguments are automatically quoted using the
-quote:
method.
result = [db query: @"SELECT Name FROM ", table, nil];
Upon error, an exception is raised.
The query returns an array of records (each of which
is represented by an SQLRecord object).
Each SQLRecord object contains one or more fields,
in the order in which they occurred in the query.
Fields may also be retrieved by name.
NULL field items are returned as NSNull objects.
Most other field items are returned as NSString
objects.
Date and timestamp field items are returned as
NSDate objects.
- (NSMutableArray*)
query: (NSString*)stmt
with: (NSDictionary*)values;
Takes the query statement and substitutes in
values from the dictionary where markup of
the format {key} is found.
Passes the result to
the
-query:,...
method to execute.
result = [db query: @"SELECT Name FROM {Table} WHERE ID = {ID}"
with: values];
Any non-string
values in the dictionary will
be replaced by the results of the
-quote:
method.
The markup format may also be
{key?default} where
default is a
string to be used if there is no value for the
key in the dictionary.
- (NSString*)
quote: (id)obj;
Convert an object to a string suitable for use in
an SQL query.
Normally the
-execute:,...
, and
-query:,...
methods will call this method automatically for
everything apart from string objects.
Strings have to be handled specially, because they
are used both for parts of the SQL command, and as
values (where they need to be quoted). So where you
need to pass a string value which needs quoting, you
must call this method explicitly.
Subclasses
may override this method to provide appropriate quoting
for types of object which need database backend
specific quoting conventions. However, the defalt
implementation should be OK for most cases.
This method makes use of
-quoteString:
to quote literal strings.
The base class
implementation formats NSDate objects as
YYYY-MM-DD hh:mm:ss.mmm ?ZZZZ
NSData
objects are not quoted... they must not appear in
queries, and where used for insert/update
operations, they need to be passed to the
-backendExecute:
method unchanged.
For a
nil
object, we return NULL.
For a number, we
simply convert directly to a string.
For a
date, we convert to the text format used by the
database, and add leading and trailing quotes.
For a data object, we don't quote... the
other parts of the code need to know they have an
NSData object and pass it on unchanged to the
-backendExecute:
method.
Just in case an NSNull subclass has
been created by someone. The normal NSNull instance
should have been handled earlier.
For an
NSArray or NSSet, we produce a bracketed list of
the (quoted) objects in the array.
For any other
type of data, we just produce a quoted string
representation of the objects description.
- (NSString*)
quoteCString: (const char*)s;
Convert a 'C' string to a string suitable for use
in an SQL query by using
-quoteString:
to convert it to a literal string format.
NB. a
null pointer is treated as an empty string.
- (NSString*)
quoteChar: (char)c;
Convert a single character to a string suitable for
use in an SQL query by using
-quoteString:
to convert it to a literal string format.
NB. a
nul character is not allowed and will cause an
exception.
- (NSString*)
quoteFloat: (float)f;
Convert a float to a string
suitable for use in an SQL query.
- (NSString*)
quoteInteger: (int)i;
Convert an integer to a string suitable for use in
an SQL query.
- (NSString*)
quoteString: (NSString*)s;
Convert a string to a form suitable for use as a
string literal in an SQL query.
Subclasses
may override this for non-standard literal string
quoting conventions.
- (NSString*)
quotef: (NSString*)fmt
,...;
Produce a quoted string from the supplied arguments
(printf style).
- (void)
rollback;
Revert a transaction for this database client.
If there is no transaction in progress, this
method does nothing.
NB. You must not execute an SQL
statement which would commit or rollback a
transaction directly... use only this method
or the
-rollback
method.
Where possible, consider using the
SQLTransaction
class rather than calling -begin
-commit
or -rollback
yourself.
- (void)
setDatabase: (NSString*)s;
Set the database host/name for this object.
This
is called automatically to configure the connection...
you normally shouldn't need to call it yourself.
- (void)
setName: (NSString*)s;
Set the database reference name for this object. This
is used to differentiate between multiple connections to
the database.
This is called automatically to
configure the connection... you normally
shouldn't need to call it yourself.
NB.
attempts to change the name of an instance to that
of an existing instance are ignored.
- (void)
setPassword: (NSString*)s;
Set the database password for this object.
This
is called automatically to configure the connection...
you normally shouldn't need to call it yourself.
- (void)
setUser: (NSString*)s;
Set the database user for this object.
This is
called automatically to configure the connection...
you normally shouldn't need to call it yourself.
- (void)
simpleExecute: (NSArray*)info;
- (NSMutableArray*)
simpleQuery: (NSString*)stmt;
- (NSString*)
user;
Return the database user for this instance (or
nil
).
Instance Variables for SQLClient Class
@protected GSCache* _cache;
The cache for query results
Warning the
underscore at the start of the name of this
instance variable indicates that, even though it
is not technically private, it is intended for
internal use within the package, and you should
not use the variable in other code.
@protected NSString* _client;
Identifier within backend
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected NSString* _database;
The configured database name/host
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected unsigned int _debugging;
The current debugging level
Warning the
underscore at the start of the name of this
instance variable indicates that, even though it
is not technically private, it is intended for
internal use within the package, and you should
not use the variable in other code.
@protected NSTimeInterval _duration;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected BOOL _inTransaction;
A flag indicating whether this instance is currently
within a transaction. This variable must
only be set by the
-begin
,
-commit
or
-rollback
methods.
Are we inside a transaction?
Warning the underscore at the start
of the name of this instance variable indicates that,
even though it is not technically
private, it
is intended for internal use within the package, and you
should not use the variable in other code.
@protected NSTimeInterval _lastOperation;
Timestamp of last operation.
Maintained by
-simpleExecute:
-simpleQuery:
-cache:simpleQuery:
Warning the underscore at the start
of the name of this instance variable indicates that,
even though it is not technically
private, it
is intended for internal use within the package, and you
should not use the variable in other code.
@protected NSString* _name;
Unique identifier for instance
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected NSString* _password;
The configured password
Warning the
underscore at the start of the name of this
instance variable indicates that, even though it
is not technically private, it is intended for
internal use within the package, and you should
not use the variable in other code.
@protected NSMutableArray* _statements;
Uncommitted statements
Warning
the underscore at the start of the name of this
instance variable indicates that, even though it
is not technically private, it is intended for
internal use within the package, and you should
not use the variable in other code.
@protected NSString* _user;
The configured user
Warning the
underscore at the start of the name of this
instance variable indicates that, even though it
is not technically private, it is intended for
internal use within the package, and you should
not use the variable in other code.
@protected BOOL connected;
A flag indicating whether this instance is currently
connected to the backend database server. This
variable must
only be set by the
-backendConnect
or
-backendDisconnect
methods.
@protected void* extra;
For subclass specific data
@protected NSRecursiveLock* lock;
Maintain thread-safety
- Declared in:
- SQLClient.h
An enhanced array to represent a record returned from a
query. You should
NOT try to create instances
of this class except via the
+newWithValues:keys:count:
method.
Method summary
+ (id)
newWithValues: (id*)v
keys: (NSString**)k
count: (unsigned int)c;
Create a new SQLRecord containing the specified
fields.
NB. The values and keys are
retained by the record rather than being
copied.
A nil
value is
represented by [NSNull null].
Keys must
be unique string values (case insensitive comparison).
- (NSArray*)
allKeys;
Returns an array containing the names of all the
fields in the record.
- (NSMutableDictionary*)
dictionary;
Return the record as a mutable dictionary with the
keys as the record field names standardised to be
lowercase strings.
- (void)
getObjects: (id*)buf;
Optimised mechanism for retrieving all objects.
- (id)
objectForKey: (NSString*)key;
Returns the value of the named field.
The
field name is case insensitive.
- (void)
setObject: (id)anObject
forKey: (NSString*)aKey;
Replaces the value of the named field.
The
field name is case insensitive.
NB. You must
be careful not to change the contents of a record which
has been cached (unless you are sure you really want
to), as you will be changing the contents of the
cache, not just a private copy.
- (unsigned)
sizeInBytes: (NSMutableSet*)exclude;
Return approximate size of this record in bytes.
The exclude set is used to specify
objects to exclude from the calculation
(to prevent recursion etc).
- Declared in:
- SQLClient.h
The SQLTransaction transaction class provides a
convenient mechanism for grouping together a
series of SQL statements to be executed as a single
transaction. It avoids the need for handling
begin/commit, and should be as efficient as
reasonably possible.
You obtain an instance
by calling
[SQLClient -transaction]
, add SQL statements to it using the
-add:,...
and/or
-add:with:
methods, and then use the
-execute
method to perform all the statements as a single
operation.
Any exception is caught and
re-raised in the
-execute
method after any tidying up to leave the database in a
consistent state.
NB. This class is not in
itsself thread-safe, though the underlying database
operations should be. If you have multiple
threads, you should create multiple SQLTransaction
instances, at least one per thread.
Instance Variables
Method summary
- (void)
add: (NSString*)stmt
,...;
Adds an SQL statement to the transaction. This is
similar to
[SQLClient -execute:,...]
but does not cause any database operation until
-execute
is called, so it will not raise a database exception.
- (void)
add: (NSString*)stmt
with: (NSDictionary*)values;
Adds an SQL statement to the transaction. This is
similar to
[SQLClient -execute:with:]
but does not cause any database operation until
-execute
is called, so it will not raise a database exception.
- (void)
append: (
SQLTransaction*)other;
Appends all the statements from the
other transaction to the receiver.
This provides a convenient way of merging transactions
which have been built by different code modules, in
order to have them all executed together in a single
operation (for efficiency etc).
This does
not alter the other transaction, so if the
execution of a group of merged transactions
fails, it is then possible to attempt to commit the
individual transactions separately.
NB.
All transactions appended must be using the same
database connection (SQLClient instance).
- (unsigned)
count;
Returns the number of statements in this
transaction.
- (
SQLClient*)
db;
Returns the database client with which this
instance operates.
This client is retained
by the transaction.
- (void)
execute;
Performs any statements added to the transaction
as a single operation. If any problem occurs, an
NSException is raised, but the database
connection is left in a consistent state and a
partially completed operation is rolled back.
NB. If the database is not already in a transaction,
this implicitly calls the
-begin
method to start the transaction before executing
the statements.
The method always commits the
transaction, even if the transaction was
begun earlier rather than in
-execute
.
This behavior allows you to call
[SQLClient -begin]
, then run one or more queries, build up a transaction
based upon the query results, and then
-execute
that transaction, causing the entire process to be
commited as a single transaction.
- (void)
reset;
Resets the transaction, removing all previously
added statements. This allows the transaction object
to be re-used for multiple transactions.
Instance Variables for SQLTransaction Class
@protected unsigned int _count;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected SQLClient* _db;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
@protected NSMutableArray* _info;
Warning the underscore at the start of the
name of this instance variable indicates that, even
though it is not technically private, it is
intended for internal use within the package, and
you should not use the variable in other code.
- Declared in:
- SQLClient.h
This category porovides methods for caching the results
of queries in order to reduce the number of client-server
trips and the database load produced by an application
which needs update its information from the database
frequently.
Method summary
- (
GSCache*)
cache;
Returns the cache used by the receiver for storing
the results of requests made through it.
- (NSMutableArray*)
cache: (int)seconds
query: (NSString*)stmt
,...;
If the result of the query is already cached and is
still valid, return it. Otherwise, perform the query
and cache the result giving it the specified lifetime
in seconds.
If seconds is
negative, the query is performed irrespective of
whether it is already cached, and its absolute
value is used to set the lifetime of the results.
If seconds is zero, the cache for
this query is emptied.
- (NSMutableArray*)
cache: (int)seconds
query: (NSString*)stmt
with: (NSDictionary*)values;
If the result of the query is already cached and is
still valid, return it. Otherwise, perform the query
and cache the result giving it the specified lifetime
in seconds.
If seconds is
negative, the query is performed irrespective of
whether it is already cached, and its absolute
value is used to set the lifetime of the results.
If seconds is zero, the cache for
this query is emptied.
- (NSMutableArray*)
cache: (int)seconds
simpleQuery: (NSString*)stmt;
If the result of the query is already cached and is
still valid, return it. Otherwise, perform the query
and cache the result giving it the specified lifetime
in
seconds.
If
seconds is
negative, the query is performed irrespective of
whether it is already cached, and its absolute
value is used to set the lifetime of the results.
If
seconds is zero, the cache for
this query is emptied.
Handles locking.
Maintains
-lastOperation
date.
- (void)
setCache: (
GSCache*)aCache;
Sets the cache to be used by the receiver for storing
the results of requests made through it.
If
aCache is nil
, the current
cache is released, and a new cache will be
automatically created as soon as there is a
need to cache anything.
- Declared in:
- SQLClient.h
This category contains convenience methods including
those for frequently performed database operations...
message logging etc.
Method summary
- (
SQLRecord*)
queryRecord: (NSString*)stmt
,...;
Executes a query (like the
-query:,...
method) and checks the result (raising an exception
if the query did not contain a single record) and
returns the resulting record.
- (NSString*)
queryString: (NSString*)stmt
,...;
Executes a query (like the
-query:,...
method) and checks the result.
Raises an
exception if the query did not contain a single
record, or if the record did not contain a single
field.
Returns the resulting field as a
string.
- (void)
singletons: (NSMutableArray*)records;
Convenience method to deal with the results of
a query where each record contains a single field... it
converts the array of records returned
by the query to an array containing the fields.
- (
SQLTransaction*)
transaction;
Creates and returns an autoreleased SQLTransaction
instance which will use the receiver as the
database connection to perform transactions.
- Declared in:
- SQLClient.h
This category porovides basic methods for logging debug
information.
Method summary
+ (unsigned int)
debugging;
Return the class-wide debugging level, which is
inherited by all newly created instances.
+ (NSTimeInterval)
durationLogging;
Return the class-wide duration logging threshold,
which is inherited by all newly created instances.
+ (void)
setDebugging: (unsigned int)level;
+ (void)
setDurationLogging: (NSTimeInterval)threshold;
- (void)
debug: (NSString*)fmt
,...;
The default implementation calls NSLogv to log a debug
message.
Override this in a category to
provide more sophisticated logging.
- (unsigned int)
debugging;
Return the current debugging level.
A level
of zero (default) means that no debug output is
produced, except for that concerned with logging
the database transactions taking over a certain amount
of time (see the
-setDurationLogging:
method).
- (NSTimeInterval)
durationLogging;
Returns the threshold above which queries and
statements taking a long time
to execute are logged. A negative value (default)
indicates that this logging is disabled. A value
of zero means that all statements are logged.
- (void)
setDebugging: (unsigned int)level;
Set the debugging level of this instance...
overrides the default level inherited
from the class.
- (void)
setDurationLogging: (NSTimeInterval)threshold;
Set a threshold above which queries and
statements taking a long time
to execute are logged. A negative value (default)
disables this logging. A value of zero logs all
statements.
- Declared in:
- SQLClient.h
This category contains the methods which a subclass
must override to provide a working instance,
and helper methods for the backend implementations.
Application programmers should
not
call the backend methods directly.
When subclassing to produce a backend driver bundle,
please be aware that the subclass must NOT
introduce additional instance variables. Instead
the extra instance variable is provided for
use as a pointer to subclass specific data.
Method summary
- (BOOL)
backendConnect;
Subclasses
must override this method.
Attempts to establish a connection to the database
server.
Returns a flag to indicate whether
the connection has been established.
If a
connection was already established, returns
YES
and does nothing.
You should
not need to use this method normally, as it is called
for you automatically when necessary.
Subclasses must implement
this method to establish a connection to the
database server process (and initialise the
extra instance variable if necessary),
setting the connected instance variable
to indicate the state of the object.
This method must call
+purgeConnections:
to ensure that there is a free slot for the new
connection.
Application code must not call this
method directly, it is for internal use only. The
-connect
method calls this method if the connected
instance variable is NO
.
- (void)
backendDisconnect;
Subclasses
must override this method.
Disconnect from the database unless already
disconnected.
This method is called automatically when the
receiver is deallocated or reconfigured, and may
also be called automatically when there are too many
database connections active.
If the receiver is an instance of a subclass which
uses the extra instance variable, it
must clear that variable in the
-backendDisconnect
method, because a reconfiguration may cause the
class of the receiver to change.
This method must set the connected instance
variable to NO
.
Application code must not call this
method directly, it is for internal use only. The
-disconnect
method calls this method if the connected
instance variable is YES
.
- (void)
backendExecute: (NSArray*)info;
Subclasses
must override this method.
Perform arbitrary operation
which does not return any value. This
method has a single argument, an array containing
the string representing the statement to be executed as
its first object, and an optional sequence of data
objects following it.
[db backendExecute: [NSArray arrayWithObject:
@"UPDATE MyTable SET Name = 'The name' WHERE ID = 123"]];
The backend implementation is required to perform the
SQL statement using the supplied NSData objects at
the points in the statement marked by the
'?'''?'
sequence. The marker
saequences are inserted into the statement at
an earlier stage by the
-execute:,...
and
-execute:with:
methods.
This method should lock the instance using the
lock instance variable for the duration of
the operation, and unlock it afterwards.
NB. callers (other than the
-begin
, -commit
, and
-rollback
methods) should not pass any statement to this
method which would cause a transaction to begin or
end.
Application code must not call this
method directly, it is for internal use only.
- (NSMutableArray*)
backendQuery: (NSString*)stmt;
Subclasses
must override this method.
Perform arbitrary query
which returns values.
result = [db backendQuery: @"SELECT Name FROM Table"];
Upon error, an exception is raised.
The query returns an array of records (each of which
is represented by an SQLRecord object).
Each SQLRecord object contains one or more fields,
in the order in which they occurred in the query.
Fields may also be retrieved by name.
NULL field items are returned as NSNull objects.
This method should lock the instance using the
lock instance variable for the duration of
the operation, and unlock it afterwards.
Application code must not call this
method directly, it is for internal use only.
- (unsigned)
copyEscapedBLOB: (NSData*)blob
into: (void*)buf;
Subclasses
must override this method.
- (const void*)
insertBLOBs: (NSArray*)blobs
intoStatement: (const void*)statement
length: (unsigned)sLength
withMarker: (const void*)marker
length: (unsigned)mLength
giving: (unsigned*)result;
This method is a convenience method provided for
subclasses which need to insert escaped binary
data into an SQL statement before sending
the statement to a backend server process.
This method makes use of the
-copyEscapedBLOB:into:
and
-lengthOfEscapedBLOB:
methods, which must be implemented by
the subclass.
The blobs array is an array containing the
original SQL statement string (unused
by this method) followed by the data items to be
inserted.
The statement and sLength
arguments specify the datastream to be copied
and into which the BLOBs are to be inserted.
The marker and mLength
arguments specify the sequence of
marker bytes in the statement
which indicate a position for insertion of an
escaped BLOB.
The method returns either the original
statement or a copy containing the
escaped BLOBs. The length of the returned data is
stored in result.
- (unsigned)
lengthOfEscapedBLOB: (NSData*)blob;
Subclasses
must override this method.
NSString* SQLConnectionException;
Exception for when a connection to the server is
lost.
NSString* SQLEmptyException;
Exception for when a query is supposed to return
data and doesn't.
NSString* SQLException;
Exception raised when an error with the remote
database server occurs.
NSString* SQLUniqueException;
Exception for when an insert/update would break the
uniqueness of a field or index.
NSTimeInterval SQLClientTimeLast();
NSTimeInterval SQLClientTimeNow();
Convenience function to provide timing
information quickly.
This returns the
current date/time, and stores the value for use by
the
SQLClientTimeLast()
function.
NSTimeInterval SQLClientTimeStart();
This returns the timestamp from which any of the
SQLClient classes was first used or
SQLClientTimeNow()
was first called (whichever came first).
unsigned int SQLClientTimeTick();
A convenience method to return the current clock 'tick'...
which is the current second based on the time we
started. This does
not check the current
time, but relies on
SQLClientTimeLast()
returning an up to date value (so if you need an
accurate tick, you should ensure that
SQLClientTimeNow()
is called at least once a second).
The returned
value is always greater than zero, and is basically
calculated as (SQLClientTimeLast() -
SQLClientTimeStart()
+ 1).
In the event that the system clock is reset
into the past, the value of
SQLClientTimeStart()
is automatically adjusted to ensure that the result of a
call to
SQLClientTimeTick()
is never less than the result of any earlier call to the
function.