Add libpq_support.c and win32_support.c

Move libpq-specific code for streaming replication support into a
separate file.  Also provide gettimeofday() on Win32, implementation
copied from Postgres core.
This commit is contained in:
Oleksandr Shulgin 2015-06-03 14:10:20 +02:00
parent 44b705f88f
commit f14521f8cb
6 changed files with 254 additions and 79 deletions

111
psycopg/libpq_support.c Normal file
View File

@ -0,0 +1,111 @@
/* libpq_support.c - functions not provided by libpq, but which are
* required for advanced communication with the server, such as
* streaming replication
*
* Copyright (C) 2003-2015 Federico Di Gregorio <fog@debian.org>
*
* This file is part of psycopg.
*
* psycopg2 is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the copyright holders give
* permission to link this program with the OpenSSL library (or with
* modified versions of OpenSSL that use the same license as OpenSSL),
* and distribute linked combinations including the two.
*
* You must obey the GNU Lesser General Public License in all respects for
* all of the code used other than OpenSSL.
*
* psycopg2 is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*/
#define PSYCOPG_MODULE
#include "psycopg/psycopg.h"
#include "psycopg/libpq_support.h"
/* htonl(), ntohl() */
#ifdef _WIN32
#include <winsock2.h>
/* gettimeofday() */
#include "psycopg/win32_support.h"
#else
#include <arpa/inet.h>
#endif
/* support routines taken from pg_basebackup/streamutil.c */
/* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */
#define UNIX_EPOCH_JDATE 2440588 /* == date2j(1970, 1, 1) */
#define POSTGRES_EPOCH_JDATE 2451545 /* == date2j(2000, 1, 1) */
#define SECS_PER_DAY 86400
#define USECS_PER_SEC 1000000LL
/*
* Frontend version of GetCurrentTimestamp(), since we are not linked with
* backend code. The protocol always uses integer timestamps, regardless of
* server setting.
*/
pg_int64
feGetCurrentTimestamp(void)
{
pg_int64 result;
struct timeval tp;
gettimeofday(&tp, NULL);
result = (pg_int64) tp.tv_sec -
((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);
result = (result * USECS_PER_SEC) + tp.tv_usec;
return result;
}
/*
* Converts an int64 to network byte order.
*/
void
fe_sendint64(pg_int64 i, char *buf)
{
uint32 n32;
/* High order half first, since we're doing MSB-first */
n32 = (uint32) (i >> 32);
n32 = htonl(n32);
memcpy(&buf[0], &n32, 4);
/* Now the low order half */
n32 = (uint32) i;
n32 = htonl(n32);
memcpy(&buf[4], &n32, 4);
}
/*
* Converts an int64 from network byte order to native format.
*/
pg_int64
fe_recvint64(char *buf)
{
pg_int64 result;
uint32 h32;
uint32 l32;
memcpy(&h32, buf, 4);
memcpy(&l32, buf + 4, 4);
h32 = ntohl(h32);
l32 = ntohl(l32);
result = h32;
result <<= 32;
result |= l32;
return result;
}

40
psycopg/libpq_support.h Normal file
View File

@ -0,0 +1,40 @@
/* libpq_support.h - definitions for libpq_support.c
*
* Copyright (C) 2003-2015 Federico Di Gregorio <fog@debian.org>
*
* This file is part of psycopg.
*
* psycopg2 is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the copyright holders give
* permission to link this program with the OpenSSL library (or with
* modified versions of OpenSSL that use the same license as OpenSSL),
* and distribute linked combinations including the two.
*
* You must obey the GNU Lesser General Public License in all respects for
* all of the code used other than OpenSSL.
*
* psycopg2 is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*/
#ifndef PSYCOPG_LIBPQ_SUPPORT_H
#define PSYCOPG_LIBPQ_SUPPORT_H 1
#include "psycopg/config.h"
/* type and constant definitions from internal postgres includes */
typedef unsigned int uint32;
typedef unsigned PG_INT64_TYPE XLogRecPtr;
#define InvalidXLogRecPtr ((XLogRecPtr) 0)
HIDDEN pg_int64 feGetCurrentTimestamp(void);
HIDDEN void fe_sendint64(pg_int64 i, char *buf);
HIDDEN pg_int64 fe_recvint64(char *buf);
#endif /* !defined(PSYCOPG_LIBPQ_SUPPORT_H) */

View File

@ -40,13 +40,14 @@
#include "psycopg/pgtypes.h"
#include "psycopg/error.h"
#include "psycopg/libpq_support.h"
#include "libpq-fe.h"
/* htonl, ntohl */
#ifdef _WIN32
/* select() */
#include <winsock2.h>
#else
#include <arpa/inet.h>
/* gettimeofday() */
#include "win32_support.h"
#endif
extern HIDDEN PyObject *psyco_DescriptionType;
@ -1520,82 +1521,6 @@ exit:
return ret;
}
/* support routines taken from pg_basebackup/streamutil.c */
/* type and constant definitions from internal postgres includes */
typedef unsigned int uint32;
typedef unsigned PG_INT64_TYPE XLogRecPtr;
#define InvalidXLogRecPtr ((XLogRecPtr) 0)
/* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */
#define UNIX_EPOCH_JDATE 2440588 /* == date2j(1970, 1, 1) */
#define POSTGRES_EPOCH_JDATE 2451545 /* == date2j(2000, 1, 1) */
#define SECS_PER_DAY 86400
#define USECS_PER_SEC 1000000LL
/*
* Frontend version of GetCurrentTimestamp(), since we are not linked with
* backend code. The protocol always uses integer timestamps, regardless of
* server setting.
*/
static pg_int64
feGetCurrentTimestamp(void)
{
pg_int64 result;
struct timeval tp;
gettimeofday(&tp, NULL);
result = (pg_int64) tp.tv_sec -
((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);
result = (result * USECS_PER_SEC) + tp.tv_usec;
return result;
}
/*
* Converts an int64 to network byte order.
*/
static void
fe_sendint64(pg_int64 i, char *buf)
{
uint32 n32;
/* High order half first, since we're doing MSB-first */
n32 = (uint32) (i >> 32);
n32 = htonl(n32);
memcpy(&buf[0], &n32, 4);
/* Now the low order half */
n32 = (uint32) i;
n32 = htonl(n32);
memcpy(&buf[4], &n32, 4);
}
/*
* Converts an int64 from network byte order to native format.
*/
static pg_int64
fe_recvint64(char *buf)
{
pg_int64 result;
uint32 h32;
uint32 l32;
memcpy(&h32, buf, 4);
memcpy(&l32, buf + 4, 4);
h32 = ntohl(h32);
l32 = ntohl(l32);
result = h32;
result <<= 32;
result |= l32;
return result;
}
static int
sendFeedback(PGconn *conn, XLogRecPtr written_lsn, XLogRecPtr fsync_lsn,
int replyRequested)

61
psycopg/win32_support.c Normal file
View File

@ -0,0 +1,61 @@
/* win32_support.c - emulate some functions missing on Win32
*
* Copyright (C) 2003-2015 Federico Di Gregorio <fog@debian.org>
*
* This file is part of psycopg.
*
* psycopg2 is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the copyright holders give
* permission to link this program with the OpenSSL library (or with
* modified versions of OpenSSL that use the same license as OpenSSL),
* and distribute linked combinations including the two.
*
* You must obey the GNU Lesser General Public License in all respects for
* all of the code used other than OpenSSL.
*
* psycopg2 is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*/
#define PSYCOPG_MODULE
#include "psycopg/psycopg.h"
#include "psycopg/win32_support.h"
#ifdef _WIN32
/* millisecond-precision port of gettimeofday for Win32, taken from
src/port/gettimeofday.c in PostgreSQL core */
/* FILETIME of Jan 1 1970 00:00:00. */
static const unsigned __int64 epoch = 116444736000000000ULL;
/*
* timezone information is stored outside the kernel so tzp isn't used anymore.
*
* Note: this function is not for Win32 high precision timing purpose. See
* elapsed_time().
*/
int
gettimeofday(struct timeval * tp, struct timezone * tzp)
{
FILETIME file_time;
SYSTEMTIME system_time;
ULARGE_INTEGER ularge;
GetSystemTime(&system_time);
SystemTimeToFileTime(&system_time, &file_time);
ularge.LowPart = file_time.dwLowDateTime;
ularge.HighPart = file_time.dwHighDateTime;
tp->tv_sec = (long) ((ularge.QuadPart - epoch) / 10000000L);
tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
return 0;
}
#endif /* _WIN32 */

36
psycopg/win32_support.h Normal file
View File

@ -0,0 +1,36 @@
/* win32_support.h - definitions for win32_support.c
*
* Copyright (C) 2003-2015 Federico Di Gregorio <fog@debian.org>
*
* This file is part of psycopg.
*
* psycopg2 is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the copyright holders give
* permission to link this program with the OpenSSL library (or with
* modified versions of OpenSSL that use the same license as OpenSSL),
* and distribute linked combinations including the two.
*
* You must obey the GNU Lesser General Public License in all respects for
* all of the code used other than OpenSSL.
*
* psycopg2 is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*/
#ifndef PSYCOPG_WIN32_SUPPORT_H
#define PSYCOPG_WIN32_SUPPORT_H 1
#include "psycopg/config.h"
#include <sys/time.h>
#ifdef _WIN32
HIDDEN int gettimeofday(struct timeval * tp, struct timezone * tzp);
#endif
#endif /* !defined(PSYCOPG_WIN32_SUPPORT_H) */

View File

@ -462,6 +462,7 @@ data_files = []
sources = [
'psycopgmodule.c',
'green.c', 'pqpath.c', 'utils.c', 'bytes_format.c',
'libpq_support.c', 'win32_support.c',
'connection_int.c', 'connection_type.c',
'cursor_int.c', 'cursor_type.c',
@ -481,6 +482,7 @@ depends = [
'config.h', 'pgtypes.h', 'psycopg.h', 'python.h', 'connection.h',
'cursor.h', 'diagnostics.h', 'error.h', 'green.h', 'lobject.h',
'notify.h', 'pqpath.h', 'xid.h',
'libpq_support.h', 'win32_support.h',
'adapter_asis.h', 'adapter_binary.h', 'adapter_datetime.h',
'adapter_list.h', 'adapter_pboolean.h', 'adapter_pdecimal.h',