From 90e0e2f47d5a767cc95d72ab7f62a2f9ae5d40f4 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Sat, 16 Oct 2010 02:31:51 +0100 Subject: [PATCH] Added documentation for the Xid object. --- doc/src/connection.rst | 30 ++++++++++----------- doc/src/extensions.rst | 6 +++++ doc/src/usage.rst | 9 ++++--- psycopg/xid_type.c | 60 +++++++++++++++++++++++++++++++++--------- 4 files changed, 74 insertions(+), 31 deletions(-) diff --git a/doc/src/connection.rst b/doc/src/connection.rst index df869bc1..6beea614 100644 --- a/doc/src/connection.rst +++ b/doc/src/connection.rst @@ -119,13 +119,14 @@ The ``connection`` class .. method:: xid(format_id, gtrid, bqual) - Returns a transaction ID object suitable for passing to the + Returns a `~psycopg2.extensions.Xid` instance to be passed to the `!tpc_*()` methods of this connection. The argument types and constraints are explained in :ref:`tpc`. - The object returned can be accessed and unpacked as a 3 items tuple, - returning the arguments passed to the method. The same values are - available as attributes `!format_id`, `!gtrid`, `!bqual`. + The values passed to the method will be available on the returned + object as the members `!format_id`, `!gtrid`, `!bqual`. The object + also allows accessing to these members and unpacking as a 3-items + tuple. .. method:: tpc_begin(xid) @@ -223,12 +224,14 @@ The ``connection`` class .. method:: tpc_recover() - Returns a list of pending transaction IDs suitable for use with - `!tpc_commit(xid)` or `!tpc_rollback(xid)`. + Returns a list of `~psycopg2.extensions.Xid` representing pending + transactions, suitable for use with `tpc_commit()` or + `tpc_rollback()`. If a transaction was not initiated by Psycopg, the returned Xids will - have attributes `!format_id` and `!bqual` set to `None` and the - `!gtrid` set to the PostgreSQL transaction ID: such Xids are still + have attributes `~psycopg2.extensions.Xid.format_id` and + `~psycopg2.extensions.Xid.bqual` set to `None` and the + `~psycopg2.extensions.Xid.gtrid` set to the PostgreSQL transaction ID: such Xids are still usable for recovery. Psycopg uses the same algorithm of the `PostgreSQL JDBC driver`__ to encode a XA triple in a string, so transactions initiated by a program using such driver should be @@ -236,13 +239,10 @@ The ``connection`` class .. __: http://jdbc.postgresql.org/ - Xids returned by `!tpc_recover()` have additional attributes populated - with the values read from the server: - - - `!prepared`: timestamp with timezone reporting the time the - transaction was prepared - - `!owner`: name of the user who prepared the transaction - - `!database`: name of the database the transaction belongs to + Xids returned by `!tpc_recover()` also have extra attributes + `~psycopg2.extensions.Xid.prepared`, `~psycopg2.extensions.Xid.owner`, + `~psycopg2.extensions.Xid.database` populated with the values read + from the server. .. seealso:: the |pg_prepared_xacts|_ system view. diff --git a/doc/src/extensions.rst b/doc/src/extensions.rst index 6517c709..5561ea4c 100644 --- a/doc/src/extensions.rst +++ b/doc/src/extensions.rst @@ -112,6 +112,12 @@ functionalities defined by the |DBAPI|_. .. versionadded:: 2.2.3 +.. autoclass:: Xid(format_id, gtrid, bqual) + :members: format_id, gtrid, bqual, prepared, owner, database + + .. automethod:: from_string(s) + + .. autofunction:: set_wait_callback(f) .. versionadded:: 2.2.0 diff --git a/doc/src/usage.rst b/doc/src/usage.rst index 311e5659..d3985158 100644 --- a/doc/src/usage.rst +++ b/doc/src/usage.rst @@ -553,7 +553,7 @@ Two-Phase Commit protocol support .. versionadded:: 2.2.3 -Psycopg exposes the two-phase commit features available from PostgreSQL 8,1 +Psycopg exposes the two-phase commit features available since PostgreSQL 8.1 implementing the *two-phase commit extensions* proposed by the |DBAPI|. The |DBAPI| model of two-phase commit is inspired to the `XA specification`__, @@ -576,9 +576,10 @@ database using `~connection.tpc_recover()` and completed using the above `!tpc_commit()` and `!tpc_rollback()`. PostgreSQL doesn't follow the XA standard though, and the ID for a PostgreSQL -prepared transaction can be any string up to 200 characters long. Psycopg can -deal both with Xid objects created by the `!xid()` method and with -transactions identified only by a string. +prepared transaction can be any string up to 200 characters long. +Psycopg's `~psycopg2.extensions.Xid` objects can represent both XA-style +transactions IDs (such as the ones created by the `!xid()` method) and +PostgreSQL transaction IDs identified by an unparsed string. The format in which the Xids are converted into strings passed to the database is the same employed by the `PostgreSQL JDBC driver`__: this should diff --git a/psycopg/xid_type.c b/psycopg/xid_type.c index 626440c3..606cb64e 100644 --- a/psycopg/xid_type.c +++ b/psycopg/xid_type.c @@ -34,13 +34,48 @@ #include "psycopg/psycopg.h" #include "psycopg/xid.h" +static const char xid_doc[] = + "A transaction identifier used for two-phase commit.\n\n" + "Usually returned by the connection methods `~connection.xid()` and\n" + "`~connection.tpc_recover()`.\n" + "`!Xid` instances can be unpacked as a 3-item tuples containing the items\n" + ":samp:`({format_id},{gtrid},{bqual})`.\n" + "The `!str()` of the object returns the *transaction ID* used\n" + "in the commands sent to the server.\n\n" + "See :ref:`tpc` for an introduction."; + +static const char format_id_doc[] = + "Format ID in a XA transaction.\n\n" + "A non-negative 32 bit integer.\n" + "`None` if the transaction doesn't follow the XA standard."; + +static const char gtrid_doc[] = + "Global transaction ID in a XA transaction.\n\n" + "If the transaction doesn't follow the XA standard, it is the plain\n" + "*transaction ID* used in the server commands."; + +static const char bqual_doc[] = + "Branch qualifier of the transaction.\n\n" + "In a XA transaction every resource participating to a transaction\n" + "receives a distinct branch qualifier.\n" + "`None` if the transaction doesn't follow the XA standard."; + +static const char prepared_doc[] = + "Timestamp (with timezone) in which a recovered transaction was prepared."; + +static const char owner_doc[] = + "Name of the user who prepared a recovered transaction."; + +static const char database_doc[] = + "Database the recovered transaction belongs to."; + static PyMemberDef xid_members[] = { - { "format_id", T_OBJECT, offsetof(XidObject, format_id), RO }, - { "gtrid", T_OBJECT, offsetof(XidObject, gtrid), RO }, - { "bqual", T_OBJECT, offsetof(XidObject, bqual), RO }, - { "prepared", T_OBJECT, offsetof(XidObject, prepared), RO }, - { "owner", T_OBJECT, offsetof(XidObject, owner), RO }, - { "database", T_OBJECT, offsetof(XidObject, database), RO }, + { "format_id", T_OBJECT, offsetof(XidObject, format_id), RO, (char *)format_id_doc }, + { "gtrid", T_OBJECT, offsetof(XidObject, gtrid), RO, (char *)gtrid_doc }, + { "bqual", T_OBJECT, offsetof(XidObject, bqual), RO, (char *)bqual_doc }, + { "prepared", T_OBJECT, offsetof(XidObject, prepared), RO, (char *)prepared_doc }, + { "owner", T_OBJECT, offsetof(XidObject, owner), RO, (char *)owner_doc }, + { "database", T_OBJECT, offsetof(XidObject, database), RO, (char *)database_doc }, { NULL } }; @@ -233,7 +268,12 @@ exit: static const char xid_from_string_doc[] = - "Create a Xid object from a string representation."; + "Create a `!Xid` object from a string representation. Static method.\n\n" + "If *s* is a PostgreSQL transaction ID produced by a XA transaction,\n" + "the returned object will have `format_id`, `gtrid`, `bqual` set to\n" + "the values of the preparing XA id.\n" + "Otherwise only the `!gtrid` is populated with the unparsed string.\n" + "The operation is the inverse of the one performed by ``str(xid)``."; static PyObject * xid_from_string_method(PyObject *cls, PyObject *args) @@ -245,6 +285,7 @@ xid_from_string_method(PyObject *cls, PyObject *args) return (PyObject *)xid_from_string(s); } + static PySequenceMethods xid_sequence = { (lenfunc)xid_len, /* sq_length */ 0, /* sq_concat */ @@ -258,17 +299,12 @@ static PySequenceMethods xid_sequence = { 0, /* sq_inplace_repeat */ }; - static struct PyMethodDef xid_methods[] = { {"from_string", (PyCFunction)xid_from_string_method, METH_VARARGS|METH_STATIC, xid_from_string_doc}, {NULL} }; - -static const char xid_doc[] = - "A transaction identifier used for two phase commit."; - PyTypeObject XidType = { PyObject_HEAD_INIT(NULL) 0,