pglib 5.9.1__tar.gz → 5.11.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pglib-5.9.1 → pglib-5.11.0}/MANIFEST.in +0 -2
- pglib-5.11.0/PKG-INFO +34 -0
- {pglib-5.9.1 → pglib-5.11.0}/README.rst +2 -2
- pglib-5.11.0/pglib.egg-info/PKG-INFO +34 -0
- {pglib-5.9.1 → pglib-5.11.0}/pglib.egg-info/SOURCES.txt +2 -18
- pglib-5.11.0/pglib.egg-info/requires.txt +3 -0
- pglib-5.11.0/pyproject.toml +40 -0
- pglib-5.11.0/setup.cfg +4 -0
- {pglib-5.9.1 → pglib-5.11.0}/setup.py +11 -63
- {pglib-5.9.1 → pglib-5.11.0}/src/getdata.cpp +3 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/pgarrays.cpp +111 -1
- {pglib-5.9.1 → pglib-5.11.0}/src/pgarrays.h +1 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/pglib.h +1 -0
- {pglib-5.9.1 → pglib-5.11.0}/test/test_async.py +10 -15
- {pglib-5.9.1 → pglib-5.11.0}/test/test_sync.py +9 -1
- {pglib-5.9.1 → pglib-5.11.0}/test/testutils.py +18 -16
- pglib-5.9.1/PKG-INFO +0 -25
- pglib-5.9.1/pglib.egg-info/PKG-INFO +0 -25
- pglib-5.9.1/setup.cfg +0 -10
- {pglib-5.9.1 → pglib-5.11.0}/LICENSE +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/pglib/__init__.py +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/pglib/asyncpglib.py +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/pglib.egg-info/dependency_links.txt +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/pglib.egg-info/top_level.txt +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/byteswap.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/connection.cpp +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/connection.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/conninfoopt.cpp +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/conninfoopt.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/datatypes.cpp +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/datatypes.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/debug.cpp +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/debug.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/enums.cpp +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/enums.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/errors.cpp +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/errors.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/getdata.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/juliandate.cpp +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/juliandate.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/params.cpp +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/params.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/pglib.cpp +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/pgtypes.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/resultset.cpp +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/resultset.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/row.cpp +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/row.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/runtime.cpp +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/runtime.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/type_hstore.cpp +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/type_hstore.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/type_json.cpp +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/type_json.h +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/type_ltree.cpp +0 -0
- {pglib-5.9.1 → pglib-5.11.0}/src/type_ltree.h +0 -0
pglib-5.11.0/PKG-INFO
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pglib
|
|
3
|
+
Version: 5.11.0
|
|
4
|
+
Summary: A PostgreSQL interface
|
|
5
|
+
Author-email: Michael Kleehammer <michael@kleehammer.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://gitlab.com/mkleehammer/pglib
|
|
8
|
+
Project-URL: Repository, https://gitlab.com/mkleehammer/pglib
|
|
9
|
+
Keywords: postgresql,postgres
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Topic :: Database
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/x-rst
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Provides-Extra: test
|
|
22
|
+
Requires-Dist: pytest; extra == "test"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
pglib is a Python 3.10+ module for working with PostgreSQL databases. It is a C extension that
|
|
27
|
+
exposes the `libpq <http://www.postgresql.org/docs/current/static/libpq.html>`_ API. It is
|
|
28
|
+
designed to be small, fast, and as convenient as possible. It provides both synchronous and
|
|
29
|
+
asynchronous APIs.
|
|
30
|
+
|
|
31
|
+
Unlike some libraries, it never modifies the SQL you pass. Parameters are passed using the
|
|
32
|
+
official libpq protocol for parameters.
|
|
33
|
+
|
|
34
|
+
Documentation is available in /docs and online at http://pglib.readthedocs.org
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
pglib is a Python 3.
|
|
3
|
-
exposes the `libpq <http://www.postgresql.org/docs/
|
|
2
|
+
pglib is a Python 3.10+ module for working with PostgreSQL databases. It is a C extension that
|
|
3
|
+
exposes the `libpq <http://www.postgresql.org/docs/current/static/libpq.html>`_ API. It is
|
|
4
4
|
designed to be small, fast, and as convenient as possible. It provides both synchronous and
|
|
5
5
|
asynchronous APIs.
|
|
6
6
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pglib
|
|
3
|
+
Version: 5.11.0
|
|
4
|
+
Summary: A PostgreSQL interface
|
|
5
|
+
Author-email: Michael Kleehammer <michael@kleehammer.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://gitlab.com/mkleehammer/pglib
|
|
8
|
+
Project-URL: Repository, https://gitlab.com/mkleehammer/pglib
|
|
9
|
+
Keywords: postgresql,postgres
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Topic :: Database
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/x-rst
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Provides-Extra: test
|
|
22
|
+
Requires-Dist: pytest; extra == "test"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
pglib is a Python 3.10+ module for working with PostgreSQL databases. It is a C extension that
|
|
27
|
+
exposes the `libpq <http://www.postgresql.org/docs/current/static/libpq.html>`_ API. It is
|
|
28
|
+
designed to be small, fast, and as convenient as possible. It provides both synchronous and
|
|
29
|
+
asynchronous APIs.
|
|
30
|
+
|
|
31
|
+
Unlike some libraries, it never modifies the SQL you pass. Parameters are passed using the
|
|
32
|
+
official libpq protocol for parameters.
|
|
33
|
+
|
|
34
|
+
Documentation is available in /docs and online at http://pglib.readthedocs.org
|
|
@@ -1,30 +1,14 @@
|
|
|
1
1
|
LICENSE
|
|
2
2
|
MANIFEST.in
|
|
3
3
|
README.rst
|
|
4
|
-
|
|
4
|
+
pyproject.toml
|
|
5
5
|
setup.py
|
|
6
|
-
/home/mkleehammer/dev/pglib/src/connection.cpp
|
|
7
|
-
/home/mkleehammer/dev/pglib/src/conninfoopt.cpp
|
|
8
|
-
/home/mkleehammer/dev/pglib/src/datatypes.cpp
|
|
9
|
-
/home/mkleehammer/dev/pglib/src/debug.cpp
|
|
10
|
-
/home/mkleehammer/dev/pglib/src/enums.cpp
|
|
11
|
-
/home/mkleehammer/dev/pglib/src/errors.cpp
|
|
12
|
-
/home/mkleehammer/dev/pglib/src/getdata.cpp
|
|
13
|
-
/home/mkleehammer/dev/pglib/src/juliandate.cpp
|
|
14
|
-
/home/mkleehammer/dev/pglib/src/params.cpp
|
|
15
|
-
/home/mkleehammer/dev/pglib/src/pgarrays.cpp
|
|
16
|
-
/home/mkleehammer/dev/pglib/src/pglib.cpp
|
|
17
|
-
/home/mkleehammer/dev/pglib/src/resultset.cpp
|
|
18
|
-
/home/mkleehammer/dev/pglib/src/row.cpp
|
|
19
|
-
/home/mkleehammer/dev/pglib/src/runtime.cpp
|
|
20
|
-
/home/mkleehammer/dev/pglib/src/type_hstore.cpp
|
|
21
|
-
/home/mkleehammer/dev/pglib/src/type_json.cpp
|
|
22
|
-
/home/mkleehammer/dev/pglib/src/type_ltree.cpp
|
|
23
6
|
pglib/__init__.py
|
|
24
7
|
pglib/asyncpglib.py
|
|
25
8
|
pglib.egg-info/PKG-INFO
|
|
26
9
|
pglib.egg-info/SOURCES.txt
|
|
27
10
|
pglib.egg-info/dependency_links.txt
|
|
11
|
+
pglib.egg-info/requires.txt
|
|
28
12
|
pglib.egg-info/top_level.txt
|
|
29
13
|
src/byteswap.h
|
|
30
14
|
src/connection.cpp
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pglib"
|
|
7
|
+
version = "5.11.0"
|
|
8
|
+
description = "A PostgreSQL interface"
|
|
9
|
+
readme = "README.rst"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
requires-python = ">=3.10"
|
|
13
|
+
authors = [
|
|
14
|
+
{name = "Michael Kleehammer", email = "michael@kleehammer.com"}
|
|
15
|
+
]
|
|
16
|
+
keywords = ["postgresql", "postgres"]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 5 - Production/Stable",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"Topic :: Database",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.14",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
Homepage = "https://gitlab.com/mkleehammer/pglib"
|
|
30
|
+
Repository = "https://gitlab.com/mkleehammer/pglib"
|
|
31
|
+
|
|
32
|
+
[project.optional-dependencies]
|
|
33
|
+
test = ["pytest"]
|
|
34
|
+
|
|
35
|
+
[tool.setuptools.packages.find]
|
|
36
|
+
where = ["."]
|
|
37
|
+
include = ["pglib*"]
|
|
38
|
+
|
|
39
|
+
[tool.pytest.ini_options]
|
|
40
|
+
testpaths = ["test"]
|
pglib-5.11.0/setup.cfg
ADDED
|
@@ -1,36 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
|
|
3
|
-
import sys
|
|
4
|
-
import
|
|
3
|
+
import sys
|
|
4
|
+
import os
|
|
5
|
+
import re
|
|
6
|
+
import subprocess
|
|
7
|
+
import sysconfig
|
|
5
8
|
from os.path import join, abspath, dirname
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
from setuptools import setup, Extension
|
|
9
|
-
except:
|
|
10
|
-
from distutils.core import setup, Extension
|
|
11
|
-
|
|
12
|
-
long_description = """\
|
|
13
|
-
A PostgreSQL interface for Python.
|
|
14
|
-
|
|
15
|
-
This provides an interface to the libpq library. It is not an DB API
|
|
16
|
-
library, but is instead designed to match the interface PostgreSQL
|
|
17
|
-
offers.
|
|
18
|
-
"""
|
|
10
|
+
from setuptools import setup, Extension
|
|
19
11
|
|
|
20
12
|
|
|
21
13
|
def _get_osx_sdkpath():
|
|
22
14
|
"""
|
|
23
15
|
Use xcodebuild to find the latest installed OS X SDK and return the path to it.
|
|
24
16
|
"""
|
|
25
|
-
# The output is in blank line separated sections. Find the section for the latest OS/X SDK
|
|
26
|
-
# and get the Path entry.
|
|
27
|
-
|
|
28
17
|
output = subprocess.check_output(['xcodebuild', '-version', '-sdk']).strip().decode('utf-8')
|
|
29
18
|
|
|
30
19
|
highest = (0, 0)
|
|
31
|
-
path
|
|
20
|
+
path = None
|
|
32
21
|
|
|
33
|
-
# MacOSX10.8.sdk - OS X 10.8 (macosx10.8)
|
|
34
22
|
resection = re.compile(r'^.*- (?:OS X|macOS) (\d+)\.(\d+)')
|
|
35
23
|
repath = re.compile('^Path: ([^\n]+)', re.MULTILINE)
|
|
36
24
|
|
|
@@ -50,27 +38,14 @@ def _get_osx_sdkpath():
|
|
|
50
38
|
return path
|
|
51
39
|
|
|
52
40
|
|
|
53
|
-
def getoutput(cmd):
|
|
54
|
-
pipe = os.popen(cmd, 'r')
|
|
55
|
-
text = pipe.read().rstrip('\n')
|
|
56
|
-
status = pipe.close() or 0
|
|
57
|
-
return status, text
|
|
58
|
-
|
|
59
|
-
|
|
60
41
|
def _get_files():
|
|
61
|
-
return [
|
|
42
|
+
return [join('src', f) for f in os.listdir('src') if f.endswith('.cpp')]
|
|
62
43
|
|
|
63
44
|
|
|
64
45
|
def _get_settings():
|
|
65
|
-
|
|
66
|
-
# version = get_version()
|
|
67
|
-
#
|
|
68
|
-
# settings = { 'define_macros' : [ ('PGLIB_VERSION', version) ] }
|
|
69
|
-
|
|
70
46
|
settings = {'define_macros': []}
|
|
71
47
|
|
|
72
|
-
#
|
|
73
|
-
# command.
|
|
48
|
+
# Custom build options
|
|
74
49
|
for option in ['assert', 'trace', 'leak-check']:
|
|
75
50
|
try:
|
|
76
51
|
sys.argv.remove('--%s' % option)
|
|
@@ -90,17 +65,12 @@ def _get_settings():
|
|
|
90
65
|
]
|
|
91
66
|
|
|
92
67
|
if '--debug' in sys.argv:
|
|
93
|
-
# TODO: The build command already has debug. Pass it in.
|
|
94
68
|
sys.argv.remove('--debug')
|
|
95
69
|
settings['extra_compile_args'].extend('/Od /Ge /GS /GZ /RTC1 /Wp64 /Yd'.split())
|
|
96
70
|
|
|
97
71
|
settings['libraries'] = ['libpq', 'Ws2_32']
|
|
98
72
|
|
|
99
73
|
elif sys.platform == 'darwin':
|
|
100
|
-
# Apple is not making it easy for non-Xcode builds. We'll always build with the latest
|
|
101
|
-
# SDK we can find but we'll set the version we are targeting to the same one that
|
|
102
|
-
# Python was built with.
|
|
103
|
-
|
|
104
74
|
sdkpath = _get_osx_sdkpath()
|
|
105
75
|
|
|
106
76
|
settings['include_dirs'] = [
|
|
@@ -109,7 +79,7 @@ def _get_settings():
|
|
|
109
79
|
subprocess.check_output(['pg_config', '--includedir']).strip().decode('utf-8')
|
|
110
80
|
]
|
|
111
81
|
settings['library_dirs'] = [subprocess.check_output(['pg_config', '--libdir']).strip().decode('utf-8')]
|
|
112
|
-
settings['libraries']
|
|
82
|
+
settings['libraries'] = ['pq']
|
|
113
83
|
|
|
114
84
|
settings['define_macros'].append(('MAC_OS_X_VERSION_10_7',))
|
|
115
85
|
|
|
@@ -117,37 +87,15 @@ def _get_settings():
|
|
|
117
87
|
|
|
118
88
|
else:
|
|
119
89
|
# Other posix-like: Linux, Solaris, etc.
|
|
120
|
-
|
|
121
90
|
settings['include_dirs'] = [subprocess.check_output(['pg_config', '--includedir']).strip().decode('utf-8')]
|
|
122
91
|
settings['library_dirs'] = [subprocess.check_output(['pg_config', '--libdir']).strip().decode('utf-8')]
|
|
123
|
-
settings['libraries']
|
|
92
|
+
settings['libraries'] = ['pq']
|
|
124
93
|
|
|
125
|
-
# Python functions take a lot of 'char *' that really should be const. gcc complains about this *a lot*
|
|
126
94
|
settings['extra_compile_args'] = ['-Wno-write-strings']
|
|
127
95
|
|
|
128
96
|
return settings
|
|
129
97
|
|
|
130
98
|
|
|
131
99
|
setup(
|
|
132
|
-
name='pglib',
|
|
133
|
-
version='5.9.1',
|
|
134
|
-
description='A PostgreSQL interface',
|
|
135
|
-
long_description=long_description,
|
|
136
|
-
maintainer='Michael Kleehammer',
|
|
137
|
-
maintainer_email='michael@kleehammer.com',
|
|
138
|
-
packages=['pglib'],
|
|
139
100
|
ext_modules=[Extension('_pglib', _get_files(), **_get_settings())],
|
|
140
|
-
keywords='postgresql postgres',
|
|
141
|
-
tests_require=['pytest'],
|
|
142
|
-
url='https://gitlab.com/mkleehammer/pglib',
|
|
143
|
-
license='MIT',
|
|
144
|
-
classifiers=[
|
|
145
|
-
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
|
146
|
-
'Development Status :: 5 - Production/Stable',
|
|
147
|
-
'Intended Audience :: Developers',
|
|
148
|
-
'Topic :: Database',
|
|
149
|
-
'License :: OSI Approved :: MIT License',
|
|
150
|
-
'Programming Language :: Python :: 3',
|
|
151
|
-
'Programming Language :: Python :: 3 :: Only'
|
|
152
|
-
]
|
|
153
101
|
)
|
|
@@ -91,6 +91,11 @@ inline uint32_t ReadU32(const char ** pp) {
|
|
|
91
91
|
return htonl(n);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
inline double ReadDouble(const char ** pp) {
|
|
95
|
+
double n = **(double**)pp;
|
|
96
|
+
*pp += sizeof(double);
|
|
97
|
+
return swapdouble(n);
|
|
98
|
+
}
|
|
94
99
|
|
|
95
100
|
|
|
96
101
|
static PyObject* FindFirstParam(Object& seq)
|
|
@@ -375,6 +380,69 @@ bool BindLongArray(Params& params, Object& seq, Py_ssize_t cItems)
|
|
|
375
380
|
}
|
|
376
381
|
|
|
377
382
|
|
|
383
|
+
static bool BindFloatArray(Params& params, Object& seq, Py_ssize_t cItems)
|
|
384
|
+
{
|
|
385
|
+
// Loop through the array and make sure each entry is a float (or None).
|
|
386
|
+
|
|
387
|
+
int cNonNull = 0; // count of non-null items
|
|
388
|
+
|
|
389
|
+
for (Py_ssize_t iItem = 0; iItem < cItems; iItem++)
|
|
390
|
+
{
|
|
391
|
+
PyObject* item = PySequence_Fast_GET_ITEM(seq.Get(), iItem);
|
|
392
|
+
if (item != Py_None)
|
|
393
|
+
{
|
|
394
|
+
if (!PyFloat_Check(item))
|
|
395
|
+
{
|
|
396
|
+
SetStringError(Error, "array parameters must all be the same type");
|
|
397
|
+
return false;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
cNonNull += 1;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
int cbItem = sizeof(double);
|
|
405
|
+
|
|
406
|
+
Py_ssize_t cb = sizeof(ArrayHeader) +
|
|
407
|
+
(4 * cItems) + // length indicators
|
|
408
|
+
(cbItem * cNonNull); // values
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
WriteBuffer buf = params.Allocate(cb);
|
|
412
|
+
if (!buf)
|
|
413
|
+
return false;
|
|
414
|
+
|
|
415
|
+
ArrayHeader* phdr = (ArrayHeader*)buf.pbStart;
|
|
416
|
+
phdr->ndim = htonl(1);
|
|
417
|
+
phdr->flags = htonl(1);
|
|
418
|
+
phdr->oid = htonl(FLOAT8OID);
|
|
419
|
+
phdr->dim = htonl(cItems);
|
|
420
|
+
phdr->lbound = htonl(1);
|
|
421
|
+
|
|
422
|
+
char* pT = &phdr->buffer[0];
|
|
423
|
+
|
|
424
|
+
for (Py_ssize_t iItem = 0; iItem < cItems; iItem++)
|
|
425
|
+
{
|
|
426
|
+
PyObject* item = PySequence_Fast_GET_ITEM(seq.Get(), iItem);
|
|
427
|
+
if (item != Py_None)
|
|
428
|
+
{
|
|
429
|
+
(*(uint32_t*)pT) = htonl(cbItem); // could be swapped and cached
|
|
430
|
+
pT += 4;
|
|
431
|
+
|
|
432
|
+
(*(double*)pT) = swapdouble(PyFloat_AS_DOUBLE(item));
|
|
433
|
+
pT += cbItem;
|
|
434
|
+
}
|
|
435
|
+
else
|
|
436
|
+
{
|
|
437
|
+
(*(uint32_t*)pT) = htonl(-1);
|
|
438
|
+
pT += 4;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
return params.Bind(FLOAT8ARRAYOID, buf, FORMAT_BINARY);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
|
|
378
446
|
bool BindArray(Params& params, PyObject* param)
|
|
379
447
|
{
|
|
380
448
|
// Binds a list or tuple as an array. All elements must be of the same type, though None
|
|
@@ -399,7 +467,10 @@ bool BindArray(Params& params, PyObject* param)
|
|
|
399
467
|
if (PyDate_Check(first))
|
|
400
468
|
return BindDateArray(params, seq, cItems);
|
|
401
469
|
|
|
402
|
-
|
|
470
|
+
if (PyFloat_Check(first))
|
|
471
|
+
return BindFloatArray(params, seq, cItems);
|
|
472
|
+
|
|
473
|
+
SetStringError(Error, "Unhandled type in array parameter");
|
|
403
474
|
|
|
404
475
|
return false;
|
|
405
476
|
}
|
|
@@ -527,6 +598,45 @@ PyObject* GetInt8Array(const char* p)
|
|
|
527
598
|
}
|
|
528
599
|
|
|
529
600
|
|
|
601
|
+
PyObject* GetFloat8Array(const char* p)
|
|
602
|
+
{
|
|
603
|
+
// Reads an FLOAT8ARRAYOID array result and returns a list of floats.
|
|
604
|
+
|
|
605
|
+
ArrayInfo info;
|
|
606
|
+
if (!ReadArrayInfo(p, info, FLOAT8OID)) {
|
|
607
|
+
return 0;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
Object list(PyList_New(info.len));
|
|
611
|
+
if (!list)
|
|
612
|
+
return 0;
|
|
613
|
+
|
|
614
|
+
if (info.len) {
|
|
615
|
+
const char* data = info.data;
|
|
616
|
+
|
|
617
|
+
for (uint32_t i = 0; i < info.len; i++)
|
|
618
|
+
{
|
|
619
|
+
int32_t len = Read32(&data);
|
|
620
|
+
|
|
621
|
+
if (len == -1)
|
|
622
|
+
{
|
|
623
|
+
Py_INCREF(Py_None);
|
|
624
|
+
PyList_SET_ITEM(list.Get(), i, Py_None);
|
|
625
|
+
}
|
|
626
|
+
else
|
|
627
|
+
{
|
|
628
|
+
double val = ReadDouble(&data);
|
|
629
|
+
PyObject* o = PyFloat_FromDouble(val);
|
|
630
|
+
if (!o)
|
|
631
|
+
return 0;
|
|
632
|
+
|
|
633
|
+
PyList_SET_ITEM(list.Get(), i, o);
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
return list.Detach();
|
|
639
|
+
}
|
|
530
640
|
|
|
531
641
|
PyObject* GetTextArray(const char* p)
|
|
532
642
|
{
|
|
@@ -44,8 +44,7 @@ def test_async():
|
|
|
44
44
|
assert row.b == 3
|
|
45
45
|
assert row[1] == 3
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
loop.run_until_complete(_t())
|
|
47
|
+
asyncio.run(_t())
|
|
49
48
|
|
|
50
49
|
|
|
51
50
|
def test_async_params():
|
|
@@ -60,8 +59,7 @@ def test_async_params():
|
|
|
60
59
|
assert row.b == 2
|
|
61
60
|
assert row[1] == 2
|
|
62
61
|
|
|
63
|
-
|
|
64
|
-
loop.run_until_complete(_t())
|
|
62
|
+
asyncio.run(_t())
|
|
65
63
|
|
|
66
64
|
|
|
67
65
|
def test_async_notify():
|
|
@@ -84,8 +82,7 @@ def test_async_notify():
|
|
|
84
82
|
assert item == sent[0]
|
|
85
83
|
sent.pop(0)
|
|
86
84
|
|
|
87
|
-
|
|
88
|
-
loop.run_until_complete(_t())
|
|
85
|
+
asyncio.run(_t())
|
|
89
86
|
|
|
90
87
|
|
|
91
88
|
def test_notify_and_command():
|
|
@@ -112,8 +109,7 @@ def test_notify_and_command():
|
|
|
112
109
|
item = ns[0]
|
|
113
110
|
assert item == ('test', 'both')
|
|
114
111
|
|
|
115
|
-
|
|
116
|
-
loop.run_until_complete(_t())
|
|
112
|
+
asyncio.run(_t())
|
|
117
113
|
|
|
118
114
|
|
|
119
115
|
def test_notification_wait():
|
|
@@ -132,9 +128,10 @@ def test_notification_wait():
|
|
|
132
128
|
cnxn = await pglib.connect_async(CONNINFO)
|
|
133
129
|
await cnxn.notify('test')
|
|
134
130
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
131
|
+
async def _run_both():
|
|
132
|
+
await asyncio.gather(_listener(), _notifier())
|
|
133
|
+
|
|
134
|
+
asyncio.run(_run_both())
|
|
138
135
|
|
|
139
136
|
|
|
140
137
|
def test_notification_timeout():
|
|
@@ -144,8 +141,7 @@ def test_notification_timeout():
|
|
|
144
141
|
ns = await cnxn.notifications(timeout=0.25)
|
|
145
142
|
assert ns == []
|
|
146
143
|
|
|
147
|
-
|
|
148
|
-
loop.run_until_complete(_t())
|
|
144
|
+
asyncio.run(_t())
|
|
149
145
|
|
|
150
146
|
|
|
151
147
|
def test_close():
|
|
@@ -156,5 +152,4 @@ def test_close():
|
|
|
156
152
|
cnxn.close()
|
|
157
153
|
cnxn = None
|
|
158
154
|
|
|
159
|
-
|
|
160
|
-
loop.run_until_complete(_t())
|
|
155
|
+
asyncio.run(_t())
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
# Run with pytest.
|
|
3
2
|
|
|
4
3
|
# pylint: disable=missing-function-docstring,redefined-outer-name,unidiomatic-typecheck
|
|
@@ -711,6 +710,15 @@ def test_array_bigint(cnxn):
|
|
|
711
710
|
assert result == value
|
|
712
711
|
|
|
713
712
|
|
|
713
|
+
def test_array_float(cnxn):
|
|
714
|
+
cnxn.execute("create table t1(id int, v float[])")
|
|
715
|
+
value = [None, -100000.0, -32768.0, -123.45, -1.0, 0.0,
|
|
716
|
+
1.0, 123.45, 32767.0, 2147483647.0, 10101010.8989]
|
|
717
|
+
cnxn.execute("insert into t1 values (1, $1)", value)
|
|
718
|
+
result = cnxn.fetchval("select v from t1")
|
|
719
|
+
assert result == value
|
|
720
|
+
|
|
721
|
+
|
|
714
722
|
def test_array_text(cnxn):
|
|
715
723
|
cnxn.execute("create table t1(id int, v text[])")
|
|
716
724
|
value = ['one', None, 'two']
|
|
@@ -10,21 +10,22 @@ def add_to_path():
|
|
|
10
10
|
it to be tested without installing it.
|
|
11
11
|
"""
|
|
12
12
|
# Put the root directory into the path first so we pick up the Python code from the source
|
|
13
|
-
# directories
|
|
13
|
+
# directories and any extension built via editable install.
|
|
14
14
|
|
|
15
15
|
root = dirname(dirname(abspath(__file__)))
|
|
16
16
|
sys.path.insert(0, root)
|
|
17
17
|
|
|
18
|
-
#
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
# Check if the extension is already importable (installed via pip or editable install)
|
|
19
|
+
try:
|
|
20
|
+
import _pglib
|
|
21
|
+
return
|
|
22
|
+
except ImportError:
|
|
23
|
+
pass
|
|
21
24
|
|
|
25
|
+
# Fall back to searching the build directory for legacy `python setup.py build` workflow.
|
|
22
26
|
prefix = '_pglib'
|
|
23
|
-
|
|
24
27
|
library_names = [prefix + ext for ext in EXTENSION_SUFFIXES]
|
|
25
28
|
|
|
26
|
-
# Only go into directories that match the current Python's version number.
|
|
27
|
-
|
|
28
29
|
dir_suffix = (
|
|
29
30
|
'-%s.%s' % (sys.version_info[0], sys.version_info[1]),
|
|
30
31
|
'-%s%s' % (sys.version_info[0], sys.version_info[1]),
|
|
@@ -33,17 +34,18 @@ def add_to_path():
|
|
|
33
34
|
|
|
34
35
|
build = join(dirname(dirname(abspath(__file__))), 'build')
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
for
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
if os.path.isdir(build):
|
|
38
|
+
for root, dirs, files in os.walk(build):
|
|
39
|
+
for d in dirs[:]:
|
|
40
|
+
if not d.endswith(dir_suffix):
|
|
41
|
+
dirs.remove(d)
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
for name in library_names:
|
|
44
|
+
if name in files:
|
|
45
|
+
sys.path.insert(1, root)
|
|
46
|
+
return
|
|
45
47
|
|
|
46
|
-
sys.exit('Did not find
|
|
48
|
+
sys.exit('Did not find _pglib extension. Run: pip install -e .')
|
|
47
49
|
|
|
48
50
|
|
|
49
51
|
_TESTSTR = '0123456789-abcdefghijklmnopqrstuvwxyz-'
|
pglib-5.9.1/PKG-INFO
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: pglib
|
|
3
|
-
Version: 5.9.1
|
|
4
|
-
Summary: A PostgreSQL interface
|
|
5
|
-
Home-page: https://gitlab.com/mkleehammer/pglib
|
|
6
|
-
Maintainer: Michael Kleehammer
|
|
7
|
-
Maintainer-email: michael@kleehammer.com
|
|
8
|
-
License: MIT
|
|
9
|
-
Keywords: postgresql postgres
|
|
10
|
-
Platform: UNKNOWN
|
|
11
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
-
Classifier: Intended Audience :: Developers
|
|
13
|
-
Classifier: Topic :: Database
|
|
14
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
-
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
-
License-File: LICENSE
|
|
18
|
-
|
|
19
|
-
A PostgreSQL interface for Python.
|
|
20
|
-
|
|
21
|
-
This provides an interface to the libpq library. It is not an DB API
|
|
22
|
-
library, but is instead designed to match the interface PostgreSQL
|
|
23
|
-
offers.
|
|
24
|
-
|
|
25
|
-
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: pglib
|
|
3
|
-
Version: 5.9.1
|
|
4
|
-
Summary: A PostgreSQL interface
|
|
5
|
-
Home-page: https://gitlab.com/mkleehammer/pglib
|
|
6
|
-
Maintainer: Michael Kleehammer
|
|
7
|
-
Maintainer-email: michael@kleehammer.com
|
|
8
|
-
License: MIT
|
|
9
|
-
Keywords: postgresql postgres
|
|
10
|
-
Platform: UNKNOWN
|
|
11
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
-
Classifier: Intended Audience :: Developers
|
|
13
|
-
Classifier: Topic :: Database
|
|
14
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
-
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
-
License-File: LICENSE
|
|
18
|
-
|
|
19
|
-
A PostgreSQL interface for Python.
|
|
20
|
-
|
|
21
|
-
This provides an interface to the libpq library. It is not an DB API
|
|
22
|
-
library, but is instead designed to match the interface PostgreSQL
|
|
23
|
-
offers.
|
|
24
|
-
|
|
25
|
-
|
pglib-5.9.1/setup.cfg
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|