mirror of
				https://github.com/psycopg/psycopg2.git
				synced 2025-11-04 09:47:30 +03:00 
			
		
		
		
	Move the decode parameter to start_replication().
				
					
				
			It makes more sense this way, because otherwise it must be passed to every call of `read_message()`.
This commit is contained in:
		
							parent
							
								
									76c7f4a0b5
								
							
						
					
					
						commit
						e69dafbecc
					
				| 
						 | 
					@ -185,10 +185,10 @@ replication::
 | 
				
			||||||
     connection_factory=psycopg2.extras.LogicalReplicationConnection)
 | 
					     connection_factory=psycopg2.extras.LogicalReplicationConnection)
 | 
				
			||||||
  cur = conn.cursor()
 | 
					  cur = conn.cursor()
 | 
				
			||||||
  try:
 | 
					  try:
 | 
				
			||||||
      cur.start_replication(slot_name='pytest')
 | 
					      cur.start_replication(slot_name='pytest', decode=True)  # test_decoding produces textual output
 | 
				
			||||||
  except psycopg2.ProgrammingError:
 | 
					  except psycopg2.ProgrammingError:
 | 
				
			||||||
      cur.create_replication_slot('pytest', output_plugin='test_decoding')
 | 
					      cur.create_replication_slot('pytest', output_plugin='test_decoding')
 | 
				
			||||||
      cur.start_replication(slot_name='pytest')
 | 
					      cur.start_replication(slot_name='pytest', decode=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  class DemoConsumer(object):
 | 
					  class DemoConsumer(object):
 | 
				
			||||||
      def __call__(self, msg):
 | 
					      def __call__(self, msg):
 | 
				
			||||||
| 
						 | 
					@ -260,9 +260,12 @@ The individual messages in the replication stream are represented by
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. attribute:: payload
 | 
					    .. attribute:: payload
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        The actual data received from the server.  An instance of either
 | 
					        The actual data received from the server.
 | 
				
			||||||
        ``str`` or ``unicode``, depending on the method that was used to
 | 
					
 | 
				
			||||||
        produce this message.
 | 
					        An instance of either `bytes()` or `unicode()`, depending on the value
 | 
				
			||||||
 | 
					        of `decode` option passed to `ReplicationCursor.start_replication()`
 | 
				
			||||||
 | 
					        on the connection.  See `ReplicationCursor.read_message()` for
 | 
				
			||||||
 | 
					        details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. attribute:: data_size
 | 
					    .. attribute:: data_size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -336,7 +339,7 @@ The individual messages in the replication stream are represented by
 | 
				
			||||||
        Replication slots are a feature of PostgreSQL server starting with
 | 
					        Replication slots are a feature of PostgreSQL server starting with
 | 
				
			||||||
        version 9.4.
 | 
					        version 9.4.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. method:: start_replication(slot_name=None, slot_type=None, start_lsn=0, timeline=0, options=None)
 | 
					    .. method:: start_replication(slot_name=None, slot_type=None, start_lsn=0, timeline=0, options=None, decode=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Start replication on the connection.
 | 
					        Start replication on the connection.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -352,6 +355,8 @@ The individual messages in the replication stream are represented by
 | 
				
			||||||
                         can only be used with physical replication)
 | 
					                         can only be used with physical replication)
 | 
				
			||||||
        :param options: a dictionary of options to pass to logical replication
 | 
					        :param options: a dictionary of options to pass to logical replication
 | 
				
			||||||
                        slot (not allowed with physical replication)
 | 
					                        slot (not allowed with physical replication)
 | 
				
			||||||
 | 
					        :param decode: a flag indicating that unicode conversion should be
 | 
				
			||||||
 | 
					                       performed on messages received from the server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        If a *slot_name* is specified, the slot must exist on the server and
 | 
					        If a *slot_name* is specified, the slot must exist on the server and
 | 
				
			||||||
        its type must match the replication type used.
 | 
					        its type must match the replication type used.
 | 
				
			||||||
| 
						 | 
					@ -387,6 +392,11 @@ The individual messages in the replication stream are represented by
 | 
				
			||||||
        on the output plugin that was used to create the slot.  Must be
 | 
					        on the output plugin that was used to create the slot.  Must be
 | 
				
			||||||
        `!None` for physical replication.
 | 
					        `!None` for physical replication.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        If *decode* is set to `!True` the messages received from the server
 | 
				
			||||||
 | 
					        would be converted according to the connection `~connection.encoding`.
 | 
				
			||||||
 | 
					        *This parameter should not be set with physical replication or with
 | 
				
			||||||
 | 
					        logical replication plugins that produce binary output.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        This function constructs a ``START_REPLICATION`` command and calls
 | 
					        This function constructs a ``START_REPLICATION`` command and calls
 | 
				
			||||||
        `start_replication_expert()` internally.
 | 
					        `start_replication_expert()` internally.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -395,43 +405,40 @@ The individual messages in the replication stream are represented by
 | 
				
			||||||
        `read_message()` in case of :ref:`asynchronous connection
 | 
					        `read_message()` in case of :ref:`asynchronous connection
 | 
				
			||||||
        <async-support>`.
 | 
					        <async-support>`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. method:: start_replication_expert(command)
 | 
					    .. method:: start_replication_expert(command, decode=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Start replication on the connection using provided ``START_REPLICATION``
 | 
					        Start replication on the connection using provided
 | 
				
			||||||
        command.
 | 
					        ``START_REPLICATION`` command.  See `start_replication()` for
 | 
				
			||||||
 | 
					        description of *decode* parameter.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. method:: consume_stream(consume, decode=False, keepalive_interval=10)
 | 
					    .. method:: consume_stream(consume, keepalive_interval=10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param consume: a callable object with signature ``consume(msg)``
 | 
					        :param consume: a callable object with signature ``consume(msg)``
 | 
				
			||||||
        :param decode: a flag indicating that unicode conversion should be
 | 
					 | 
				
			||||||
                       performed on the messages received from the server
 | 
					 | 
				
			||||||
        :param keepalive_interval: interval (in seconds) to send keepalive
 | 
					        :param keepalive_interval: interval (in seconds) to send keepalive
 | 
				
			||||||
                                   messages to the server
 | 
					                                   messages to the server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        This method can only be used with synchronous connection.  For
 | 
					        This method can only be used with synchronous connection.  For
 | 
				
			||||||
        asynchronous connections see `read_message()`.
 | 
					        asynchronous connections see `read_message()`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Before calling this method to consume the stream use
 | 
					        Before using this method to consume the stream call
 | 
				
			||||||
        `start_replication()` first.
 | 
					        `start_replication()` first.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        This method enters an endless loop reading messages from the server
 | 
					        This method enters an endless loop reading messages from the server
 | 
				
			||||||
        and passing them to ``consume()``, then waiting for more messages from
 | 
					        and passing them to ``consume()`` one at a time, then waiting for more
 | 
				
			||||||
        the server.  In order to make this method break out of the loop and
 | 
					        messages from the server.  In order to make this method break out of
 | 
				
			||||||
        return, ``consume()`` can throw a `StopReplication` exception.  Any
 | 
					        the loop and return, ``consume()`` can throw a `StopReplication`
 | 
				
			||||||
        unhandled exception will make it break out of the loop as well.
 | 
					        exception.  Any unhandled exception will make it break out of the loop
 | 
				
			||||||
 | 
					        as well.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        If *decode* is set to `!True` the messages read from the server are
 | 
					        The *msg* object passed to ``consume()`` is an instance of
 | 
				
			||||||
        converted according to the connection `~connection.encoding`.  This
 | 
					        `ReplicationMessage` class.  See `read_message()` for details about
 | 
				
			||||||
        parameter should not be set with physical replication.
 | 
					        message decoding.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        This method also sends keepalive messages to the server in case there
 | 
					        This method also sends keepalive messages to the server in case there
 | 
				
			||||||
        were no new data from the server for the duration of
 | 
					        were no new data from the server for the duration of
 | 
				
			||||||
        *keepalive_interval* (in seconds).  The value of this parameter must
 | 
					        *keepalive_interval* (in seconds).  The value of this parameter must
 | 
				
			||||||
        be set to at least 1 second, but it can have a fractional part.
 | 
					        be set to at least 1 second, but it can have a fractional part.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        The *msg* objects passed to ``consume()`` are instances of
 | 
					 | 
				
			||||||
        `ReplicationMessage` class.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        After processing certain amount of messages the client should send a
 | 
					        After processing certain amount of messages the client should send a
 | 
				
			||||||
        confirmation message to the server.  This should be done by calling
 | 
					        confirmation message to the server.  This should be done by calling
 | 
				
			||||||
        `send_feedback()` method on the corresponding replication cursor.  A
 | 
					        `send_feedback()` method on the corresponding replication cursor.  A
 | 
				
			||||||
| 
						 | 
					@ -452,7 +459,7 @@ The individual messages in the replication stream are represented by
 | 
				
			||||||
                        msg.cursor.send_feedback(flush_lsn=msg.data_start)
 | 
					                        msg.cursor.send_feedback(flush_lsn=msg.data_start)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            consumer = LogicalStreamConsumer()
 | 
					            consumer = LogicalStreamConsumer()
 | 
				
			||||||
            cur.consume_stream(consumer, decode=True)
 | 
					            cur.consume_stream(consumer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .. warning::
 | 
					        .. warning::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -510,17 +517,21 @@ The individual messages in the replication stream are represented by
 | 
				
			||||||
    for better control, in particular to `~select` on multiple sockets.  The
 | 
					    for better control, in particular to `~select` on multiple sockets.  The
 | 
				
			||||||
    following methods are provided for asynchronous operation:
 | 
					    following methods are provided for asynchronous operation:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. method:: read_message(decode=True)
 | 
					    .. method:: read_message()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param decode: a flag indicating that unicode conversion should be
 | 
					        Try to read the next message from the server without blocking and
 | 
				
			||||||
                       performed on the data received from the server
 | 
					        return an instance of `ReplicationMessage` or `!None`, in case there
 | 
				
			||||||
 | 
					        are no more data messages from the server at the moment.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        This method should be used in a loop with asynchronous connections
 | 
					        This method should be used in a loop with asynchronous connections
 | 
				
			||||||
        after calling `start_replication()` once.
 | 
					        (after calling `start_replication()` once).  For synchronous
 | 
				
			||||||
 | 
					        connections see `consume_stream()`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        It tries to read the next message from the server without blocking and
 | 
					        The returned message's `ReplicationMessage.payload` is an instance of
 | 
				
			||||||
        returns an instance of `ReplicationMessage` or `!None`, in case there
 | 
					        `unicode()` decoded according to connection `connection.encoding`
 | 
				
			||||||
        are no more data messages from the server at the moment.
 | 
					        *iff* `decode` was set to `!True` in the initial call to
 | 
				
			||||||
 | 
					        `start_replication()` on this connection, otherwise it is an instance
 | 
				
			||||||
 | 
					        of `bytes()` with no decoding.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        It is expected that the calling code will call this method repeatedly
 | 
					        It is expected that the calling code will call this method repeatedly
 | 
				
			||||||
        in order to consume all of the messages that might have been buffered
 | 
					        in order to consume all of the messages that might have been buffered
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -548,7 +548,7 @@ class ReplicationCursor(_replicationCursor):
 | 
				
			||||||
        self.execute(command)
 | 
					        self.execute(command)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def start_replication(self, slot_name=None, slot_type=None, start_lsn=0,
 | 
					    def start_replication(self, slot_name=None, slot_type=None, start_lsn=0,
 | 
				
			||||||
                          timeline=0, options=None):
 | 
					                          timeline=0, options=None, decode=False):
 | 
				
			||||||
        """Start replication stream."""
 | 
					        """Start replication stream."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        command = "START_REPLICATION "
 | 
					        command = "START_REPLICATION "
 | 
				
			||||||
| 
						 | 
					@ -597,7 +597,7 @@ class ReplicationCursor(_replicationCursor):
 | 
				
			||||||
                command += "%s %s" % (quote_ident(k, self), _A(str(v)))
 | 
					                command += "%s %s" % (quote_ident(k, self), _A(str(v)))
 | 
				
			||||||
            command += ")"
 | 
					            command += ")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.start_replication_expert(command)
 | 
					        self.start_replication_expert(command, decode=decode)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # allows replication cursors to be used in select.select() directly
 | 
					    # allows replication cursors to be used in select.select() directly
 | 
				
			||||||
    def fileno(self):
 | 
					    def fileno(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1543,7 +1543,7 @@ exit:
 | 
				
			||||||
   are never returned to the caller.
 | 
					   are never returned to the caller.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
PyObject *
 | 
					PyObject *
 | 
				
			||||||
pq_read_replication_message(replicationCursorObject *repl, int decode)
 | 
					pq_read_replication_message(replicationCursorObject *repl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    cursorObject *curs = &repl->cur;
 | 
					    cursorObject *curs = &repl->cur;
 | 
				
			||||||
    connectionObject *conn = curs->conn;
 | 
					    connectionObject *conn = curs->conn;
 | 
				
			||||||
| 
						 | 
					@ -1555,7 +1555,7 @@ pq_read_replication_message(replicationCursorObject *repl, int decode)
 | 
				
			||||||
    PyObject *str = NULL, *result = NULL;
 | 
					    PyObject *str = NULL, *result = NULL;
 | 
				
			||||||
    replicationMessageObject *msg = NULL;
 | 
					    replicationMessageObject *msg = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Dprintf("pq_read_replication_message(decode=%d)", decode);
 | 
					    Dprintf("pq_read_replication_message");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    consumed = 0;
 | 
					    consumed = 0;
 | 
				
			||||||
retry:
 | 
					retry:
 | 
				
			||||||
| 
						 | 
					@ -1629,8 +1629,7 @@ retry:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Dprintf("pq_read_replication_message: >>%.*s<<", data_size, buffer + hdr);
 | 
					        Dprintf("pq_read_replication_message: >>%.*s<<", data_size, buffer + hdr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* XXX it would be wise to check if it's really a logical replication */
 | 
					        if (repl->decode) {
 | 
				
			||||||
        if (decode) {
 | 
					 | 
				
			||||||
            str = PyUnicode_Decode(buffer + hdr, data_size, conn->codec, NULL);
 | 
					            str = PyUnicode_Decode(buffer + hdr, data_size, conn->codec, NULL);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            str = Bytes_FromStringAndSize(buffer + hdr, data_size);
 | 
					            str = Bytes_FromStringAndSize(buffer + hdr, data_size);
 | 
				
			||||||
| 
						 | 
					@ -1730,8 +1729,7 @@ pq_send_replication_feedback(replicationCursorObject *repl, int reply_requested)
 | 
				
			||||||
   manages to send keepalive messages to the server as needed.
 | 
					   manages to send keepalive messages to the server as needed.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
pq_copy_both(replicationCursorObject *repl, PyObject *consume, int decode,
 | 
					pq_copy_both(replicationCursorObject *repl, PyObject *consume, double keepalive_interval)
 | 
				
			||||||
             double keepalive_interval)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    cursorObject *curs = &repl->cur;
 | 
					    cursorObject *curs = &repl->cur;
 | 
				
			||||||
    connectionObject *conn = curs->conn;
 | 
					    connectionObject *conn = curs->conn;
 | 
				
			||||||
| 
						 | 
					@ -1752,7 +1750,7 @@ pq_copy_both(replicationCursorObject *repl, PyObject *consume, int decode,
 | 
				
			||||||
    keep_intr.tv_usec = (keepalive_interval - keep_intr.tv_sec)*1.0e6;
 | 
					    keep_intr.tv_usec = (keepalive_interval - keep_intr.tv_sec)*1.0e6;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (1) {
 | 
					    while (1) {
 | 
				
			||||||
        msg = pq_read_replication_message(repl, decode);
 | 
					        msg = pq_read_replication_message(repl);
 | 
				
			||||||
        if (!msg) {
 | 
					        if (!msg) {
 | 
				
			||||||
            goto exit;
 | 
					            goto exit;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,8 +75,8 @@ RAISES HIDDEN void pq_complete_error(connectionObject *conn, PGresult **pgres,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* replication protocol support */
 | 
					/* replication protocol support */
 | 
				
			||||||
HIDDEN int pq_copy_both(replicationCursorObject *repl, PyObject *consumer,
 | 
					HIDDEN int pq_copy_both(replicationCursorObject *repl, PyObject *consumer,
 | 
				
			||||||
                        int decode, double keepalive_interval);
 | 
					                        double keepalive_interval);
 | 
				
			||||||
HIDDEN PyObject *pq_read_replication_message(replicationCursorObject *repl, int decode);
 | 
					HIDDEN PyObject *pq_read_replication_message(replicationCursorObject *repl);
 | 
				
			||||||
HIDDEN int pq_send_replication_feedback(replicationCursorObject *repl, int reply_requested);
 | 
					HIDDEN int pq_send_replication_feedback(replicationCursorObject *repl, int reply_requested);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* !defined(PSYCOPG_PQPATH_H) */
 | 
					#endif /* !defined(PSYCOPG_PQPATH_H) */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,10 +38,11 @@ extern HIDDEN PyTypeObject replicationCursorType;
 | 
				
			||||||
typedef struct replicationCursorObject {
 | 
					typedef struct replicationCursorObject {
 | 
				
			||||||
    cursorObject cur;
 | 
					    cursorObject cur;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int         started:1;          /* if replication is started */
 | 
					    int         started:1;        /* if replication is started */
 | 
				
			||||||
    int         consuming:1;        /* if running the consume loop */
 | 
					    int         consuming:1;      /* if running the consume loop */
 | 
				
			||||||
 | 
					    int         decode:1;         /* if we should use character decoding on the messages */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct timeval last_io;       /* timestamp of the last exchange with the server */
 | 
					    struct timeval last_io  ;     /* timestamp of the last exchange with the server */
 | 
				
			||||||
    struct timeval keepalive_interval;   /* interval for keepalive messages in replication mode */
 | 
					    struct timeval keepalive_interval;   /* interval for keepalive messages in replication mode */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    XLogRecPtr  write_lsn;        /* LSN stats for replication feedback messages */
 | 
					    XLogRecPtr  write_lsn;        /* LSN stats for replication feedback messages */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,8 +38,8 @@
 | 
				
			||||||
#include "datetime.h"
 | 
					#include "datetime.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define psyco_repl_curs_start_replication_expert_doc                                \
 | 
					#define psyco_repl_curs_start_replication_expert_doc \
 | 
				
			||||||
"start_replication_expert(command, writer=None, keepalive_interval=10) -- Start replication stream with a directly given command."
 | 
					"start_replication_expert(command, decode=False) -- Start replication with a given command."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
psyco_repl_curs_start_replication_expert(replicationCursorObject *self,
 | 
					psyco_repl_curs_start_replication_expert(replicationCursorObject *self,
 | 
				
			||||||
| 
						 | 
					@ -49,9 +49,10 @@ psyco_repl_curs_start_replication_expert(replicationCursorObject *self,
 | 
				
			||||||
    connectionObject *conn = self->cur.conn;
 | 
					    connectionObject *conn = self->cur.conn;
 | 
				
			||||||
    PyObject *res = NULL;
 | 
					    PyObject *res = NULL;
 | 
				
			||||||
    char *command;
 | 
					    char *command;
 | 
				
			||||||
    static char *kwlist[] = {"command", NULL};
 | 
					    long int decode = 0;
 | 
				
			||||||
 | 
					    static char *kwlist[] = {"command", "decode", NULL};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &command)) {
 | 
					    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|l", kwlist, &command, &decode)) {
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,17 +61,15 @@ psyco_repl_curs_start_replication_expert(replicationCursorObject *self,
 | 
				
			||||||
    EXC_IF_TPC_PREPARED(conn, start_replication_expert);
 | 
					    EXC_IF_TPC_PREPARED(conn, start_replication_expert);
 | 
				
			||||||
    EXC_IF_REPLICATING(self, start_replication_expert);
 | 
					    EXC_IF_REPLICATING(self, start_replication_expert);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Dprintf("psyco_repl_curs_start_replication_expert: %s", command);
 | 
					    Dprintf("psyco_repl_curs_start_replication_expert: '%s'; decode: %d", command, decode);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*    self->copysize = 0;*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gettimeofday(&self->last_io, NULL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pq_execute(curs, command, conn->async, 1 /* no_result */, 1 /* no_begin */) >= 0) {
 | 
					    if (pq_execute(curs, command, conn->async, 1 /* no_result */, 1 /* no_begin */) >= 0) {
 | 
				
			||||||
        res = Py_None;
 | 
					        res = Py_None;
 | 
				
			||||||
        Py_INCREF(res);
 | 
					        Py_INCREF(res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self->started = 1;
 | 
					        self->started = 1;
 | 
				
			||||||
 | 
					        self->decode = decode;
 | 
				
			||||||
 | 
					        gettimeofday(&self->last_io, NULL);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
| 
						 | 
					@ -85,12 +84,11 @@ psyco_repl_curs_consume_stream(replicationCursorObject *self,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    cursorObject *curs = &self->cur;
 | 
					    cursorObject *curs = &self->cur;
 | 
				
			||||||
    PyObject *consume = NULL, *res = NULL;
 | 
					    PyObject *consume = NULL, *res = NULL;
 | 
				
			||||||
    int decode = 0;
 | 
					 | 
				
			||||||
    double keepalive_interval = 10;
 | 
					    double keepalive_interval = 10;
 | 
				
			||||||
    static char *kwlist[] = {"consume", "decode", "keepalive_interval", NULL};
 | 
					    static char *kwlist[] = {"consume", "keepalive_interval", NULL};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|id", kwlist,
 | 
					    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|id", kwlist,
 | 
				
			||||||
                                     &consume, &decode, &keepalive_interval)) {
 | 
					                                     &consume, &keepalive_interval)) {
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -115,7 +113,7 @@ psyco_repl_curs_consume_stream(replicationCursorObject *self,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    self->consuming = 1;
 | 
					    self->consuming = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pq_copy_both(self, consume, decode, keepalive_interval) >= 0) {
 | 
					    if (pq_copy_both(self, consume, keepalive_interval) >= 0) {
 | 
				
			||||||
        res = Py_None;
 | 
					        res = Py_None;
 | 
				
			||||||
        Py_INCREF(res);
 | 
					        Py_INCREF(res);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -126,27 +124,19 @@ psyco_repl_curs_consume_stream(replicationCursorObject *self,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define psyco_repl_curs_read_message_doc \
 | 
					#define psyco_repl_curs_read_message_doc \
 | 
				
			||||||
"read_message(decode=True) -- Try reading a replication message from the server (non-blocking)."
 | 
					"read_message() -- Try reading a replication message from the server (non-blocking)."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
psyco_repl_curs_read_message(replicationCursorObject *self,
 | 
					psyco_repl_curs_read_message(replicationCursorObject *self)
 | 
				
			||||||
                             PyObject *args, PyObject *kwargs)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    cursorObject *curs = &self->cur;
 | 
					    cursorObject *curs = &self->cur;
 | 
				
			||||||
    int decode = 1;
 | 
					 | 
				
			||||||
    static char *kwlist[] = {"decode", NULL};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    EXC_IF_CURS_CLOSED(curs);
 | 
					    EXC_IF_CURS_CLOSED(curs);
 | 
				
			||||||
    EXC_IF_GREEN(read_message);
 | 
					    EXC_IF_GREEN(read_message);
 | 
				
			||||||
    EXC_IF_TPC_PREPARED(self->cur.conn, read_message);
 | 
					    EXC_IF_TPC_PREPARED(self->cur.conn, read_message);
 | 
				
			||||||
    EXC_IF_NOT_REPLICATING(self, read_message);
 | 
					    EXC_IF_NOT_REPLICATING(self, read_message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist,
 | 
					    return pq_read_replication_message(self);
 | 
				
			||||||
                                     &decode)) {
 | 
					 | 
				
			||||||
        return NULL;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return pq_read_replication_message(self, decode);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
| 
						 | 
					@ -267,7 +257,7 @@ static struct PyMethodDef replicationCursorObject_methods[] = {
 | 
				
			||||||
    {"consume_stream", (PyCFunction)psyco_repl_curs_consume_stream,
 | 
					    {"consume_stream", (PyCFunction)psyco_repl_curs_consume_stream,
 | 
				
			||||||
     METH_VARARGS|METH_KEYWORDS, psyco_repl_curs_consume_stream_doc},
 | 
					     METH_VARARGS|METH_KEYWORDS, psyco_repl_curs_consume_stream_doc},
 | 
				
			||||||
    {"read_message", (PyCFunction)psyco_repl_curs_read_message,
 | 
					    {"read_message", (PyCFunction)psyco_repl_curs_read_message,
 | 
				
			||||||
     METH_VARARGS|METH_KEYWORDS, psyco_repl_curs_read_message_doc},
 | 
					     METH_NOARGS, psyco_repl_curs_read_message_doc},
 | 
				
			||||||
    {"send_feedback", (PyCFunction)psyco_repl_curs_send_feedback,
 | 
					    {"send_feedback", (PyCFunction)psyco_repl_curs_send_feedback,
 | 
				
			||||||
     METH_VARARGS|METH_KEYWORDS, psyco_repl_curs_send_feedback_doc},
 | 
					     METH_VARARGS|METH_KEYWORDS, psyco_repl_curs_send_feedback_doc},
 | 
				
			||||||
    {"flush_feedback", (PyCFunction)psyco_repl_curs_flush_feedback,
 | 
					    {"flush_feedback", (PyCFunction)psyco_repl_curs_flush_feedback,
 | 
				
			||||||
| 
						 | 
					@ -289,6 +279,7 @@ replicationCursor_setup(replicationCursorObject* self)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    self->started = 0;
 | 
					    self->started = 0;
 | 
				
			||||||
    self->consuming = 0;
 | 
					    self->consuming = 0;
 | 
				
			||||||
 | 
					    self->decode = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    self->write_lsn = InvalidXLogRecPtr;
 | 
					    self->write_lsn = InvalidXLogRecPtr;
 | 
				
			||||||
    self->flush_lsn = InvalidXLogRecPtr;
 | 
					    self->flush_lsn = InvalidXLogRecPtr;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user