From: Michael Wallner Date: Wed, 24 Sep 2014 16:01:29 +0000 (+0200) Subject: pq\Connection X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=c9a53c31d87ef99b7a669cd98a756dc1c7762f57;p=mdref%2Fmdref-pq pq\Connection --- diff --git a/pq.md b/pq.md index 45d9faa..7abc9b1 100644 --- a/pq.md +++ b/pq.md @@ -2,7 +2,7 @@ ## About: -This is a modern binding to the mature [libpq, the official PostgreSQL C-client library](http://www.postgresql.org/docs/current/static/libpq.html). +This is a modern binding to the mature [libpq](http://www.postgresql.org/docs/current/static/libpq.html), the official PostgreSQL C-client library. ### Highlights: diff --git a/pq/Connection.md b/pq/Connection.md index 924e104..0bf2897 100644 --- a/pq/Connection.md +++ b/pq/Connection.md @@ -1,6 +1,6 @@ # class pq\Connection -A class representing a connection to the PostgreSQL server. +The connection to the PostgreSQL server. See the [General Usage](pq/Connection/: General Usage) page for an introduction on how to use this class. @@ -19,7 +19,7 @@ Broken connection; consider pq\Connection::reset() or recreation. * STARTED Waiting for connection to be made. * MADE -Connection OK; waiting to send. +Connection okay; waiting to send. * AWAITING_RESPONSE Waiting for a response from the server. * AUTH_OK @@ -71,21 +71,36 @@ Negotiating environment-driven parameter settings. Whether the connection is busy with [asynchronous operations](pq/Connection/: Asynchronous Usage). * public (readonly) $errorMessage Any error message on failure. +* public (readonly) $eventHandlers + List of registered event handlers. * public $encoding = NULL Connection character set. * public $unbuffered = FALSE - Whether to fetch results in unbuffered mode, i.e. each row generates a distinct pq\Result. + Whether to fetch [asynchronous](pq/Connection/: Asynchronous Usage) results in unbuffered mode, i.e. each row generates a distinct pq\Result. ### Connection Information: * public (readonly) $db -The database name of the connection. + The database name of the connection. * public (readonly) $user -The user name of the connection. + The user name of the connection. * public (readonly) $pass -The password of the connection. + The password of the connection. * public (readonly) $host -The server host name of the connection. + The server host name of the connection. * public (readonly) $port -The port of the connection. + The port of the connection. * public (readonly) $options -The command-line options passed in the connection request. + The command-line options passed in the connection request. + +### Inheritable Defaults: +* public $defaultFetchType = pq\Result::FETCH_ARRAY + Default fetch type for future pq\Result instances. +* public $defaultAutoConvert = pq\Result::CONV_ALL + Default conversion bitmask for future pq\Result instances. +* public $defaultTransactionIsolation = pq\Transaction::READ_COMMITTED + Default transaction isolation level for future pq\Transaction instances. +* public $defaultTransactionReadonly = FALSE + Default transaction readonlyness for futire pq\Transaction instances. +* public $defaultTransactionDeferrable = FALSE + Default transaction deferrability for future pq\Transaction instances. + diff --git a/pq/Connection/: Asynchronous Usage.md b/pq/Connection/: Asynchronous Usage.md new file mode 100644 index 0000000..b19779b --- /dev/null +++ b/pq/Connection/: Asynchronous Usage.md @@ -0,0 +1,104 @@ +# pq\Connection: Asynchronous Usage + +Whenever you start an asynchronous operation, you will have to probe pq\Connection::poll() to determine the current status of the operation. + +You can then use the ***public readonly*** property pq\Connection::$socket with ```stream_select()``` to wait for read/write-readiness. + +> ***NOTE:*** +You cannot use the connection for anything else while an asynchronous operation is active. + +## Connect or reset asynchronously: + +First, you can establish or reset a connection asynchronously. + +### Start asynchronous connect: + + + +### Start asynchronous reset: + + resetAsync(); + + ?> + +### Complete asynchronous operation: + +Keep in mind that you have to test for write-readiness once *before* starting the polling loop on connect/reset. + + socket); + $r = $e = null; + + if (stream_select($r, $w, $e, null)) { + + // loop until the connection is established + while (true) { + + switch ($c->poll()) { + + case pq\Connection::POLLING_READING: + // we should wait for the stream to be read-ready + $r = array($c->socket); + stream_select($r, $w, $e, NULL); + break; + + case pq\Connection::POLLING_WRITING: + // we should wait for the stream to be write-ready + $w = array($c->socket); + $r = $e = null; + stream_select($r, $w, $e, null); + break; + + case pq\Connection::POLLING_FAILED: + printf("Connection failed: %s\n", $c->errorMessage); + break 2; + + case pq\Connection::POLLING_OK: + printf("Connection completed\n"); + break 2; + } + } + + ?> + + +If you use an appropriate timeout in the ```stream_select()``` call and do something else at the end of the while loop, you probably got the idea... + +## Execute queries asynchronously: + + execAsync("SELECT 1+2+3; SELECT 2,3,4", function ($res) { + var_dump($res); + }); + + ?> + +The body of the while loop looks slightly different, when executing queries asynchronously, because you only have to wait for read-readiness. + +You can use the ***public readonly*** property pq\Connection::$busy to test if a call to pq\Connection::getResult() would block, and if so wait for read-readiness and then call pq\Connection::poll(). + + busy) { + $r = array($c->socket); + $w = $e = null; + if (stream_select($r, $w, $e, null)) { + $c->poll(); + } + } + } while ($c->getResult()); + + ?> + +If pq\Connection::getResult() returns NULL, there's nothing more in the pipeline. diff --git a/pq/Connection/: Executing Queries.md b/pq/Connection/: Executing Queries.md new file mode 100644 index 0000000..d603214 --- /dev/null +++ b/pq/Connection/: Executing Queries.md @@ -0,0 +1,57 @@ +# Executing queries + +ext/pq provides three means to execute queries against the PostgreSQL server: + +* pq\Connection::exec() + Simple plain execution of a query. +* pq\Connection::execParams() + Automatic prepare & execute of an unnamed statement. +* pq\Connection::prepare() and pq\Statement::exec() + Explicit prepare & execute of an named statement. + + +## Simple plain execution of a query + +pq\Connection::exec() accepts a single argument, a ***query string***, containing a single or multiple SQL queries, separated by semi-colon. + + exec("SELECT 1*s,2*s,3*s FROM generate_series(1,3) s"); + ?> + +An object of class pq\Result is returned on success. See [Fetching results](pq/: Fetching Results) for details. + +> ***NOTE:*** +> Only the last result will be returned, if the query string contains more than one SQL query. + + +## Automatic prepare & execute of an unnamed statement + +pq\Connection::execParams() accepts a ***query string*** with a single SQL query as first argument, which will be prepared as an unnamed statement. + +The second argument is an ***array of parameters*** to execute the prepared statement with. + +If the third argument is present, an ***array with pg_type OIDs***, those types will be used for the parameters. See [Using types](pq/: Using Types) for details. + + execParams("SELECT int($1) * s, int($2) * s, int($3) * s FROM generate_series(1,3) s", array(1,2,3)); + ?> + +An object of class pq\Result is returned on success. See [Fetching results](pq/: Fetching Results) for details. + + +## Explicit prepare & execute of a named statement + +pq\Connection::prepare() requires the ***statement name*** as string as first argument. This name is used later to refer to this prepared statement. See [Prepared statements](pq/: Prepared Statements) for details. + +The second argument is a ***query string*** containing a single SQL query, which will be prepared on the server. + +If the third argument is present, an ***array with pg_type OIDs***, those types will be used for the parameters. See [Using types](pq/: Using Types) for details. + + prepare("my_stm", "SELECT \$1::int*s,\$2::int*s,\$3::int*s FROM generate_series(1,3) s"); + $result = $statement->exec(array(1,2,3)); + + ?> + +An object of class pq\Statement will be returned on success. See [Prepared statements](pq/: Prepared Statements) for details. diff --git a/pq/Connection/: General Usage.md b/pq/Connection/: General Usage.md new file mode 100644 index 0000000..0b282c5 --- /dev/null +++ b/pq/Connection/: General Usage.md @@ -0,0 +1,87 @@ +# pq\Connection: General Usage + +What is needed to create, check and reset a connection. + +## Creating a connection: + +Creating a connection to the PostgreSQL server is as simple as: + + + +The first argument to the Connection constructor is a ***connection string*** as described [in the PostgreSQL documentation](http://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING). + +Optional ***flags*** are accepted as second argument. See [connection flag constants](pq/Connection#Connection.Flags:). + +### Creating a persistent connection: + + + +### Creating an asynchronously opened connection: + + + +## Checking the connection status: + +The connection object provides a ***public readonly*** property pq\Connection::$status, which value can be one of the [connection status constants](pq/Connection#Connection.Status:). + + status) { + case pq\Connection::OK: + // connection complete + break; + case pq\Connection::BAD: + $connection->reset(); + break; + default: + // connection in progress + break; + } + + ?> + +## Resetting the connection: + + reset(); + + ?> + +Attempt to close the connection to the server and reestablish a new connection with the same connection parameters previously used. + +## Closing the connection: + + + +### Non-persistent connections: + +A ***non-persistent*** connection will be closed when all references to the pq\Connection object are gone. + +### Persistent connections: + +A ***persistent*** connection will be recycled, when it is not referenced any longer. + +There is also some cleanup performed, so that subsequent usage is as unimpaired as possible: + +* any active asynchronous queries are canceled +* any pending results of asynchronous queries are fetched and cleared +* ```ROLLBACK``` if pq\Connection::$transactionStatus is anything but pq\Connection::TRANS_IDLE +* ```RESET ALL``` to reset any changed session variables +* ```UNLISTEN``` for each listened notification channel diff --git a/pq/Connection/__construct.md b/pq/Connection/__construct.md index 10d78d8..7890c93 100644 --- a/pq/Connection/__construct.md +++ b/pq/Connection/__construct.md @@ -4,9 +4,9 @@ Create a new PostgreSQL connection. See also [General Usage](pq/Connection/: General Usage). ## Params: -* string $dsn = "" +* Optional string $dsn = "" A ***connection string*** as described [in the PostgreSQL documentation](http://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING). -* int $flags = 0 +* Optional int $flags = 0 See [connection flag constants](pq/Connection#Connection.Flags:). ## Throws: @@ -17,8 +17,6 @@ See also [General Usage](pq/Connection/: General Usage). ## Example: -Creating a connection: - declare("example", pq\Cursor::WITH_HOLD, + "SELECT * FROM generate_series(0,29) s WHERE (s%2)=0"); + + for ( $result = $cursor->fetch(2); + $result->numRows; + $cursor->move(1), $result = $cursor->fetch(2)) { + foreach ($result as $row) { + foreach ($row as $col) { + echo " $col"; + } + echo "\n"; + } + } + + ?> + +Yields: + + 0 + 2 + 6 + 8 + 12 + 14 + 18 + 20 + 24 + 26 diff --git a/pq/Connection/declareAsync.md b/pq/Connection/declareAsync.md new file mode 100644 index 0000000..af80b52 --- /dev/null +++ b/pq/Connection/declareAsync.md @@ -0,0 +1,25 @@ +# pq\Cursor pq\Connection::declareAsync(string $name, int $flags, string $query) + +[Asynchronously](pq/Connection/: Asynchronous Usage) declare a cursor for a query. + +> ***NOTE***: + If pq\Connection::$unbuffered is TRUE, each call to pq\Connection::getResult() will generate a distinct pq\Result containing exactly one row. + +## Params: + +* string $name + The identifying name of the cursor. +* int $flags + Any combination of pq\Cursor constants. +* string $query + The query for which to open a cursor. + +## Returns: + +* pq\Cursor, an open cursor instance. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\RuntimeException +* pq\Exception\BadMethodCallException diff --git a/pq/Connection/escapeBytea.md b/pq/Connection/escapeBytea.md new file mode 100644 index 0000000..6cb0a2a --- /dev/null +++ b/pq/Connection/escapeBytea.md @@ -0,0 +1,20 @@ +# string pq\Connection::escapeBytea(string $binary) + +Escape binary data for use within a query with the type bytea. + +> ***NOTE:*** + The result is not wrapped in single quotes. + +## Params: + +* string $binary + The binary data to escape. + +## Returns: + +* string, the escaped binary data. +* FALSE, if escaping fails. + +## Throws: + +* pq\Exception\BadMethodCallException diff --git a/pq/Connection/exec.md b/pq/Connection/exec.md new file mode 100644 index 0000000..54f6dd9 --- /dev/null +++ b/pq/Connection/exec.md @@ -0,0 +1,33 @@ +# pq\Result pq\Connection::exec(string $query) + +[Execute one or multiple SQL queries](pq/Connection/: Executing Queries) on the connection. + +> ***NOTE:*** +> Only the last result will be returned, if the query string contains more than one SQL query. + + +## Params: + +* string $query + The queries to send to the server, separated by semi-colon. + +## Returns: + +* pq\Result + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException +* pq\Exception\RuntimeException +* pq\Exception\DomainException + + +## Example: + + exec("SELECT 1"); + + ?> diff --git a/pq/Connection/execAsync.md b/pq/Connection/execAsync.md new file mode 100644 index 0000000..a002319 --- /dev/null +++ b/pq/Connection/execAsync.md @@ -0,0 +1,31 @@ +# void pq\Connection::exec(string $query[, callable $callback]) + +[Asynchronously](pq/Connection/: Asynchronous Usage) [execute an SQL query](pq/Connection: Executing Queries) on the connection. + +> ***NOTE***: + If pq\Connection::$unbuffered is TRUE, each call to pq\Connection::getResult() will generate a distinct pq\Result containing exactly one row. + +## Params: + +* string $query + The query to send to the server. +* Optional callable $callback as function(pq\Result $res) + The callback to execute when the query finishes. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException +* pq\Exception\RuntimeException + +## Example: + + execAsync("SELECT 1", function($res) { + //... + }); + $connection->getResult(); + + ?> diff --git a/pq/Connection/execParams.md b/pq/Connection/execParams.md new file mode 100644 index 0000000..9d45720 --- /dev/null +++ b/pq/Connection/execParams.md @@ -0,0 +1,32 @@ +# pq\Result pq\Connection::execParams(string $query, array $params[, array $types = NULL]) + +[Execute an SQL query](pq/Connection: Executing Queries) with properly escaped parameters substituted. + +## Params: + +* string $query + The query to execute. +* array $params + The parameter list to substitute. +* Optional array $types = NULL + Corresponding list of type OIDs for the parameters. + +## Returns: + +* pq\Result + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\RuntimeException +* pq\Exception\DomainException + +## Example: + + execParams("SELECT int($1) * s, int($2) * s, int($3) * s + FROM generate_series(1,3) s", array(1,2,3)); + + ?> diff --git a/pq/Connection/execParamsAsync.md b/pq/Connection/execParamsAsync.md new file mode 100644 index 0000000..24e57b0 --- /dev/null +++ b/pq/Connection/execParamsAsync.md @@ -0,0 +1,22 @@ +# pq\Result pq\Connection::execParamsAsync(string $query, array $params[, array $types = NULL]) + +[Asynchronously](pq/Connection/: Asynchronous Usage) [execute an SQL query](pq/Connection: Executing Queries) with properly escaped parameters substituted. + +> ***NOTE***: + If pq\Connection::$unbuffered is TRUE, each call to pq\Connection::getResult() will generate a distinct pq\Result containing exactly one row. + +## Params: + +* string $query + The query to execute. +* array $params + The parameter list to substitute. +* Optional array $types = NULL + Corresponding list of type OIDs for the parameters. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\RuntimeException +* pq\Exception\BadMethodCallException + diff --git a/pq/Connection/getResult.md b/pq/Connection/getResult.md new file mode 100644 index 0000000..afbf93e --- /dev/null +++ b/pq/Connection/getResult.md @@ -0,0 +1,32 @@ +# pq\Result pq\Connection::getResult() + +Fetch the result of an [asynchronous](pq/Connection/: Asynchronous Usage) query. + +If the query hasn't finished yet, the call will block until the result is available. + +## Params: + +None. + +## Returns: + +* NULL, if there has not been a query +* pq\Result, when the query has finished + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException + +## Example: + + execAsync("SELECT 1"); + + // ... + + $result = $conn->getResult(); + + ?> diff --git a/pq/Connection/listen.md b/pq/Connection/listen.md new file mode 100644 index 0000000..66249a7 --- /dev/null +++ b/pq/Connection/listen.md @@ -0,0 +1,28 @@ +# void pq\Connection::listen(string $channel, callable $listener) + +Listen on $channel for notifcations. +See pq\Connection::unlisten(). + +## Params: + +* string $channel + The channel to listen on. +* callable $listener as function(string $channel, string $message, int $pid) + A callback automatically called whenever a notification on $channel arrives. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException +* pq\Exception\RuntimeException + +## Example: + + listen("queue", function($channel, $message, $backend_pid) { + printf("Connection on backend %d said %s\n", $backend_pid, $message); + }); + + ?> diff --git a/pq/Connection/listenAsync.md b/pq/Connection/listenAsync.md new file mode 100644 index 0000000..3e63d23 --- /dev/null +++ b/pq/Connection/listenAsync.md @@ -0,0 +1,17 @@ +# void pq\Connection::listenAsync(string $channel, callable $listener) + +[Asynchronously](pq/Connection/: Asynchronous Usage) start listening on $channel for notifcations. +See pq\Connection::listen(). + +## Params: + +* string $channel + The channel to listen on. +* callable $listener as function(string $channel, string $message, int $pid) + A callback automatically called whenever a notification on $channel arrives. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException +* pq\Exception\RuntimeException diff --git a/pq/Connection/notify.md b/pq/Connection/notify.md new file mode 100644 index 0000000..bf89f49 --- /dev/null +++ b/pq/Connection/notify.md @@ -0,0 +1,25 @@ +# void pq\Connection::notify(string $channel, string $message) + +Notify all listeners on $channel with $message. + +## Params: + +* string $channel + The channel to notify. +* string $message + The message to send. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException +* pq\Exception\RuntimeException + +## Example: + + notify("queue", "Hello World!"); + + ?> diff --git a/pq/Connection/notifyAsync.md b/pq/Connection/notifyAsync.md new file mode 100644 index 0000000..7ce1b78 --- /dev/null +++ b/pq/Connection/notifyAsync.md @@ -0,0 +1,25 @@ +# void pq\Connection::notifyAsync(string $channel, string $message) + +[Asynchronously](pq/Connection/: Asynchronous Usage) start notifying all listeners on $channel with $message. + +## Params: + +* string $channel + The channel to notify. +* string $message + The message to send. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException +* pq\Exception\RuntimeException + +## Example: + + notifyAsync("queue", "Hello World!"); + + ?> diff --git a/pq/Connection/off.md b/pq/Connection/off.md new file mode 100644 index 0000000..fc0e228 --- /dev/null +++ b/pq/Connection/off.md @@ -0,0 +1,17 @@ +# bool pq\Connection::off(string $event) + +Stops listening for an event type. + +## Params: + +* string $event + Any pq\Connection::EVENT_*. + +## Returns: + +* bool, success. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException diff --git a/pq/Connection/on.md b/pq/Connection/on.md new file mode 100644 index 0000000..cda9738 --- /dev/null +++ b/pq/Connection/on.md @@ -0,0 +1,34 @@ +# int pq\Connection::on(string $event, callable $callback) + +Listen for an event. + +## Params: + +* string $event + Any pq\Connection::EVENT_*. +* callable $callback as function(pq\Connection $c[, pq\Result $r) + The callback to invoke on event. + +## Returns: + +* int, number of previously attached event listeners. + +## Throws: + +* pq\Exception\InvalidArgumentException + +## Example: + + on(pq\Connection::EVENT_RESULT, function($c, $r) { + printf("Got result with %d rows\n", $r->numRows); + }); + $connection->exec("SELECT * FROM generate_series(1,3)"); + + ?> + +Yields: + + Got result with 3 rows diff --git a/pq/Connection/poll.md b/pq/Connection/poll.md new file mode 100644 index 0000000..92e1ae1 --- /dev/null +++ b/pq/Connection/poll.md @@ -0,0 +1,19 @@ +# int pq\Connection::poll() + +Poll an [asynchronously](pq/Connection/: Asynchronous Usage) operating connection. +See pq\Connection::resetAsync() for an usage example. + +## Params: + +None. + +## Returns: + + * int, pq\Connection::POLLING_* constant + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\RuntimeException +* pq\Exception\BadMethodCallException + diff --git a/pq/Connection/prepare.md b/pq/Connection/prepare.md new file mode 100644 index 0000000..ceaea70 --- /dev/null +++ b/pq/Connection/prepare.md @@ -0,0 +1,53 @@ +# pq\Statement pq\Connection::prepare(string $name, string $query[, array $types = NULL]) + +Prepare a named statement for later execution with pq\Statement::execute(). + +## Params: + +* string $name + The identifying name of the prepared statement. +* string $query + The query to prepare. +* Optional array $types = NULL + An array of type OIDs for the substitution parameters. + +## Returns: + +* pq\Statement, a prepared statement instance. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException +* pq\Exception\RuntimeException + + +## Example: + + prepare( + "example", + "SELECT a from generate_series(1,9) a WHERE a > \$1", + [pq\Types::INT4]); + $result = $statement->exec([5]); + + var_dump($result->fetchAllCols(0)); + + ?> + +Yields: + + array(4) { + [0]=> + int(6) + [1]=> + int(7) + [2]=> + int(8) + [3]=> + int(9) + } + diff --git a/pq/Connection/prepareAsync.md b/pq/Connection/prepareAsync.md new file mode 100644 index 0000000..f74d024 --- /dev/null +++ b/pq/Connection/prepareAsync.md @@ -0,0 +1,25 @@ +# pq\Statement pq\Connection::prepareAsync(string $name, string $query[, array $types = NULL]) + +[Asynchronously](pq/Connection/: Asynchronous Usage) prepare a named statement for later execution with pq\Statement::exec(). + +> ***NOTE***: + If pq\Connection::$unbuffered is TRUE, each call to pq\Connection::getResult() will generate a distinct pq\Result containing exactly one row. + +## Params: + +* string $name + The identifying name of the prepared statement. +* string $query + The query to prepare. +* Optional array $types = NULL + An array of type OIDs for the substitution parameters. + +## Returns: + +* pq\Statement, a prepared statement instance. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException +* pq\Exception\RuntimeException diff --git a/pq/Connection/quote.md b/pq/Connection/quote.md new file mode 100644 index 0000000..4ede455 --- /dev/null +++ b/pq/Connection/quote.md @@ -0,0 +1,21 @@ +# string pq\Connection::quote(string $payload) + +Quote a string for safe use in a query. +The result is truncated at any zero byte and wrapped in single quotes. + +> ***NOTE:*** + Beware of matching character encodings. + +## Params: + +* string $payload + The payload to quote for use in a query. + +## Returns: + +* string, a single-quote wrapped string safe for literal use in a qurey. +* FALSE, if quoting fails. + +# Throws: + +* pq\Exception\BadMethodCallException diff --git a/pq/Connection/quoteName.md b/pq/Connection/quoteName.md new file mode 100644 index 0000000..a981872 --- /dev/null +++ b/pq/Connection/quoteName.md @@ -0,0 +1,20 @@ +# string pq\Connection::quoteName(string $name) + +Quote an identifier for safe usage as name. + +> ***NOTE:*** + Beware of case-sensitivity. + +## Params: + +* string $name + The name to quote. + +## Returns: + +* string, the quoted identifier. +* FALSE, if quoting fails. + +## Throws: + +* pq\Exception\BadMethodCallException diff --git a/pq/Connection/reset.md b/pq/Connection/reset.md new file mode 100644 index 0000000..52d8ca8 --- /dev/null +++ b/pq/Connection/reset.md @@ -0,0 +1,24 @@ +# void pq\Connection::reset() + +Attempt to reset a possibly broken connection to a working state. + +## Params: + +None. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException +* pq\Exception\RuntimeException + + +## Example: + + status != pq\Connection::OK) { + $connection->reset(); + } + + ?> diff --git a/pq/Connection/resetAsync.md b/pq/Connection/resetAsync.md new file mode 100644 index 0000000..8b1ff99 --- /dev/null +++ b/pq/Connection/resetAsync.md @@ -0,0 +1,57 @@ +# void pq\Connection::resetAsync() + +[Asynchronously](pq/Connection/: Asynchronous Usage) reset a possibly broken connection to a working state. + +## Params: + +None. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException +* pq\Exception\RuntimeException + + +## Example: + + resetAsync(); + + // wait until the stream becomes writable + $w = array($c->socket); + $r = $e = null; + + if (stream_select($r, $w, $e, null)) { + + // loop until the connection is established + while (true) { + + switch ($c->poll()) { + + case pq\Connection::POLLING_READING: + // we should wait for the stream to be read-ready + $r = array($c->socket); + stream_select($r, $w, $e, NULL); + break; + + case pq\Connection::POLLING_WRITING: + // we should wait for the stream to be write-ready + $w = array($c->socket); + $r = $e = null; + stream_select($r, $w, $e, null); + break; + + case pq\Connection::POLLING_FAILED: + printf("Connection failed: %s\n", $c->errorMessage); + break 2; + + case pq\Connection::POLLING_OK: + printf("Connection completed\n"); + break 2; + } + } + + ?> + diff --git a/pq/Connection/setConverter.md b/pq/Connection/setConverter.md new file mode 100644 index 0000000..0c71405 --- /dev/null +++ b/pq/Connection/setConverter.md @@ -0,0 +1,78 @@ +# void pq\Connection::setConverter(pq\ConverterInterface $converter) + +Set a data type converter. + +## Params: + +* pq\ConverterInterface $converter + An instance implementing pq\ConverterInterface. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException + +## Example: + + oids = [$types["hstore"]->oid]; + } + + function convertTypes() { + return $this->oids; + } + + function convertFromString($string) { + return eval("return [$string];"); + } + + function convertToString($data) { + $string = ""; + foreach ($data as $k => $v) { + if (isset($v)) { + $string .= sprintf("\"%s\"=>\"%s\",", addslashes($k), addslashes($v)); + } else { + $string .= sprintf("\"%s\"=>NULL,", addslashes($k)); + } + } + return $string; + } + } + $connection = new pq\Connection; + $types = new pq\Types($connection); + + $connection->setConverter(new HStoreConverter($types)); + + $result = $connection->execParams("SELECT \$1", [ + [ + "k1" => "v1", + "k2" => "v2", + "k3" => null + ] + ], [ + $types["hstore"]->oid + ]); + + var_dump(current($result->fetchAll())); + + ?> + +Yields: + + array(1) { + [0]=> + array(3) { + ["k1"]=> + string(2) "v1" + ["k2"]=> + string(2) "v2" + ["k3"]=> + NULL + } + } diff --git a/pq/Connection/startTransaction.md b/pq/Connection/startTransaction.md new file mode 100644 index 0000000..4fd8d0f --- /dev/null +++ b/pq/Connection/startTransaction.md @@ -0,0 +1,41 @@ +# pq\Transaction pq\Connection::startTransaction([int $isolation = pq\Transaction::READ_COMMITTED[, bool $readonly = FALSE[, bool $deferrable = FALSE]]]) + +Begin a transaction. + +## Params: + +* Optional int $isolation = pq\Transaction::READ_COMMITTED + Any pq\Transaction isolation level constant + (defaults to pq\Connection::$defaultTransactionIsolation). +* Optional bool $readonly = FALSE + Whether the transaction executes only reads + (defaults to pq\Connection::$defaultTransactionReadonly). +* Optional bool $deferrable = FALSE + Whether the transaction is deferrable + (defaults to pq\Connection::$defaultTransactionDeferrable). + +> ***NOTE:*** + A transaction can only be deferrable if it also is readonly and serializable. + See the official [PostgreSQL documentaion](http://www.postgresql.org/docs/current/static/sql-set-transaction.html) for further information. + +## Returns: + +* pq\Transaction, a begun transaction instance. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException +* pq\Exception\RuntimeException + + +## Example: + + startTransaction( + pq\Transaction::SERIALIZABLE, true, true); + $result = $transaction->connection->exec( + "SELECT * FROM generate_series(1,3)"); + + ?> diff --git a/pq/Connection/startTransactionAsync.md b/pq/Connection/startTransactionAsync.md new file mode 100644 index 0000000..126d65d --- /dev/null +++ b/pq/Connection/startTransactionAsync.md @@ -0,0 +1,29 @@ +# pq\Transaction pq\Connection::startTransactionAsync([int $isolation = pq\Transaction::READ_COMMITTED[, bool $readonly = FALSE[, bool $deferrable = FALSE]]]) + +[Asynchronously](pq/Connection/: Asynchronous Usage) begin a transaction. + +## Params: + +* Optional int $isolation = pq\Transaction::READ_COMMITTED + Any pq\Transaction isolation level constant + (defaults to pq\Connection::$defaultTransactionIsolation). +* Optional bool $readonly = FALSE + Whether the transaction executes only reads + (defaults to pq\Connection::$defaultTransactionReadonly). +* Optional bool $deferrable = FALSE + Whether the transaction is deferrable + (defaults to pq\Connection::$defaultTransactionDeferrable). + +> ***NOTE:*** + A transaction can only be deferrable if it also is readonly and serializable. + See the official [PostgreSQL documentaion](http://www.postgresql.org/docs/current/static/sql-set-transaction.html) for further information. + +## Returns: + +* pq\Transaction, an asynchronously begun transaction instance. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException +* pq\Exception\RuntimeException diff --git a/pq/Connection/trace.md b/pq/Connection/trace.md new file mode 100644 index 0000000..8bb27f3 --- /dev/null +++ b/pq/Connection/trace.md @@ -0,0 +1,20 @@ +# bool pq\Connection::trace([resource $stream]) + +Trace protocol communication with the server. + +> ***NOTE:*** + Calling pq\Connection::trace() without parameter or NULL stops tracing. + +## Params: + +* Optional resource $stream = NULL + The resource to which the protocol trace will be output. + (The stream must be castable to STDIO). + +## Returns: + +* bool, success. + +## Throws: + +* pq\Exception\BadMethodCallException diff --git a/pq/Connection/unescapeBytea.md b/pq/Connection/unescapeBytea.md new file mode 100644 index 0000000..1e4bc54 --- /dev/null +++ b/pq/Connection/unescapeBytea.md @@ -0,0 +1,18 @@ +# string pq\Connection::unescapeBytea(string $bytea) + +Unescape bytea data retrieved from the server. + +## Params: + +* string $bytea + Bytea data retrieved from the server. + + +## Returns: + +* string, unescaped binary data. +* FALSE, if unescaping fails. + +## Throws: + +* pq\Exception\BadMethodCallException diff --git a/pq/Connection/unlisten.md b/pq/Connection/unlisten.md new file mode 100644 index 0000000..081901e --- /dev/null +++ b/pq/Connection/unlisten.md @@ -0,0 +1,31 @@ +# void pq\Connection::unlisten(string $channel) + +Stop listening for notifications on channel $channel. +See pq\Connection::listen(). + +## Params: + +* string $channel + The name of a channel which is currently listened on. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException +* pq\Exception\RuntimeException + + +## Example: + + listen("foo", function($channel, $message, $backend_pid) { + printf("Got message '%s' on channel '%s' from backend %d\n", + $message, $channel, $backend_pid); + }); + + $conn->notify("foo", "bar"); + $conn->unlisten("foo"); + + ?> diff --git a/pq/Connection/unlistenAsync.md b/pq/Connection/unlistenAsync.md new file mode 100644 index 0000000..f8ebfb1 --- /dev/null +++ b/pq/Connection/unlistenAsync.md @@ -0,0 +1,16 @@ +# void pq\Connection::unlistenAsync(string $channel) + +[Asynchronously](pq/Connection/: Asynchronous Usage) stop listening for notifications on channel $channel. +See pq\Connection::unlisten() and pq\Connection::listenAsync(). + +## Params: + +* string $channel + The name of a channel which is currently listened on. + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException +* pq\Exception\RuntimeException + diff --git a/pq/Connection/unsetConverter.md b/pq/Connection/unsetConverter.md new file mode 100644 index 0000000..9d2fb46 --- /dev/null +++ b/pq/Connection/unsetConverter.md @@ -0,0 +1,13 @@ +# void pq\Connection::unsetConverter(pq\ConverterInterface $converter) + +Stop applying a data type converter. + +## Params: + +* pq\ConverterInterface $converter + A converter previously set with pq\Connection::setConverter(). + +## Throws: + +* pq\Exception\InvalidArgumentException +* pq\Exception\BadMethodCallException