Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
f36e7ff0
Commit
f36e7ff0
authored
Oct 02, 2000
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update for PyGreSQL 3.0, from D'Arcy J.M. Cain
parent
0bd84442
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
1981 additions
and
1373 deletions
+1981
-1373
doc/TODO
doc/TODO
+1
-1
src/interfaces/python/Announce
src/interfaces/python/Announce
+43
-15
src/interfaces/python/ChangeLog
src/interfaces/python/ChangeLog
+24
-1
src/interfaces/python/PyGreSQL.spec
src/interfaces/python/PyGreSQL.spec
+57
-0
src/interfaces/python/README
src/interfaces/python/README
+109
-30
src/interfaces/python/README.linux
src/interfaces/python/README.linux
+5
-0
src/interfaces/python/mkdefines
src/interfaces/python/mkdefines
+1
-1
src/interfaces/python/pg.py
src/interfaces/python/pg.py
+28
-16
src/interfaces/python/pgdb.py
src/interfaces/python/pgdb.py
+401
-0
src/interfaces/python/pgmodule.c
src/interfaces/python/pgmodule.c
+1269
-434
src/interfaces/python/pgsqldb.py
src/interfaces/python/pgsqldb.py
+0
-46
src/interfaces/python/setup.py
src/interfaces/python/setup.py
+43
-0
src/interfaces/python/tutorial/advanced.py
src/interfaces/python/tutorial/advanced.py
+0
-171
src/interfaces/python/tutorial/basics.py
src/interfaces/python/tutorial/basics.py
+0
-284
src/interfaces/python/tutorial/func.py
src/interfaces/python/tutorial/func.py
+0
-193
src/interfaces/python/tutorial/pgtools.py
src/interfaces/python/tutorial/pgtools.py
+0
-48
src/interfaces/python/tutorial/syscat.py
src/interfaces/python/tutorial/syscat.py
+0
-133
No files found.
doc/TODO
View file @
f36e7ff0
...
...
@@ -250,7 +250,7 @@ MISC
* allow configuration of maximum number of open files
* Remove pg_listener index
* Remove ANALYZE from VACUUM so it can be run separately without locks
* Gather more accurate statistics using indexes
* Gather more accurate
disbursion
statistics using indexes
* Improve statistics storage in pg_class [performance]
* Improve VACUUM speed with indexes [vacuum]
* -BSD/OS does not support locale because there is no LC_MESSAGES (Bruce)
...
...
src/interfaces/python/Announce
View file @
f36e7ff0
Announce
:
Release
of
PyGreSQL
version
2.4
Announce: Release of PyGreSQL version
3.0
===============================================
PyGreSQL
v
2
.4
has
been
released
.
PyGreSQL v
3.0
has been released.
It is available at: ftp://ftp.druid.net/pub/distrib/PyGreSQL.tgz. If
you
are
on
NetBSD
,
look
in
the
packages
directory
under
databases
.
If
it
isn
't there yet, it should be there shortly. You can also pick up the
package files from ftp://ftp.druid.net/pub/distrib/pygresql.pkg.tgz.
There is also a package in the FreeBSD ports collection but as I write
this it is at version 2.1. I will try to get that updated as well.
you are running NetBSD, look in the packages directory under databases.
There is also a package in the FreeBSD ports collection.
PostgreSQL is a database system derived from Postgres4.2. It conforms
to (most of) ANSI SQL and offers many interesting capabilities (C
...
...
@@ -28,19 +25,49 @@ PyGreSQL is a python module that interfaces to a PostgreSQL database. It
embeds the PostgreSQL query library to allow easy use of the powerful
PostgreSQL features from a Python script.
I wanted to have DB-SIG API support in the next release but there ar
e
enough fixes and improvements to make one more release before starting
on that. The next version will be 3.0 and have the DB-SIG API support.
Note that I said this for 2.4 but some required changes from others have
been slow in coming (I'
m
not
complaining
,
people
do
have
lives
)
and
there
were
enough
fixes
that
I
didn
't want to keep them from a release
.
This release of PyGreSQL is the first DB-SIG API. That's why we hav
e
a bump in the major number. There is also a potential problem in
backwards compatibility. Previously when there was a NULL in a returned
field it was returned as a blank. Now it is more properly returned as
a Python None. Any scripts that expect NULLs to be blanks will have
problems with this
.
PyGreSQL 2.3 was developed and tested on a NetBSD 1.3_BETA system. It
Due to the fact that the DB-API is brand new, it is expected that there
will be a 3.1 release shortly with corrections once many people have
had a chance to test it.
See the other changes below or in the Changelog file.
PyGreSQL 2.0 was developed and tested on a NetBSD 1.3_BETA system. It
is based on the PyGres95 code written by Pascal Andre,
andre@chimay.via.ecp.fr. I changed the version to 2.0 and updated the
code for Python 1.5 and PostgreSQL 6.2.1. While I was at it I upgraded
the code to use full ANSI style prototypes and changed the order of
arguments to connect. Later versions are fixes and enhancements to that.
The latest version of PyGreSQL works with Python 1.5.2 and PostgreSQL 6.5.
Important changes from PyGreSQL 2.4 to PyGreSQL 3.0:
- Remove strlen() call from pglarge_write() and get size from object.
(Richard@Bouska.cz)
- Add a little more error checking to the quote function in the wrapper
- Add extra checking in _quote function
- Wrap query in pg.py for debugging
- Add DB-API 2.0 support to pgmodule.c (andre@via.ecp.fr)
- Add DB-API 2.0 wrapper pgdb.py (andre@via.ecp.fr)
- Correct keyword clash (temp) in tutorial
- Clean up layout of tutorial
- Return NULL values as None (rlawrence@lastfoot.com) (WARNING: This
will cause backwards compatibility issues.)
- Change None to NULL in insert and update
- Change hash-bang lines to use /usr/bin/env
- Clearing date should be blank (NULL) not TODAY
- Quote backslashes in strings in _quote (brian@CSUA.Berkeley.EDU)
- Expanded and clarified build instructions (tbryan@starship.python.net)
- Make code thread safe (Jerome.Alet@unice.fr)
- Add README.distutils (mwa@gate.net & jeremy@cnri.reston.va.us)
- Many fixes and increased DB-API compliance by chifungfan@yahoo.com,
tony@printra.net, jeremy@alum.mit.edu and others to get the final
version ready to release.
Important changes from PyGreSQL 2.3 to PyGreSQL 2.4:
- Insert returns None if the user doesn't have select permissions
...
...
@@ -48,10 +75,11 @@ Important changes from PyGreSQL 2.3 to PyGreSQL 2.4:
not select permissions on a table.
- Added ntuples() method to query object (brit@druid.net)
- Corrected a bug related to getresult() and the money type
-
Corrected
a
bu
t
related
to
negative
money
amounts
- Corrected a bu
g
related to negative money amounts
- Allow update based on primary key if munged oid not available and
table has a primary key
- Add many __doc__ strings. (andre@via.ecp.fr)
- Get method works with views if key specified
Important changes from PyGreSQL 2.2 to PyGreSQL 2.3:
- connect.host returns "localhost" when connected to Unix socket
...
...
src/interfaces/python/ChangeLog
View file @
f36e7ff0
...
...
@@ -5,16 +5,39 @@ This software is copyright (c) 1995, Pascal Andre (andre@via.ecp.fr)
Further copyright 1997, 1998 and 1999 by D'Arcy J.M. Cain (darcy@druid.net)
See file README for copyright information.
Version 3.0
- Remove strlen() call from pglarge_write() and get size from object.
(Richard@Bouska.cz)
- Add a little more error checking to the quote function in the wrapper
- Add extra checking in _quote function
- Wrap query in pg.py for debugging
- Add DB-API 2.0 support to pgmodule.c (andre@via.ecp.fr)
- Add DB-API 2.0 wrapper pgdb.py (andre@via.ecp.fr)
- Correct keyword clash (temp) in tutorial
- Clean up layout of tutorial
- Return NULL values as None (rlawrence@lastfoot.com)
- Change None to NULL in insert and update
- Change hash-bang lines to use /usr/bin/env
- Clearing date should be blank (NULL) not TODAY
- Quote backslashes in strings in _quote (brian@CSUA.Berkeley.EDU)
- Expanded and clarified build instructions (tbryan@starship.python.net)
- Make code thread safe (Jerome.Alet@unice.fr)
- Add README.distutils (mwa@gate.net & jeremy@cnri.reston.va.us)
- Many fixes and increased DB-API compliance by chifungfan@yahoo.com,
tony@printra.net, jeremy@alum.mit.edu and others to get the final
version ready to release.
Version 2.4
- Insert returns None if the user doesn't have select permissions
on the table. It can (and does) happen that one has insert but
not select permissions on a table.
- Added ntuples() method to query object (brit@druid.net)
- Corrected a bug related to getresult() and the money type
- Corrected a bu
t
related to negative money amounts
- Corrected a bu
g
related to negative money amounts
- Allow update based on primary key if munged oid not available and
table has a primary key
- Add many __doc__ strings. (andre@via.ecp.fr)
- Get method works with views if key specified
Version 2.3
- connect.host returns "localhost" when connected to Unix socket
...
...
src/interfaces/python/PyGreSQL.spec
0 → 100644
View file @
f36e7ff0
%define version 3.0
%define release pre20000310
%define name PyGreSQL
%define pythonversion 1.5
Source: %{name}-%{version}-%{release}.tgz
Summary: A Python interface for PostgreSQL database.
Name: %{name}
Version: %{version}
Release: %{release}
#Patch:
Group: Applications/Databases
BuildRoot: /tmp/rpmbuild_%{name}
Copyright: GPL-like
Requires: python >= %{pythonversion}, postgresql
Packager: Hartmut Goebel <hartmut@goebel.noris.de>
Vendor: D'Arcy J.M. Cain <darcy@druid.net>
URL: http://www.druid.net/pygresql/
%changelog
#* Tue Oct 06 1998 Fabio Coatti <cova@felix.unife.it>
#- fixed installation directory files list
%description
PyGreSQL is a python module that interfaces to a PostgreSQL database. It
embeds the PostgreSQL query library to allow easy use of the powerful
PostgreSQL features from a Python script.
Version 3.0 includes DB-API 2.0 support.
%prep
rm -rf $RPM_BUILD_ROOT
%setup -n %{name}-%{version}-%{release}
#%patch
%build
mkdir -p $RPM_BUILD_ROOT/usr/lib/python%{pythonversion}/lib-dynload
cc -fpic -shared -o $RPM_BUILD_ROOT/usr/lib/python%{pythonversion}/lib-dynload/_pg.so -I/usr/include/pgsql/ -I/usr/include/python1.5 pgmodule.c -lpq
## import fails, since _pg is not yet installed
python -c 'import pg' || true
python -c 'import pgdb' || true
%install
cp *.py *.pyc $RPM_BUILD_ROOT/usr/lib/python%{pythonversion}/
cd $RPM_BUILD_ROOT
find . -type f | sed 's,^\.,\%attr(-\,root\,root) ,' > $RPM_BUILD_DIR/file.list.%{name}
find . -type l | sed 's,^\.,\%attr(-\,root\,root) ,' >> $RPM_BUILD_DIR/file.list.%{name}
%files -f ../file.list.%{name}
%doc %attr(-,root,root) Announce ChangeLog README tutorial
%clean
rm -rf $RPM_BUILD_ROOT
cd $RPM_BUILD_DIR
rm -rf %{name}-%{version}-%{release} file.list.%{name}
src/interfaces/python/README
View file @
f36e7ff0
PyGreSQL
-
v2
.
4
:
PostgreSQL
module
for
Python
PyGreSQL
-
v2
.
5
:
PostgreSQL
module
for
Python
==============================================
0.
Copyright
notice
===================
PyGreSQL
,
version
2.
4
PyGreSQL
,
version
2.
5
A
Python
interface
for
PostgreSQL
database
.
Written
by
D
'Arcy J.M. Cain, darcy@druid.net<BR>
Based heavily on code written by Pascal Andre, andre@chimay.via.ecp.fr.
...
...
@@ -57,7 +57,8 @@ PyGreSQL 2.0 was developed and tested on a NetBSD 1.3_BETA system. It is
based
on
the
PyGres95
code
written
by
Pascal
Andre
,
andre
@
chimay
.
via
.
ecp
.
fr
.
I
changed
the
version
to
2.0
and
updated
the
code
for
Python
1.5
and
PostgreSQL
6.2.1
.
While
I
was
at
it
I
upgraded
the
code
to
use
full
ANSI
style
prototypes
and
changed
the
order
of
arguments
to
connect
.
style
prototypes
and
changed
the
order
of
arguments
to
connect
.
The
latest
version
of
PyGreSQL
works
with
PostgreSQL
6.5
and
Python
1.5.2
.
1.2
.
Distribution
files
...
...
@@ -78,25 +79,90 @@ style prototypes and changed the order of arguments to connect.
1.3
.
Installation
-----------------
*
You
first
have
to
get
and
build
Python
and
PostgreSQL
.
*
If
you
are
on
NetBSD
,
look
in
the
packages
directory
under
databases
.
If
it
isn
't there yet, it should be there shortly. You can also pick up the
package files from ftp://ftp.druid.net/pub/distrib/pygresql.pkg.tgz.
There is also a package in the FreeBSD ports collection but as I write
this it is at version 2.1. I will try to get that updated as well.
* For Linux installation look at README.linux. If you'
re
on
an
x86
system
that
uses
RPMs
,
then
you
can
pick
up
an
RPM
at
ftp
://
ftp
.
druid
.
net
/
pub
/
distrib
/
pygresql
.
i386
.
rpm
*
Also
,
check
out
setup
.
py
for
an
alternate
method
of
installing
the
package
.
You
have
two
options
.
You
can
compile
PyGreSQL
as
a
stand
-
alone
module
or
you
can
build
it
into
the
Python
interpreter
.
GENERAL
*
You
must
first
have
installed
Python
and
PostgreSQL
on
your
system
.
The
header
files
and
developer
's libraries for both Python and PostgreSQL
must be installed on your system before you can build PyGreSQL. If you
built both Python and PostgreSQL from source, you should be fine. If your
system uses some package mechanism (such as RPMs or NetBSD packages), then
you probably need to install packages such as Python-devel in addition to
the Python package.
* PyGreSQL is implemented as two parts, a C module labeled _pg and a
Python wrapper called pg.py. This changed between 2.1 and 2.2. This
should not affect any existing programs but the installation is slightly
different.
*
Find
the
directory
where
your
'Setup'
file
lives
(
usually
??/
Modules
)
and
copy
or
symlink
the
'pgmodule.c'
file
there
.
* Download and unpack the PyGreSQL tarball if you haven'
t
already
done
so
.
STAND
-
ALONE
*
In
the
directory
containing
pgmodule
.
c
,
run
the
following
command
cc
-
fpic
-
shared
-
o
_pg
.
so
-
I
[
pyInc
]
-
I
[
pgInc
]
-
L
[
pgLib
]
-
lpq
#
-
lcrypt
#
needed
on
some
systems
where
:
[
pyInc
]
=
path
of
the
Python
include
(
usually
Python
.
h
)
[
pgInc
]
=
path
of
the
PostgreSQL
include
(
usually
postgres
.
h
)
[
pgLib
]
=
path
of
the
PostgreSQL
libraries
(
usually
libpq
.
so
or
libpq
.
a
)
Some
options
may
be
added
to
this
line
:
-
DNO_DEF_VAR
-
no
default
variables
support
-
DNO_DIRECT
-
no
direct
access
methods
-
DNO_LARGE
-
no
large
object
support
-
DNO_SNPRINTF
-
if
running
a
system
with
no
snprintf
call
-
DNO_PQSOCKET
-
if
running
an
older
PostgreSQL
Define
NO_PQSOCKET
if
you
are
using
a
version
of
PostgreSQL
before
6.4
that
does
not
have
the
PQsocket
function
.
The
other
options
will
be
described
in
the
next
sections
.
*
Test
the
new
module
.
Something
like
the
following
should
work
.
$
python
>>>
import
_pg
>>>
db
=
_pg
.
connect
(
'thilo'
,
'localhost'
)
>>>
db
.
query
(
"INSERT INTO test VALUES ('ping','pong')"
)
18304
>>>
db
.
query
(
"SELECT * FROM test"
)
eins
|
zwei
----+----
ping
|
pong
(
1
row
)
*
Finally
,
move
the
_pg
.
so
,
pg
.
py
,
and
pgdb
.
py
to
a
directory
in
your
PYTHONPATH
.
A
good
place
would
be
/
usr
/
lib
/
python1
.5
/
site
-
python
if
your
Python
modules
are
in
/
usr
/
lib
/
python1
.5
.
BUILT
-
IN
TO
PYTHON
INTERPRETER
*
Find
the
directory
where
your
'Setup'
file
lives
(
usually
??/
Modules
)
in
the
Python
source
hierarchy
and
copy
or
symlink
the
'pgmodule.c'
file
there
.
*
Add
the
following
line
to
your
Setup
file
_pg
pgmodule
.
c
-
I
[
pgInc
]
-
L
[
pgLib
]
-
lpq
#
-
lcrypt
#
needed
on
some
systems
where
:
[
pgInc
]
=
path
of
the
PostgreSQL
include
[
pgLib
]
=
path
of
the
PostgreSQL
libraries
[
pgInc
]
=
path
of
PostgreSQL
include
(
often
/
usr
/
local
/
include
/
python1
.5
)
[
pgLib
]
=
path
of
the
PostgreSQL
libraries
(
often
/
usr
/
local
/
lib
/
python1
.5
)
Some
options
may
be
added
to
this
line
:
-
DNO_DEF_VAR
-
no
default
variables
support
-
DNO_DIRECT
-
no
direct
access
methods
-
DNO_LARGE
-
no
large
object
support
-
DNO_SNPRINTF
-
if
running
a
system
with
no
snprintf
call
-
DNO_PQSOCKET
-
if
running
an
older
PostgreSQL
Define
NO_PQSOCKET
if
you
are
using
a
version
of
PostgreSQL
before
6.4
...
...
@@ -108,21 +174,14 @@ style prototypes and changed the order of arguments to connect.
your
shared
modules
with
"make sharedinstall but this no longer seems
to be true."
*
Copy
pg
.
py
to
the
lib
directory
where
the
rest
of
your
modules
are
.
For
*
Copy
pg
.
py
to
the
lib
directory
where
the
rest
of
your
modules
are
.
For
example
,
that
's /usr/local/lib/Python on my system.
* Do '
make
-
f
Makefile
.
pre
.
in
boot
' and do '
make
&&
make
install
'
* Rebuild Python from the root directory of the Python source hierarchy by
running '
make
-
f
Makefile
.
pre
.
in
boot
' and '
make
&&
make
install
'
* For more details read the documentation at the top of Makefile.pre.in
* If you are on NetBSD, look in the packages directory under databases. If
it isn'
t
there
yet
,
it
should
be
there
shortly
.
You
can
also
pick
up
the
package
files
from
ftp
://
ftp
.
druid
.
net
/
pub
/
distrib
/
pygresql
.
pkg
.
tgz
.
There
is
also
a
package
in
the
FreeBSD
ports
collection
but
as
I
write
this
it
is
at
version
2.1
.
I
will
try
to
get
that
updated
as
well
.
*
For
Linux
installation
look
at
README
.
linux
1.4. Where to get ... ?
-----------------------
...
...
@@ -133,9 +192,10 @@ The home sites of the different packages are:
- PosgreSQL: http://www.PostgreSQL.org/
- PyGreSQL: http://www.druid.net/pygresql/
A
Linux
RPM
can
be
picked
up
from
ftp
://
www
.
eevolute
.
com
/
pub
/
python
/.
A
NetBSD
package
thould
be
in
the
distribution
soon
and
is
available
at
ftp
://
ftp
.
druid
.
net
/
pub
/
distrib
/
pygresql
.
pkg
.
tgz
.
A Linux RPM can be picked up from
ftp://ftp.druid.net/pub/distrib/pygresql.i386.rpm. A NetBSD package thould
be in the distribution soon and is available at
ftp://ftp.druid.net/pub/distrib/pygresql.pkg.tgz.
1.5. Information and support
----------------------------
...
...
@@ -394,7 +454,7 @@ methods are specified by the tag [LO].
inserted
row
.
If
it
is
otherwise
a
query
that
does
not
return
a
result
(
ie
.
is
not
a
some
kind
of
SELECT
statement
),
it
returns
None
.
Otherwise
,
it
returns
a
pgqueryobject
that
can
be
accessed
via
the
getresult
method or
printed.
getresult
or
dictresult
method
or
simply
printed
.
pgqueryobject
methods
---------------------
...
...
@@ -411,8 +471,8 @@ methods are specified by the tag [LO].
pg
.
error
-
invalid
previous
result
Description
:
This
method
returns
the
list
of
the
values
returned
by
the
query
.
More information about this result may be
get
using listfields,
fieldname and fiednum methods.
More
information
about
this
result
may
be
accessed
using
listfields
,
fieldname
and
fie
l
dnum
methods
.
2.2.1.2
.
dictresult
-
like
getresult
but
returns
list
of
dictionaries
---------------------------------------------------------------------
...
...
@@ -839,8 +899,8 @@ has a class called DB. The above functions are also included in the
name
space
so
it
isn
't necessary to import both modules. The preferred
way to use this module is as follows.
from
pg
import
DB
db
=
DB
(...)
#
See
description
of
the
initialization
method
below
.
import pg
db =
pg.
DB(...) # See description of the initialization method below.
The following describes the methods and variables of this class.
...
...
@@ -973,11 +1033,30 @@ The following describes the methods and variables of this class.
as
munged
as
described
above
.
4. Future directions
====================
4.
DB
-
API
reference
===================
This
section
needs
to
be
written
.
5.
Todo
=======
The
large
object
and
direct
access
functions
need
much
more
attention
.
I want to add a DB-SIG API wrapper around the underlying module. This
will be in 3.0.
An
update
query
should
return
the
number
of
rows
affected
.
The
C
module
needs
to
be
cleaned
up
and
redundant
code
merged
.
The
DB
-
API
module
needs
to
be
documented
.
6.
Future
directions
====================
Users
should
be
able
to
register
their
own
types
with
_pg
.
I
would
like
a
new
method
that
returns
a
dictionary
of
dictionaries
from
a
SELECT
.
src/interfaces/python/README.linux
View file @
f36e7ff0
Thanks to thilo@eevolute.com for this README and the RPM
Note: The precompiled RPM package is not available at www.eevolute.com.
You may use the spec file provided with PyGreSQL to build your
own package.
Hartmut Goebel <hartmut@goebel.noris.de>
INSTALLING PyGreSQL on Redhat Linux 5.1 or 5.2
==============================================
...
...
src/interfaces/python/mkdefines
View file @
f36e7ff0
#! /usr/
local/bin/
python
#! /usr/
bin/env
python
import
string
...
...
src/interfaces/python/pg.py
View file @
f36e7ff0
...
...
@@ -10,13 +10,16 @@ import string, re, sys
# utility function
# We expect int, seq, decimal, text or date (more later)
def
_quote
(
d
,
t
):
if
d
==
None
:
return
"NULL"
if
t
in
[
'int'
,
'decimal'
,
'seq'
]:
if
d
==
""
:
return
0
return
"
%
s"
%
d
return
"
%
d"
%
int
(
d
)
if
t
==
'money'
:
if
d
==
""
:
return
'0.00'
return
"'
%.2
f'"
%
d
return
"'
%.2
f'"
%
float
(
d
)
if
t
==
'bool'
:
if
string
.
upper
(
d
)
in
[
'T'
,
'TRUE'
,
'Y'
,
'YES'
,
1
,
'1'
,
'ON'
]:
...
...
@@ -25,7 +28,8 @@ def _quote(d, t):
return
"'f'"
if
d
==
""
:
return
"null"
return
"'
%
s'"
%
string
.
strip
(
re
.
sub
(
"'"
,
"''"
,
"
%
s"
%
d
))
return
"'
%
s'"
%
string
.
strip
(
re
.
sub
(
"'"
,
"''"
,
\
re
.
sub
(
"
\\\\
"
,
"
\\\\\\\\
"
,
"
%
s"
%
d
)))
class
DB
:
"""This class wraps the pg connection type"""
...
...
@@ -42,8 +46,8 @@ class DB:
if
not
hasattr
(
self
,
e
)
and
hasattr
(
self
.
db
,
e
):
exec
'self.
%
s = self.db.
%
s'
%
(
e
,
e
)
self
.
attnames
=
{}
self
.
pkeys
=
{}
self
.
__attnames__
=
{}
self
.
__pkeys__
=
{}
self
.
debug
=
None
# For debugging scripts, set to output format
# that takes a single string arg. For example
# in a CGI set to "%s<BR>"
...
...
@@ -56,11 +60,17 @@ class DB:
pg_class.oid = pg_index.indrelid AND
pg_index.indkey[0] = pg_attribute.attnum AND
pg_index.indisprimary = 't'"""
)
.
getresult
():
self
.
pkeys
[
rel
]
=
att
self
.
__pkeys__
[
rel
]
=
att
# wrap query for debugging
def
query
(
self
,
qstr
):
if
self
.
debug
!=
None
:
print
self
.
debug
%
qstr
return
self
.
db
.
query
(
qstr
)
def
pkey
(
self
,
cl
):
# will raise an exception if primary key doesn't exist
return
self
.
pkeys
[
cl
]
return
self
.
__pkeys__
[
cl
]
def
get_databases
(
self
):
l
=
[]
...
...
@@ -79,8 +89,8 @@ class DB:
def
get_attnames
(
self
,
cl
):
# May as well cache them
if
self
.
attnames
.
has_key
(
cl
):
return
self
.
attnames
[
cl
]
if
self
.
__attnames__
.
has_key
(
cl
):
return
self
.
__attnames__
[
cl
]
query
=
"""SELECT pg_attribute.attname, pg_type.typname
FROM pg_class, pg_attribute, pg_type
...
...
@@ -114,13 +124,13 @@ class DB:
else
:
l
[
attname
]
=
'text'
self
.
attnames
[
cl
]
=
l
return
self
.
attnames
[
cl
]
self
.
__attnames__
[
cl
]
=
l
return
self
.
__attnames__
[
cl
]
# return a tuple from a database
def
get
(
self
,
cl
,
arg
,
keyname
=
None
):
def
get
(
self
,
cl
,
arg
,
keyname
=
None
,
view
=
0
):
if
keyname
==
None
:
# use the primary key by default
keyname
=
self
.
pkeys
[
cl
]
keyname
=
self
.
__pkeys__
[
cl
]
fnames
=
self
.
get_attnames
(
cl
)
...
...
@@ -136,6 +146,9 @@ class DB:
# We want the oid for later updates if that isn't the key
if
keyname
==
'oid'
:
q
=
"SELECT * FROM
%
s WHERE oid =
%
s"
%
(
cl
,
k
)
elif
view
:
q
=
"SELECT * FROM
%
s WHERE
%
s =
%
s"
%
\
(
cl
,
keyname
,
_quote
(
k
,
fnames
[
keyname
]))
else
:
q
=
"SELECT oid AS oid_
%
s,
%
s FROM
%
s WHERE
%
s =
%
s"
%
\
(
cl
,
string
.
join
(
fnames
.
keys
(),
','
),
\
...
...
@@ -155,6 +168,7 @@ class DB:
return
arg
# Inserts a new tuple into a table
# We currently don't support insert into views although PostgreSQL does
def
insert
(
self
,
cl
,
a
):
fnames
=
self
.
get_attnames
(
cl
)
l
=
[]
...
...
@@ -183,7 +197,7 @@ class DB:
# otherwise use the primary key. Fail if neither.
def
update
(
self
,
cl
,
a
):
foid
=
'oid_
%
s'
%
cl
pk
=
self
.
pkeys
[
cl
]
pk
=
self
.
__pkeys__
[
cl
]
if
a
.
has_key
(
foid
):
where
=
"oid =
%
s"
%
a
[
foid
]
elif
a
.
has_key
(
pk
):
...
...
@@ -228,8 +242,6 @@ class DB:
for
ff
in
fnames
.
keys
():
if
fnames
[
ff
]
in
[
'int'
,
'decimal'
,
'seq'
,
'money'
]:
a
[
ff
]
=
0
elif
fnames
[
ff
]
==
'date'
:
a
[
ff
]
=
'TODAY'
else
:
a
[
ff
]
=
""
...
...
src/interfaces/python/pgdb.py
0 → 100644
View file @
f36e7ff0
""" pgdb - DB-SIG compliant module for PygreSQL.
(c) 1999, Pascal Andre <andre@via.ecp.fr>.
See package documentation for further information on copyright.
Even though this file is distributed with a release version of
PyGreSQL, this is beta software. Inline documentation is sparse.
See DB-SIG 2.0 specification for usage information.
basic usage:
pgdb.connect(connect_string) -> connection
connect_string = 'host:database:user:password:opt:tty'
All parts are optional. You may also pass host through
password as keyword arguments. To pass a port, pass it in
the host keyword parameter:
pgdb.connect(host='localhost:5432')
connection.cursor() -> cursor
connection.commit()
connection.close()
connection.rollback()
cursor.execute(query[, params])
execute a query, binding params (a dictionary) if it is
passed. The binding syntax is the same as the
%
operator
for dictionaries, and no quoting is done.
cursor.executemany(query, list of params)
execute a query many times, binding each param dictionary
from the list.
cursor.fetchone() -> [value, value, ...]
cursor.fetchall() -> [[value, value, ...], ...]
cursor.fetchmany([size]) -> [[value, value, ...], ...]
returns size or cursor.arraysize number of rows from result
set. Default cursor.arraysize is 1.
cursor.description -> [(column_name, type_name, display_size,
internal_size, precision, scale, null_ok), ...]
Note that precision, scale and null_ok are not implemented.
cursor.rowcount
number of rows available in the result set. Available after
a call to execute.
cursor.close()
"""
import
_pg
import
string
import
exceptions
import
types
import
DateTime
import
time
### module constants
# compliant with DB SIG 2.0
apilevel
=
'2.0'
# module may be shared, but not connections
threadsafety
=
1
# this module use extended python format codes
paramstyle
=
'pyformat'
### exception hierarchy
class
Warning
(
StandardError
):
pass
class
Error
(
StandardError
):
pass
class
InterfaceError
(
Error
):
pass
class
DatabaseError
(
Error
):
pass
class
DataError
(
DatabaseError
):
pass
class
OperationalError
(
DatabaseError
):
pass
class
IntegrityError
(
DatabaseError
):
pass
class
InternalError
(
DatabaseError
):
pass
class
ProgrammingError
(
DatabaseError
):
pass
class
NotSupportedError
(
DatabaseError
):
pass
### internal type handling class
class
pgdbTypeCache
:
def
__init__
(
self
,
cnx
):
self
.
__source
=
cnx
.
source
()
self
.
__type_cache
=
{}
def
typecast
(
self
,
typ
,
value
):
# for NULL values, no typecast is necessary
if
value
==
None
:
return
value
if
typ
==
STRING
:
pass
elif
typ
==
BINARY
:
pass
elif
typ
==
INTEGER
:
value
=
int
(
value
)
elif
typ
==
LONG
:
value
=
long
(
value
)
elif
typ
==
FLOAT
:
value
=
float
(
value
)
elif
typ
==
MONEY
:
value
=
string
.
replace
(
value
,
"$"
,
""
)
value
=
string
.
replace
(
value
,
","
,
""
)
value
=
float
(
value
)
elif
typ
==
DATETIME
:
# format may differ ... we'll give string
pass
elif
typ
==
ROWID
:
value
=
long
(
value
)
return
value
def
getdescr
(
self
,
oid
):
try
:
return
self
.
__type_cache
[
oid
]
except
:
self
.
__source
.
execute
(
"SELECT typname, typprtlen, typlen "
"FROM pg_type WHERE oid =
%
s"
%
oid
)
res
=
self
.
__source
.
fetch
(
1
)[
0
]
# column name is omitted from the return value. It will
# have to be prepended by the caller.
res
=
(
res
[
0
],
string
.
atoi
(
res
[
1
]),
string
.
atoi
(
res
[
2
]),
None
,
None
,
None
)
self
.
__type_cache
[
oid
]
=
res
return
res
### cursor object
class
pgdbCursor
:
def
__init__
(
self
,
src
,
cache
):
self
.
__cache
=
cache
self
.
__source
=
src
self
.
description
=
None
self
.
rowcount
=
-
1
self
.
arraysize
=
5
def
close
(
self
):
self
.
__source
.
close
()
self
.
description
=
None
self
.
rowcount
=
-
1
def
execute
(
self
,
operation
,
params
=
None
):
if
type
(
params
)
==
types
.
TupleType
or
type
(
params
)
==
types
.
ListType
:
self
.
executemany
(
operation
,
params
)
else
:
self
.
executemany
(
operation
,
(
params
,))
def
executemany
(
self
,
operation
,
param_seq
):
self
.
description
=
None
self
.
rowcount
=
-
1
# first try to execute all queries
totrows
=
0
sql
=
"INIT"
try
:
for
params
in
param_seq
:
if
params
!=
None
:
sql
=
operation
%
params
else
:
sql
=
operation
rows
=
self
.
__source
.
execute
(
sql
)
if
rows
!=
None
:
# true is __source is NOT a DQL
totrows
=
totrows
+
rows
except
_pg
.
error
,
msg
:
raise
DatabaseError
,
"error '
%
s' in '
%
s'"
%
(
msg
,
sql
)
except
:
raise
OperationalError
,
"internal error in '
%
s'"
%
sql
# then initialize result raw count and description
if
self
.
__source
.
resulttype
==
_pg
.
RESULT_DQL
:
self
.
rowcount
=
self
.
__source
.
ntuples
d
=
[]
for
typ
in
self
.
__source
.
listinfo
():
# listinfo is a sequence of
# (index, column_name, type_oid)
# getdescr returns all items needed for a
# description tuple except the column_name.
desc
=
typ
[
1
:
2
]
+
self
.
__cache
.
getdescr
(
typ
[
2
])
d
.
append
(
desc
)
self
.
description
=
d
else
:
self
.
rowcount
=
totrows
self
.
description
=
None
def
fetchone
(
self
):
res
=
self
.
fetchmany
(
1
,
0
)
try
:
return
res
[
0
]
except
:
return
None
def
fetchall
(
self
):
return
self
.
fetchmany
(
-
1
,
0
)
def
fetchmany
(
self
,
size
=
None
,
keep
=
1
):
if
size
==
None
:
size
=
self
.
arraysize
if
keep
==
1
:
self
.
arraysize
=
size
res
=
self
.
__source
.
fetch
(
size
)
result
=
[]
for
r
in
res
:
row
=
[]
for
i
in
range
(
len
(
r
)):
row
.
append
(
self
.
__cache
.
typecast
(
self
.
description
[
i
][
1
],
r
[
i
]
)
)
result
.
append
(
row
)
return
result
def
setinputsizes
(
self
,
sizes
):
pass
def
setoutputsize
(
self
,
size
,
col
=
0
):
pass
### connection object
class
pgdbCnx
:
def
__init__
(
self
,
cnx
):
self
.
__cnx
=
cnx
self
.
__cache
=
pgdbTypeCache
(
cnx
)
try
:
src
=
self
.
__cnx
.
source
()
src
.
execute
(
"BEGIN"
)
except
:
raise
OperationalError
,
"invalid connection."
def
close
(
self
):
self
.
__cnx
.
close
()
def
commit
(
self
):
try
:
src
=
self
.
__cnx
.
source
()
src
.
execute
(
"COMMIT"
)
src
.
execute
(
"BEGIN"
)
except
:
raise
OperationalError
,
"can't commit."
def
rollback
(
self
):
try
:
src
=
self
.
__cnx
.
source
()
src
.
execute
(
"ROLLBACK"
)
src
.
execute
(
"BEGIN"
)
except
:
raise
OperationalError
,
"can't rollback."
def
cursor
(
self
):
try
:
src
=
self
.
__cnx
.
source
()
return
pgdbCursor
(
src
,
self
.
__cache
)
except
:
raise
pgOperationalError
,
"invalid connection."
### module interface
# connects to a database
def
connect
(
dsn
=
None
,
user
=
None
,
password
=
None
,
host
=
None
,
database
=
None
):
# first get params from DSN
dbport
=
-
1
dbhost
=
""
dbbase
=
""
dbuser
=
""
dbpasswd
=
""
dbopt
=
""
dbtty
=
""
try
:
params
=
string
.
split
(
dsn
,
":"
)
dbhost
=
params
[
0
]
dbbase
=
params
[
1
]
dbuser
=
params
[
2
]
dbpasswd
=
params
[
3
]
dbopt
=
params
[
4
]
dbtty
=
params
[
5
]
except
:
pass
# override if necessary
if
user
!=
None
:
dbuser
=
user
if
password
!=
None
:
dbpasswd
=
password
if
database
!=
None
:
dbbase
=
database
if
host
!=
None
:
try
:
params
=
string
.
split
(
host
,
":"
)
dbhost
=
params
[
0
]
dbport
=
params
[
1
]
except
:
pass
# empty host is localhost
if
dbhost
==
""
:
dbhost
=
None
if
dbuser
==
""
:
dbuser
=
None
# open the connection
cnx
=
_pg
.
connect
(
host
=
dbhost
,
dbname
=
dbbase
,
port
=
dbport
,
opt
=
dbopt
,
tty
=
dbtty
,
user
=
dbuser
,
passwd
=
dbpasswd
)
return
pgdbCnx
(
cnx
)
### types handling
# PostgreSQL is object-oriented: types are dynamic. We must thus use type names
# as internal type codes.
class
pgdbType
:
def
__init__
(
self
,
*
values
):
self
.
values
=
values
def
__cmp__
(
self
,
other
):
if
other
in
self
.
values
:
return
0
if
other
<
self
.
values
:
return
1
else
:
return
-
1
STRING
=
pgdbType
(
'char'
,
'name'
,
'text'
,
'varchar'
)
# BLOB support is pg specific
BINARY
=
pgdbType
()
INTEGER
=
pgdbType
(
'int2'
,
'int4'
,
'serial'
)
LONG
=
pgdbType
(
'int8'
)
FLOAT
=
pgdbType
(
'float4'
,
'float8'
,
'numeric'
)
BOOL
=
pgdbType
(
'bool'
)
MONEY
=
pgdbType
(
'money'
)
# this may be problematic as type are quite different ... I hope it won't hurt
DATETIME
=
pgdbType
(
'abstime'
,
'reltime'
,
'tinterval'
,
'date'
,
'time'
,
'timespan'
,
'timestamp'
)
# OIDs are used for everything (types, tables, BLOBs, rows, ...). This may cause
# confusion, but we are unable to find out what exactly is behind the OID (at
# least not easily enough). Should this be undefined as BLOBs ?
ROWID
=
pgdbType
(
'oid'
,
'oid8'
)
# mandatory type helpers
def
Date
(
year
,
month
,
day
):
return
DateTime
.
DateTime
(
year
,
month
,
day
)
def
Time
(
hour
,
minute
,
second
):
return
DateTime
.
TimeDelta
(
hour
,
minute
,
second
)
def
Timestamp
(
year
,
month
,
day
,
hour
,
minute
,
second
):
return
DateTime
.
DateTime
(
year
,
month
,
day
,
hour
,
minute
,
second
)
def
DateFromTicks
(
ticks
):
return
apply
(
Date
,
time
.
localtime
(
ticks
)[:
3
])
def
TimeFromTicks
(
ticks
):
return
apply
(
Time
,
time
.
localtime
(
ticks
)[
3
:
6
])
def
TimestampFromTicks
(
ticks
):
return
apply
(
Timestamp
,
time
.
localtime
(
ticks
)[:
6
])
src/interfaces/python/pgmodule.c
View file @
f36e7ff0
...
...
@@ -26,9 +26,9 @@
*
*/
#include
"Python.h"
#include
"libpq-fe.h"
#include
"libpq/libpq-fs.h"
#include
<Python.h>
#include
<libpq-fe.h>
#include
<libpq/libpq-fs.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
...
...
@@ -36,22 +36,22 @@
/* really bad stuff here - I'm so naughty */
/* If you need to you can run mkdefines to get */
/* current defines but it should not have changed */
#define
INT2OID 21
#define
INT4OID 23
#define
OIDOID 26
#define
FLOAT4OID 700
#define
FLOAT8OID 701
#define
CASHOID 790
#define
INT2OID 21
#define
INT4OID 23
#define
OIDOID 26
#define
FLOAT4OID 700
#define
FLOAT8OID 701
#define
CASHOID 790
static
PyObject
*
PGError
;
static
const
char
*
PyPgVersion
=
"2.4
"
;
static
PyObject
*
PGError
;
static
const
char
*
PyPgVersion
=
"3.0
"
;
/* taken from fileobject.c */
#define BUF(v) PyString_AS_STRING((PyStringObject *)(v))
/* default values */
#define
MODULE_NAME "pgsql"
#define
ARRAYSIZE 1
#define
MODULE_NAME "pgsql"
#define
ARRAYSIZE 1
/* flags for object validity checks */
#define CHECK_OPEN 1
...
...
@@ -60,19 +60,35 @@ static const char *PyPgVersion = "2.4";
#define CHECK_RESULT 8
#define CHECK_DQL 16
#define MAX_BUFFER_SIZE 8192
/* maximum transaction size */
/* query result types */
#define RESULT_EMPTY 1
#define RESULT_DML 2
#define RESULT_DDL 3
#define RESULT_DQL 4
/* flags for move methods */
#define QUERY_MOVEFIRST 1
#define QUERY_MOVELAST 2
#define QUERY_MOVENEXT 3
#define QUERY_MOVEPREV 4
/* moves names for errors */
const
char
*
__movename
[
5
]
=
{
""
,
"movefirst"
,
"movelast"
,
"movenext"
,
"moveprev"
};
#define MAX_BUFFER_SIZE 8192
/* maximum transaction size */
#ifndef NO_DIRECT
#define DIRECT_ACCESS
1
/* enables direct access functions */
#endif
/* NO_DIRECT */
#define DIRECT_ACCESS 1
/* enables direct access functions */
#endif
/* NO_DIRECT */
#ifndef NO_LARGE
#define LARGE_OBJECTS
1
/* enables large objects support */
#endif
/* NO_LARGE */
#define LARGE_OBJECTS 1
/* enables large objects support */
#endif
/* NO_LARGE */
#ifndef NO_DEF_VAR
#define DEFAULT_VARS
1
/* enables default variables use */
#endif
/* NO_DEF_VAR */
#define DEFAULT_VARS 1
/* enables default variables use */
#endif
/* NO_DEF_VAR */
/* --------------------------------------------------------------------- */
...
...
@@ -80,15 +96,15 @@ static const char *PyPgVersion = "2.4";
#ifdef DEFAULT_VARS
static
PyObject
*
pg_default_host
;
/* default database host */
static
PyObject
*
pg_default_base
;
/* default database name */
static
PyObject
*
pg_default_opt
;
/* default connection options */
static
PyObject
*
pg_default_tty
;
/* default debug tty */
static
PyObject
*
pg_default_port
;
/* default connection port */
static
PyObject
*
pg_default_user
;
/* default username */
static
PyObject
*
pg_default_passwd
;
/* default password */
static
PyObject
*
pg_default_host
;
/* default database host */
static
PyObject
*
pg_default_base
;
/* default database name */
static
PyObject
*
pg_default_opt
;
/* default connection options */
static
PyObject
*
pg_default_tty
;
/* default debug tty */
static
PyObject
*
pg_default_port
;
/* default connection port */
static
PyObject
*
pg_default_user
;
/* default username */
static
PyObject
*
pg_default_passwd
;
/* default password */
#endif
/* DEFAULT_VARS */
#endif
/* DEFAULT_VARS */
/* --------------------------------------------------------------------- */
/* OBJECTS DECLARATION */
...
...
@@ -99,40 +115,78 @@ typedef struct
{
PyObject_HEAD
int
valid
;
/* validity flag */
PGconn
*
cnx
;
/* PostGres connection handle */
}
pgobject
;
PGconn
*
cnx
;
/* PostGres connection handle */
PGresult
*
last_result
;
/* last result content */
}
pgobject
;
staticforward
PyTypeObject
PgType
;
#define is_pgobject(v) ((v)->ob_type == &PgType)
static
PyObject
*
pgobject_New
(
void
)
{
pgobject
*
pgobj
;
if
((
pgobj
=
PyObject_NEW
(
pgobject
,
&
PgType
))
==
NULL
)
return
NULL
;
pgobj
->
valid
=
1
;
pgobj
->
last_result
=
NULL
;
pgobj
->
cnx
=
NULL
;
return
(
PyObject
*
)
pgobj
;
}
/* pg query object */
typedef
struct
{
PyObject_HEAD
PGresult
*
last_result
;
/* last result content */
}
pgqueryobject
;
PGresult
*
last_result
;
/* last result content */
int
result_type
;
/* type of previous result */
long
current_pos
;
/* current position in last result */
long
num_rows
;
/* number of (affected) rows */
}
pgqueryobject
;
staticforward
PyTypeObject
PgQueryType
;
#define is_pgqueryobject(v) ((v)->ob_type == &PgQueryType)
/* pg source object */
typedef
struct
{
PyObject_HEAD
int
valid
;
/* validity flag */
pgobject
*
pgcnx
;
/* parent connection object */
PGresult
*
last_result
;
/* last result content */
int
result_type
;
/* result type (DDL/DML/DQL) */
long
arraysize
;
/* array size for fetch method */
int
current_row
;
/* current selected row */
int
max_row
;
/* number of rows in the result */
int
num_fields
;
/* number of fields in each row */
}
pgsourceobject
;
staticforward
PyTypeObject
PgSourceType
;
#define is_pgsourceobject(v) ((v)->ob_type == &PgSourceType)
#ifdef LARGE_OBJECTS
/* pg large object */
typedef
struct
{
PyObject_HEAD
pgobject
*
pgcnx
;
/* parent connection object */
Oid
lo_oid
;
/* large object oid */
int
lo_fd
;
/* large object fd */
}
pglargeobject
;
pgobject
*
pgcnx
;
/* parent connection object */
Oid
lo_oid
;
/* large object oid */
int
lo_fd
;
/* large object fd */
}
pglargeobject
;
staticforward
PyTypeObject
PglargeType
;
#define is_pglargeobject(v) ((v)->ob_type == &PglargeType)
#endif
/* LARGE_OBJECTS */
#endif
/* LARGE_OBJECTS */
/* --------------------------------------------------------------------- */
/* INTERNAL FUNCTIONS */
...
...
@@ -141,8 +195,7 @@ staticforward PyTypeObject PglargeType;
static
int
check_cnx_obj
(
pgobject
*
self
)
{
if
(
!
self
->
valid
)
{
if
(
!
self
->
valid
)
{
PyErr_SetString
(
PGError
,
"connection has been closed"
);
return
0
;
}
...
...
@@ -184,10 +237,725 @@ check_lo_obj(pglargeobject * self, int level)
return
1
;
}
#endif
/* LARGE_OBJECTS */
#endif
/* LARGE_OBJECTS */
/* checks source object validity */
static
int
check_source_obj
(
pgsourceobject
*
self
,
int
level
)
{
if
(
!
self
->
valid
)
{
PyErr_SetString
(
PGError
,
"object has been closed"
);
return
0
;
}
if
((
level
&
CHECK_RESULT
)
&&
self
->
last_result
==
NULL
)
{
PyErr_SetString
(
PGError
,
"no result."
);
return
0
;
}
if
((
level
&
CHECK_DQL
)
&&
self
->
result_type
!=
RESULT_DQL
)
{
PyErr_SetString
(
PGError
,
"last query did not return tuples."
);
return
0
;
}
if
((
level
&
CHECK_CNX
)
&&
!
check_cnx_obj
(
self
->
pgcnx
))
return
0
;
return
1
;
}
/* shared functions for converting PG types to Python types */
int
*
get_type_array
(
PGresult
*
result
,
int
nfields
)
{
int
*
typ
;
int
j
;
if
((
typ
=
malloc
(
sizeof
(
int
)
*
nfields
))
==
NULL
)
{
PyErr_SetString
(
PyExc_SyntaxError
,
"memory error in getresult()."
);
return
NULL
;
}
for
(
j
=
0
;
j
<
nfields
;
j
++
)
{
switch
(
PQftype
(
result
,
j
))
{
case
INT2OID
:
case
INT4OID
:
case
OIDOID
:
typ
[
j
]
=
1
;
break
;
case
FLOAT4OID
:
case
FLOAT8OID
:
typ
[
j
]
=
2
;
break
;
case
CASHOID
:
typ
[
j
]
=
3
;
break
;
default:
typ
[
j
]
=
4
;
break
;
}
}
return
typ
;
}
/* prototypes for constructors */
static
pgsourceobject
*
pgsource_new
(
pgobject
*
pgcnx
);
/* --------------------------------------------------------------------- */
/* PG SOURCE OBJECT IMPLEMENTATION */
/* constructor (internal use only) */
static
pgsourceobject
*
pgsource_new
(
pgobject
*
pgcnx
)
{
pgsourceobject
*
npgobj
;
/* allocates new query object */
if
((
npgobj
=
PyObject_NEW
(
pgsourceobject
,
&
PgSourceType
))
==
NULL
)
return
NULL
;
/* initializes internal parameters */
Py_XINCREF
(
pgcnx
);
npgobj
->
pgcnx
=
pgcnx
;
npgobj
->
last_result
=
NULL
;
npgobj
->
valid
=
1
;
npgobj
->
arraysize
=
ARRAYSIZE
;
return
npgobj
;
}
/* destructor */
static
void
pgsource_dealloc
(
pgsourceobject
*
self
)
{
if
(
self
->
last_result
)
PQclear
(
self
->
last_result
);
Py_XDECREF
(
self
->
pgcnx
);
PyMem_DEL
(
self
);
}
/* closes object */
static
char
pgsource_close__doc__
[]
=
"close() -- close query object without deleting it. "
"All instances of the query object can no longer be used after this call."
;
static
PyObject
*
pgsource_close
(
pgsourceobject
*
self
,
PyObject
*
args
)
{
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_TypeError
,
"method close() takes no parameter."
);
return
NULL
;
}
/* frees result if necessary and invalidates object */
if
(
self
->
last_result
)
{
PQclear
(
self
->
last_result
);
self
->
result_type
=
RESULT_EMPTY
;
self
->
last_result
=
NULL
;
}
self
->
valid
=
0
;
/* return None */
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* database query */
static
char
pgsource_execute__doc__
[]
=
"execute(sql) -- execute a SQL statement (string).
\n
"
"On success, this call returns the number of affected rows, "
"or None for DQL (SELECT, ...) statements.
\n
"
"The fetch (fetch(), fetchone() and fetchall()) methods can be used "
"to get result rows."
;
static
PyObject
*
pgsource_execute
(
pgsourceobject
*
self
,
PyObject
*
args
)
{
char
*
query
;
const
char
*
temp
;
long
num_rows
;
/* checks validity */
if
(
!
check_source_obj
(
self
,
CHECK_CNX
))
return
NULL
;
/* get query args */
if
(
!
PyArg_ParseTuple
(
args
,
"s"
,
&
query
))
{
PyErr_SetString
(
PyExc_TypeError
,
"execute(sql), with sql (string)."
);
return
NULL
;
}
/* frees previous result */
if
(
self
->
last_result
)
{
PQclear
(
self
->
last_result
);
self
->
last_result
=
NULL
;
}
self
->
max_row
=
0
;
self
->
current_row
=
0
;
self
->
num_fields
=
0
;
/* gets result */
Py_BEGIN_ALLOW_THREADS
self
->
last_result
=
PQexec
(
self
->
pgcnx
->
cnx
,
query
);
Py_END_ALLOW_THREADS
/* checks result validity */
if
(
!
self
->
last_result
)
{
PyErr_SetString
(
PyExc_ValueError
,
PQerrorMessage
(
self
->
pgcnx
->
cnx
));
return
NULL
;
}
/* checks result status */
switch
(
PQresultStatus
(
self
->
last_result
))
{
/* query succeeded */
case
PGRES_TUPLES_OK
:
/* DQL: returns None (DB-SIG compliant) */
self
->
result_type
=
RESULT_DQL
;
self
->
max_row
=
PQntuples
(
self
->
last_result
);
self
->
num_fields
=
PQnfields
(
self
->
last_result
);
Py_INCREF
(
Py_None
);
return
Py_None
;
case
PGRES_COMMAND_OK
:
/* other requests */
case
PGRES_COPY_OUT
:
case
PGRES_COPY_IN
:
self
->
result_type
=
RESULT_DDL
;
temp
=
PQcmdTuples
(
self
->
last_result
);
num_rows
=
1
;
if
(
temp
[
0
]
!=
0
)
{
self
->
result_type
=
RESULT_DML
;
num_rows
=
atol
(
temp
);
}
return
PyInt_FromLong
(
num_rows
);
/* query failed */
case
PGRES_EMPTY_QUERY
:
PyErr_SetString
(
PyExc_ValueError
,
"empty query."
);
break
;
case
PGRES_BAD_RESPONSE
:
case
PGRES_FATAL_ERROR
:
case
PGRES_NONFATAL_ERROR
:
PyErr_SetString
(
PGError
,
PQerrorMessage
(
self
->
pgcnx
->
cnx
));
break
;
default:
PyErr_SetString
(
PGError
,
"internal error: "
"unknown result status."
);
break
;
}
/* frees result and returns error */
PQclear
(
self
->
last_result
);
self
->
last_result
=
NULL
;
self
->
result_type
=
RESULT_EMPTY
;
return
NULL
;
}
/* gets oid status for last query (valid for INSERTs, 0 for other) */
static
char
pgsource_oidstatus__doc__
[]
=
"oidstatus() -- return oid of last inserted row (if available)."
;
static
PyObject
*
pgsource_oidstatus
(
pgsourceobject
*
self
,
PyObject
*
args
)
{
long
oid
;
const
char
*
status
;
/* checks validity */
if
(
!
check_source_obj
(
self
,
CHECK_RESULT
))
return
NULL
;
/* checks args */
if
((
args
!=
NULL
)
&&
(
!
PyArg_ParseTuple
(
args
,
""
)))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method oidstatus() takes no parameters."
);
return
NULL
;
}
/* retrieves oid status */
oid
=
0
;
if
((
status
=
PQoidStatus
(
self
->
last_result
)))
oid
=
atol
(
status
);
return
PyInt_FromLong
(
oid
);
}
/* fetches rows from last result */
static
char
pgsource_fetch__doc__
[]
=
"fetch(num) -- return the next num rows from the last result in a list. "
"If num parameter is omitted arraysize attribute value is used. "
"If size equals -1, all rows are fetched."
;
static
PyObject
*
pgsource_fetch
(
pgsourceobject
*
self
,
PyObject
*
args
)
{
PyObject
*
rowtuple
,
*
reslist
,
*
str
;
int
i
,
j
;
long
size
;
/* checks validity */
if
(
!
check_source_obj
(
self
,
CHECK_RESULT
|
CHECK_DQL
))
return
NULL
;
/* checks args */
size
=
self
->
arraysize
;
if
(
!
PyArg_ParseTuple
(
args
,
"|l"
,
&
size
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"fetch(num), with num (integer, optional)."
);
return
NULL
;
}
/* seeks last line */
/* limit size to be within the amount of data we actually have */
if
(
size
==
-
1
||
(
self
->
max_row
-
self
->
current_row
)
<
size
)
size
=
self
->
max_row
-
self
->
current_row
;
/* allocate list for result */
if
((
reslist
=
PyList_New
(
0
))
==
NULL
)
return
NULL
;
/* builds result */
for
(
i
=
0
;
i
<
size
;
++
i
)
{
if
((
rowtuple
=
PyTuple_New
(
self
->
num_fields
))
==
NULL
)
{
Py_DECREF
(
reslist
);
return
NULL
;
}
for
(
j
=
0
;
j
<
self
->
num_fields
;
j
++
)
{
if
(
PQgetisnull
(
self
->
last_result
,
i
,
j
))
{
Py_INCREF
(
Py_None
);
str
=
Py_None
;
}
else
str
=
PyString_FromString
(
PQgetvalue
(
self
->
last_result
,
i
,
j
));
PyTuple_SET_ITEM
(
rowtuple
,
j
,
str
);
}
PyList_Append
(
reslist
,
rowtuple
);
self
->
current_row
++
;
}
return
reslist
;
}
/* changes current row (internal wrapper for all "move" methods) */
static
PyObject
*
pgsource_move
(
pgsourceobject
*
self
,
PyObject
*
args
,
int
move
)
{
/* checks validity */
if
(
!
check_source_obj
(
self
,
CHECK_RESULT
|
CHECK_DQL
))
return
NULL
;
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
char
errbuf
[
256
];
#ifdef NO_SNPRINTF
sprintf
(
errbuf
,
"method %s() takes no parameter."
,
__movename
[
move
]);
#else
snprintf
(
errbuf
,
sizeof
(
errbuf
),
"method %s() takes no parameter."
,
__movename
[
move
]);
#endif
PyErr_SetString
(
PyExc_SyntaxError
,
errbuf
);
return
NULL
;
}
/* changes the current row */
switch
(
move
)
{
case
QUERY_MOVEFIRST
:
self
->
current_row
=
0
;
break
;
case
QUERY_MOVELAST
:
self
->
current_row
=
self
->
max_row
-
1
;
break
;
case
QUERY_MOVENEXT
:
if
(
self
->
current_row
!=
self
->
max_row
)
self
->
current_row
++
;
break
;
case
QUERY_MOVEPREV
:
if
(
self
->
current_row
>
0
)
self
->
current_row
--
;
break
;
}
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* move to first result row */
static
char
pgsource_movefirst__doc__
[]
=
"movefirst() -- move to first result row."
;
static
PyObject
*
pgsource_movefirst
(
pgsourceobject
*
self
,
PyObject
*
args
)
{
return
pgsource_move
(
self
,
args
,
QUERY_MOVEFIRST
);
}
/* move to last result row */
static
char
pgsource_movelast__doc__
[]
=
"movelast() -- move to last valid result row."
;
static
PyObject
*
pgsource_movelast
(
pgsourceobject
*
self
,
PyObject
*
args
)
{
return
pgsource_move
(
self
,
args
,
QUERY_MOVELAST
);
}
/* move to next result row */
static
char
pgsource_movenext__doc__
[]
=
"movenext() -- move to next result row."
;
static
PyObject
*
pgsource_movenext
(
pgsourceobject
*
self
,
PyObject
*
args
)
{
return
pgsource_move
(
self
,
args
,
QUERY_MOVENEXT
);
}
/* move to previous result row */
static
char
pgsource_moveprev__doc__
[]
=
"moveprev() -- move to previous result row."
;
static
PyObject
*
pgsource_moveprev
(
pgsourceobject
*
self
,
PyObject
*
args
)
{
return
pgsource_move
(
self
,
args
,
QUERY_MOVEPREV
);
}
/* finds field number from string/integer (internal use only) */
static
int
pgsource_fieldindex
(
pgsourceobject
*
self
,
PyObject
*
param
,
const
char
*
usage
)
{
int
num
;
/* checks validity */
if
(
!
check_source_obj
(
self
,
CHECK_RESULT
|
CHECK_DQL
))
return
-
1
;
/* gets field number */
if
(
PyString_Check
(
param
))
{
num
=
PQfnumber
(
self
->
last_result
,
PyString_AsString
(
param
));
}
else
if
(
PyInt_Check
(
param
))
{
num
=
PyInt_AsLong
(
param
);
}
else
{
PyErr_SetString
(
PyExc_TypeError
,
usage
);
return
-
1
;
}
/* checks field validity */
if
(
num
<
0
||
num
>=
self
->
num_fields
)
{
PyErr_SetString
(
PyExc_ValueError
,
"Unknown field."
);
return
-
1
;
}
return
num
;
}
/* builds field information from position (internal use only) */
static
PyObject
*
pgsource_buildinfo
(
pgsourceobject
*
self
,
int
num
)
{
PyObject
*
result
;
/* allocates tuple */
result
=
PyTuple_New
(
3
);
if
(
!
result
)
return
NULL
;
/* affects field information */
PyTuple_SET_ITEM
(
result
,
0
,
PyInt_FromLong
(
num
));
PyTuple_SET_ITEM
(
result
,
1
,
PyString_FromString
(
PQfname
(
self
->
last_result
,
num
)));
PyTuple_SET_ITEM
(
result
,
2
,
PyInt_FromLong
(
PQftype
(
self
->
last_result
,
num
)));
return
result
;
}
/* lists fields info */
static
char
pgsource_listinfo__doc__
[]
=
"listinfo() -- return information for all fields "
"(position, name, type oid)."
;
static
PyObject
*
pgsource_listinfo
(
pgsourceobject
*
self
,
PyObject
*
args
)
{
int
i
;
PyObject
*
result
,
*
info
;
/* checks validity */
if
(
!
check_source_obj
(
self
,
CHECK_RESULT
|
CHECK_DQL
))
return
NULL
;
/* gets args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_TypeError
,
"method listinfo() takes no parameter."
);
return
NULL
;
}
/* builds result */
if
((
result
=
PyTuple_New
(
self
->
num_fields
))
==
NULL
)
return
NULL
;
for
(
i
=
0
;
i
<
self
->
num_fields
;
i
++
)
{
info
=
pgsource_buildinfo
(
self
,
i
);
if
(
!
info
)
{
Py_DECREF
(
result
);
return
NULL
;
}
PyTuple_SET_ITEM
(
result
,
i
,
info
);
}
/* returns result */
return
result
;
};
/* list fields information for last result */
static
char
pgsource_fieldinfo__doc__
[]
=
"fieldinfo(string|integer) -- return specified field information "
"(position, name, type oid)."
;
static
PyObject
*
pgsource_fieldinfo
(
pgsourceobject
*
self
,
PyObject
*
args
)
{
static
const
char
short_usage
[]
=
"fieldinfo(desc), with desc (string|integer)."
;
int
num
;
PyObject
*
param
;
/* gets args */
if
(
!
PyArg_ParseTuple
(
args
,
"O"
,
&
param
))
{
PyErr_SetString
(
PyExc_TypeError
,
short_usage
);
return
NULL
;
}
/* checks args and validity */
if
((
num
=
pgsource_fieldindex
(
self
,
param
,
short_usage
))
==
-
1
)
return
NULL
;
/* returns result */
return
pgsource_buildinfo
(
self
,
num
);
};
/* retrieve field value */
static
char
pgsource_field__doc__
[]
=
"field(string|integer) -- return specified field value."
;
static
PyObject
*
pgsource_field
(
pgsourceobject
*
self
,
PyObject
*
args
)
{
static
const
char
short_usage
[]
=
"field(desc), with desc (string|integer)."
;
int
num
;
PyObject
*
param
;
/* gets args */
if
(
!
PyArg_ParseTuple
(
args
,
"O"
,
&
param
))
{
PyErr_SetString
(
PyExc_TypeError
,
short_usage
);
return
NULL
;
}
/* checks args and validity */
if
((
num
=
pgsource_fieldindex
(
self
,
param
,
short_usage
))
==
-
1
)
return
NULL
;
return
PyString_FromString
(
PQgetvalue
(
self
->
last_result
,
self
->
current_row
,
num
));
}
/* query object methods */
static
PyMethodDef
pgsource_methods
[]
=
{
{
"close"
,
(
PyCFunction
)
pgsource_close
,
1
,
pgsource_close__doc__
},
{
"execute"
,
(
PyCFunction
)
pgsource_execute
,
1
,
pgsource_execute__doc__
},
{
"oidstatus"
,
(
PyCFunction
)
pgsource_oidstatus
,
1
,
pgsource_oidstatus__doc__
},
{
"fetch"
,
(
PyCFunction
)
pgsource_fetch
,
1
,
pgsource_fetch__doc__
},
{
"movefirst"
,
(
PyCFunction
)
pgsource_movefirst
,
1
,
pgsource_movefirst__doc__
},
{
"movelast"
,
(
PyCFunction
)
pgsource_movelast
,
1
,
pgsource_movelast__doc__
},
{
"movenext"
,
(
PyCFunction
)
pgsource_movenext
,
1
,
pgsource_movenext__doc__
},
{
"moveprev"
,
(
PyCFunction
)
pgsource_moveprev
,
1
,
pgsource_moveprev__doc__
},
{
"field"
,
(
PyCFunction
)
pgsource_field
,
1
,
pgsource_field__doc__
},
{
"fieldinfo"
,
(
PyCFunction
)
pgsource_fieldinfo
,
1
,
pgsource_fieldinfo__doc__
},
{
"listinfo"
,
(
PyCFunction
)
pgsource_listinfo
,
1
,
pgsource_listinfo__doc__
},
{
NULL
,
NULL
}
};
/* gets query object attributes */
static
PyObject
*
pgsource_getattr
(
pgsourceobject
*
self
,
char
*
name
)
{
/* pg connection object */
if
(
!
strcmp
(
name
,
"pgcnx"
))
{
if
(
check_source_obj
(
self
,
0
))
{
Py_INCREF
(
self
->
pgcnx
);
return
(
PyObject
*
)
(
self
->
pgcnx
);
}
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* arraysize */
if
(
!
strcmp
(
name
,
"arraysize"
))
return
PyInt_FromLong
(
self
->
arraysize
);
/* resulttype */
if
(
!
strcmp
(
name
,
"resulttype"
))
return
PyInt_FromLong
(
self
->
result_type
);
/* ntuples */
if
(
!
strcmp
(
name
,
"ntuples"
))
return
PyInt_FromLong
(
self
->
max_row
);
/* nfields */
if
(
!
strcmp
(
name
,
"nfields"
))
return
PyInt_FromLong
(
self
->
num_fields
);
/* attributes list */
if
(
!
strcmp
(
name
,
"__members__"
))
{
PyObject
*
list
=
PyList_New
(
5
);
PyList_SET_ITEM
(
list
,
0
,
PyString_FromString
(
"pgcnx"
));
PyList_SET_ITEM
(
list
,
1
,
PyString_FromString
(
"arraysize"
));
PyList_SET_ITEM
(
list
,
2
,
PyString_FromString
(
"resulttype"
));
PyList_SET_ITEM
(
list
,
3
,
PyString_FromString
(
"ntuples"
));
PyList_SET_ITEM
(
list
,
4
,
PyString_FromString
(
"nfields"
));
return
list
;
}
/* module name */
if
(
!
strcmp
(
name
,
"__module__"
))
return
PyString_FromString
(
MODULE_NAME
);
/* class name */
if
(
!
strcmp
(
name
,
"__class__"
))
return
PyString_FromString
(
"pgsource"
);
/* seeks name in methods (fallback) */
return
Py_FindMethod
(
pgsource_methods
,
(
PyObject
*
)
self
,
name
);
}
/* sets query object attributes */
static
int
pgsource_setattr
(
pgsourceobject
*
self
,
char
*
name
,
PyObject
*
v
)
{
/* arraysize */
if
(
!
strcmp
(
name
,
"arraysize"
))
{
if
(
!
PyInt_Check
(
v
))
{
PyErr_SetString
(
PyExc_TypeError
,
"arraysize must be integer."
);
return
-
1
;
}
self
->
arraysize
=
PyInt_AsLong
(
v
);
return
0
;
}
/* unknown attribute */
PyErr_SetString
(
PyExc_TypeError
,
"not a writable attribute."
);
return
-
1
;
}
/* prints query object in human readable format */
static
int
pgsource_print
(
pgsourceobject
*
self
,
FILE
*
fp
,
int
flags
)
{
PQprintOpt
op
;
switch
(
self
->
result_type
)
{
case
RESULT_DQL
:
memset
(
&
op
,
0
,
sizeof
(
op
));
op
.
align
=
1
;
op
.
header
=
1
;
op
.
fieldSep
=
"|"
;
op
.
pager
=
1
;
PQprint
(
fp
,
self
->
last_result
,
&
op
);
break
;
case
RESULT_DDL
:
case
RESULT_DML
:
fputs
(
PQcmdStatus
(
self
->
last_result
),
fp
);
break
;
case
RESULT_EMPTY
:
default:
fputs
(
"Empty PostgreSQL source object."
,
fp
);
break
;
}
return
0
;
}
/* query type definition */
staticforward
PyTypeObject
PgSourceType
=
{
PyObject_HEAD_INIT
(
&
PyType_Type
)
0
,
/* ob_size */
"pgsourceobject"
,
/* tp_name */
sizeof
(
pgsourceobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
(
destructor
)
pgsource_dealloc
,
/* tp_dealloc */
(
printfunc
)
pgsource_print
,
/* tp_print */
(
getattrfunc
)
pgsource_getattr
,
/* tp_getattr */
(
setattrfunc
)
pgsource_setattr
,
/* tp_setattr */
0
,
/* tp_compare */
0
,
/* tp_repr */
0
,
/* tp_as_number */
0
,
/* tp_as_sequence */
0
,
/* tp_as_mapping */
0
,
/* tp_hash */
};
/* --------------------------------------------------------------------- */
/* PG
CONNECTION
OBJECT IMPLEMENTATION */
/* PG
"LARGE"
OBJECT IMPLEMENTATION */
#ifdef LARGE_OBJECTS
...
...
@@ -195,7 +963,7 @@ check_lo_obj(pglargeobject * self, int level)
static
pglargeobject
*
pglarge_new
(
pgobject
*
pgcnx
,
Oid
oid
)
{
pglargeobject
*
npglo
;
pglargeobject
*
npglo
;
if
((
npglo
=
PyObject_NEW
(
pglargeobject
,
&
PglargeType
))
==
NULL
)
return
NULL
;
...
...
@@ -221,14 +989,13 @@ pglarge_dealloc(pglargeobject * self)
/* opens large object */
static
char
pglarge_open__doc__
[]
=
"open(mode) -- open access to large object with specified mode "
"(INV_READ, INV_WRITE constants defined by module)."
;
"open(mode) -- open access to large object with specified mode "
"(INV_READ, INV_WRITE constants defined by module)."
;
static
PyObject
*
pglarge_open
(
pglargeobject
*
self
,
PyObject
*
args
)
{
int
mode
,
fd
;
int
mode
,
fd
;
/* check validity */
if
(
!
check_lo_obj
(
self
,
CHECK_CLOSE
))
...
...
@@ -256,7 +1023,7 @@ pglarge_open(pglargeobject * self, PyObject * args)
/* close large object */
static
char
pglarge_close__doc__
[]
=
"close() -- close access to large object data."
;
"close() -- close access to large object data."
;
static
PyObject
*
pglarge_close
(
pglargeobject
*
self
,
PyObject
*
args
)
...
...
@@ -265,7 +1032,7 @@ pglarge_close(pglargeobject * self, PyObject * args)
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method close() takes no parameters."
);
"method close() takes no parameters."
);
return
NULL
;
}
...
...
@@ -288,14 +1055,14 @@ pglarge_close(pglargeobject * self, PyObject * args)
/* reads from large object */
static
char
pglarge_read__doc__
[]
=
"read(integer) -- read from large object to sized string. "
"Object must be opened in read mode before calling this method."
;
"read(integer) -- read from large object to sized string. "
"Object must be opened in read mode before calling this method."
;
static
PyObject
*
pglarge_read
(
pglargeobject
*
self
,
PyObject
*
args
)
{
int
size
;
PyObject
*
buffer
;
PyObject
*
buffer
;
/* checks validity */
if
(
!
check_lo_obj
(
self
,
CHECK_OPEN
))
...
...
@@ -331,30 +1098,30 @@ pglarge_read(pglargeobject * self, PyObject * args)
/* write to large object */
static
char
pglarge_write__doc__
[]
=
"write(string) -- write sized string to large object. "
"Object must be opened in read mode before calling this method."
;
"write(string) -- write sized string to large object. "
"Object must be opened in read mode before calling this method."
;
static
PyObject
*
pglarge_write
(
pglargeobject
*
self
,
PyObject
*
args
)
{
char
*
buffer
;
int
size
;
char
*
buffer
;
int
size
,
buf
size
;
/* checks validity */
if
(
!
check_lo_obj
(
self
,
CHECK_OPEN
))
return
NULL
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"s
"
,
&
buffer
))
if
(
!
PyArg_ParseTuple
(
args
,
"s
#"
,
&
buffer
,
&
bufsize
))
{
PyErr_SetString
(
PyExc_TypeError
,
"write(buffer), with buffer (sized string)."
);
"write(buffer), with buffer (sized string)."
);
return
NULL
;
}
/* sends query */
if
((
size
=
lo_write
(
self
->
pgcnx
->
cnx
,
self
->
lo_fd
,
buffer
,
strlen
(
buffer
)))
<
strlen
(
buffer
)
)
bufsize
))
<
bufsize
)
{
PyErr_SetString
(
PyExc_IOError
,
"buffer truncated during write."
);
return
NULL
;
...
...
@@ -367,17 +1134,15 @@ pglarge_write(pglargeobject * self, PyObject * args)
/* go to position in large object */
static
char
pglarge_seek__doc__
[]
=
"seek(off, whence) -- move to specified position. Object must be opened "
"before calling this method. whence can be SEEK_SET, SEEK_CUR or SEEK_END, "
"constants defined by module."
;
"seek(off, whence) -- move to specified position. Object must be opened "
"before calling this method. whence can be SEEK_SET, SEEK_CUR or SEEK_END, "
"constants defined by module."
;
static
PyObject
*
pglarge_lseek
(
pglargeobject
*
self
,
PyObject
*
args
)
{
/* offset and whence are initialized to keep compiler happy */
int
ret
,
offset
=
0
,
whence
=
0
;
int
ret
,
offset
=
0
,
whence
=
0
;
/* checks validity */
if
(
!
check_lo_obj
(
self
,
CHECK_OPEN
))
...
...
@@ -387,7 +1152,7 @@ pglarge_lseek(pglargeobject * self, PyObject * args)
if
(
!
PyArg_ParseTuple
(
args
,
"ii"
,
&
offset
,
&
whence
))
{
PyErr_SetString
(
PyExc_TypeError
,
"lseek(offset, whence), with offset and whence (integers)."
);
"lseek(offset, whence), with offset and whence (integers)."
);
return
NULL
;
}
...
...
@@ -404,20 +1169,19 @@ pglarge_lseek(pglargeobject * self, PyObject * args)
/* gets large object size */
static
char
pglarge_size__doc__
[]
=
"size() -- return large object size. "
"Object must be opened before calling this method."
;
"size() -- return large object size. "
"Object must be opened before calling this method."
;
static
PyObject
*
pglarge_size
(
pglargeobject
*
self
,
PyObject
*
args
)
{
int
start
,
end
;
int
start
,
end
;
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method size() takes no parameters."
);
"method size() takes no parameters."
);
return
NULL
;
}
...
...
@@ -440,10 +1204,10 @@ pglarge_size(pglargeobject * self, PyObject * args)
}
/* move back to start position */
if
((
start
=
lo_lseek
(
self
->
pgcnx
->
cnx
,
self
->
lo_fd
,
start
,
SEEK_SET
))
==
-
1
)
if
((
start
=
lo_lseek
(
self
->
pgcnx
->
cnx
,
self
->
lo_fd
,
start
,
SEEK_SET
))
==
-
1
)
{
PyErr_SetString
(
PyExc_IOError
,
"error while moving back to first position."
);
"error while moving back to first position."
);
return
NULL
;
}
...
...
@@ -453,19 +1217,19 @@ pglarge_size(pglargeobject * self, PyObject * args)
/* gets large object cursor position */
static
char
pglarge_tell__doc__
[]
=
"tell() -- give current position in large object. "
"Object must be opened before calling this method."
;
"tell() -- give current position in large object. "
"Object must be opened before calling this method."
;
static
PyObject
*
pglarge_tell
(
pglargeobject
*
self
,
PyObject
*
args
)
{
int
start
;
int
start
;
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method tell() takes no parameters."
);
"method tell() takes no parameters."
);
return
NULL
;
}
...
...
@@ -486,13 +1250,13 @@ pglarge_tell(pglargeobject * self, PyObject * args)
/* exports large object as unix file */
static
char
pglarge_export__doc__
[]
=
"export(string) -- export large object data to specified file. "
"Object must be closed when calling this method."
;
"export(string) -- export large object data to specified file. "
"Object must be closed when calling this method."
;
static
PyObject
*
pglarge_export
(
pglargeobject
*
self
,
PyObject
*
args
)
{
char
*
name
;
char
*
name
;
/* checks validity */
if
(
!
check_lo_obj
(
self
,
CHECK_CLOSE
))
...
...
@@ -502,7 +1266,7 @@ pglarge_export(pglargeobject * self, PyObject * args)
if
(
!
PyArg_ParseTuple
(
args
,
"s"
,
&
name
))
{
PyErr_SetString
(
PyExc_TypeError
,
"export(filename), with filename (string)."
);
"export(filename), with filename (string)."
);
return
NULL
;
}
...
...
@@ -519,8 +1283,8 @@ pglarge_export(pglargeobject * self, PyObject * args)
/* deletes a large object */
static
char
pglarge_unlink__doc__
[]
=
"unlink() -- destroy large object. "
"Object must be closed when calling this method."
;
"unlink() -- destroy large object. "
"Object must be closed when calling this method."
;
static
PyObject
*
pglarge_unlink
(
pglargeobject
*
self
,
PyObject
*
args
)
...
...
@@ -529,7 +1293,7 @@ pglarge_unlink(pglargeobject * self, PyObject * args)
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method unlink() takes no parameters."
);
"method unlink() takes no parameters."
);
return
NULL
;
}
...
...
@@ -551,15 +1315,15 @@ pglarge_unlink(pglargeobject * self, PyObject * args)
/* large object methods */
static
struct
PyMethodDef
pglarge_methods
[]
=
{
{
"open"
,
(
PyCFunction
)
pglarge_open
,
1
,
pglarge_open__doc__
},
{
"close"
,
(
PyCFunction
)
pglarge_close
,
1
,
pglarge_close__doc__
},
{
"read"
,
(
PyCFunction
)
pglarge_read
,
1
,
pglarge_read__doc__
},
{
"write"
,
(
PyCFunction
)
pglarge_write
,
1
,
pglarge_write__doc__
},
{
"seek"
,
(
PyCFunction
)
pglarge_lseek
,
1
,
pglarge_seek__doc__
},
{
"size"
,
(
PyCFunction
)
pglarge_size
,
1
,
pglarge_size__doc__
},
{
"tell"
,
(
PyCFunction
)
pglarge_tell
,
1
,
pglarge_tell__doc__
},
{
"export"
,
(
PyCFunction
)
pglarge_export
,
1
,
pglarge_export__doc__
},
{
"unlink"
,
(
PyCFunction
)
pglarge_unlink
,
1
,
pglarge_unlink__doc__
},
{
"open"
,
(
PyCFunction
)
pglarge_open
,
1
,
pglarge_open__doc__
},
{
"close"
,
(
PyCFunction
)
pglarge_close
,
1
,
pglarge_close__doc__
},
{
"read"
,
(
PyCFunction
)
pglarge_read
,
1
,
pglarge_read__doc__
},
{
"write"
,
(
PyCFunction
)
pglarge_write
,
1
,
pglarge_write__doc__
},
{
"seek"
,
(
PyCFunction
)
pglarge_lseek
,
1
,
pglarge_seek__doc__
},
{
"size"
,
(
PyCFunction
)
pglarge_size
,
1
,
pglarge_size__doc__
},
{
"tell"
,
(
PyCFunction
)
pglarge_tell
,
1
,
pglarge_tell__doc__
},
{
"export"
,
(
PyCFunction
)
pglarge_export
,
1
,
pglarge_export__doc__
},
{
"unlink"
,
(
PyCFunction
)
pglarge_unlink
,
1
,
pglarge_unlink__doc__
},
{
NULL
,
NULL
}
};
...
...
@@ -599,13 +1363,13 @@ pglarge_getattr(pglargeobject * self, char *name)
/* attributes list */
if
(
!
strcmp
(
name
,
"__members__"
))
{
PyObject
*
list
=
PyList_New
(
3
);
PyObject
*
list
=
PyList_New
(
3
);
if
(
list
)
{
PyList_S
etItem
(
list
,
0
,
PyString_FromString
(
"oid"
));
PyList_S
etItem
(
list
,
1
,
PyString_FromString
(
"pgcnx"
));
PyList_S
etItem
(
list
,
2
,
PyString_FromString
(
"error"
));
PyList_S
ET_ITEM
(
list
,
0
,
PyString_FromString
(
"oid"
));
PyList_S
ET_ITEM
(
list
,
1
,
PyString_FromString
(
"pgcnx"
));
PyList_S
ET_ITEM
(
list
,
2
,
PyString_FromString
(
"error"
));
}
return
list
;
...
...
@@ -627,46 +1391,56 @@ pglarge_getattr(pglargeobject * self, char *name)
static
int
pglarge_print
(
pglargeobject
*
self
,
FILE
*
fp
,
int
flags
)
{
char
print_buffer
[
128
];
char
print_buffer
[
128
];
if
(
self
->
lo_fd
>=
0
)
{
#ifdef NO_SNPRINTF
sprintf
(
print_buffer
,
"Opened large object, oid %ld"
,
(
long
)
self
->
lo_oid
);
#else
snprintf
(
print_buffer
,
sizeof
(
print_buffer
),
"Opened large object, oid %ld"
,
(
long
)
self
->
lo_oid
);
"Opened large object, oid %ld"
,
(
long
)
self
->
lo_oid
);
#endif
fputs
(
print_buffer
,
fp
);
}
else
{
#ifdef NO_SNPRINTF
sprintf
(
print_buffer
,
"Closed large object, oid %ld"
,
(
long
)
self
->
lo_oid
);
#else
snprintf
(
print_buffer
,
sizeof
(
print_buffer
),
"Closed large object, oid %ld"
,
(
long
)
self
->
lo_oid
);
"Closed large object, oid %ld"
,
(
long
)
self
->
lo_oid
);
#endif
fputs
(
print_buffer
,
fp
);
}
return
0
;
}
;
}
/* object type definition */
staticforward
PyTypeObject
PglargeType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/* ob_size */
"pglarge"
,
/* tp_name */
sizeof
(
pglargeobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
0
,
/* ob_size */
"pglarge"
,
/* tp_name */
sizeof
(
pglargeobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
(
destructor
)
pglarge_dealloc
,
/* tp_dealloc */
(
printfunc
)
pglarge_print
,
/* tp_print */
(
getattrfunc
)
pglarge_getattr
,
/* tp_getattr */
0
,
/* tp_setattr */
0
,
/* tp_compare */
0
,
/* tp_repr */
0
,
/* tp_as_number */
0
,
/* tp_as_sequence */
0
,
/* tp_as_mapping */
0
,
/* tp_hash */
(
destructor
)
pglarge_dealloc
,
/* tp_dealloc */
(
printfunc
)
pglarge_print
,
/* tp_print */
(
getattrfunc
)
pglarge_getattr
,
/* tp_getattr */
0
,
/* tp_setattr */
0
,
/* tp_compare */
0
,
/* tp_repr */
0
,
/* tp_as_number */
0
,
/* tp_as_sequence */
0
,
/* tp_as_mapping */
0
,
/* tp_hash */
};
#endif
/* LARGE_OBJECTS */
#endif
/* LARGE_OBJECTS */
/* --------------------------------------------------------------------- */
...
...
@@ -674,35 +1448,29 @@ staticforward PyTypeObject PglargeType = {
/* connects to a database */
static
char
connect__doc__
[]
=
"connect(dbname, host, port, opt, tty) -- connect to a PostgreSQL database "
"using specified parameters (optionals, keywords aware)."
;
"connect(dbname, host, port, opt, tty) -- connect to a PostgreSQL database "
"using specified parameters (optionals, keywords aware)."
;
static
PyObject
*
pgconnect
(
pgobject
*
self
,
PyObject
*
args
,
PyObject
*
dict
)
{
static
char
*
kwlist
[]
=
{
"dbname"
,
"host"
,
"port"
,
"opt"
,
"tty"
,
"user"
,
"passwd"
,
NULL
};
char
*
pghost
,
*
pgopt
,
*
pgtty
,
*
pgdbname
,
*
pguser
,
*
pgpasswd
;
int
pgport
;
char
port_buffer
[
20
];
pgobject
*
npgobj
;
pgconnect
(
pgobject
*
self
,
PyObject
*
args
,
PyObject
*
dict
)
{
static
const
char
*
kwlist
[]
=
{
"dbname"
,
"host"
,
"port"
,
"opt"
,
"tty"
,
"user"
,
"passwd"
,
NULL
};
char
*
pghost
,
*
pgopt
,
*
pgtty
,
*
pgdbname
,
*
pguser
,
*
pgpasswd
;
int
pgport
;
char
port_buffer
[
20
];
pgobject
*
npgobj
;
pghost
=
pgopt
=
pgtty
=
pgdbname
=
pguser
=
pgpasswd
=
NULL
;
pgport
=
-
1
;
/*
* parses standard arguments With the right compiler warnings, this
* will issue a diagnostic. There is really no way around it. If I
* don't declare kwlist as const char *kwlist[] then it complains when
* I try to assign all those constant strings to it.
*/
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
dict
,
"|zzlzzzz"
,
kwlist
,
&
pgdbname
,
&
pghost
,
&
pgport
,
&
pgopt
,
&
pgtty
,
&
pguser
,
&
pgpasswd
))
/* parses standard arguments
* With the right compiler warnings, this will issue a diagnostic.
* There is really no way around it. If I don't declare kwlist as
* const char *kwlist[] then it complains when I try to assign all
* those constant strings to it. */
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
dict
,
"|zzlzzzz"
,
(
char
**
)
kwlist
,
&
pgdbname
,
&
pghost
,
&
pgport
,
&
pgopt
,
&
pgtty
,
&
pguser
,
&
pgpasswd
))
return
NULL
;
#ifdef DEFAULT_VARS
...
...
@@ -727,9 +1495,9 @@ pgconnect(pgobject * self, PyObject * args, PyObject * dict)
if
((
!
pgpasswd
)
&&
(
pg_default_passwd
!=
Py_None
))
pgpasswd
=
PyString_AsString
(
pg_default_passwd
);
#endif
/* DEFAULT_VARS */
#endif
/* DEFAULT_VARS */
if
((
npgobj
=
PyObject_NEW
(
pgobject
,
&
PgType
))
==
NULL
)
if
((
npgobj
=
(
pgobject
*
)
pgobject_New
(
))
==
NULL
)
return
NULL
;
if
(
pgport
!=
-
1
)
...
...
@@ -737,11 +1505,11 @@ pgconnect(pgobject * self, PyObject * args, PyObject * dict)
bzero
(
port_buffer
,
sizeof
(
port_buffer
));
sprintf
(
port_buffer
,
"%d"
,
pgport
);
npgobj
->
cnx
=
PQsetdbLogin
(
pghost
,
port_buffer
,
pgopt
,
pgtty
,
pgdbname
,
pguser
,
pgpasswd
);
pguser
,
pgpasswd
);
}
else
npgobj
->
cnx
=
PQsetdbLogin
(
pghost
,
NULL
,
pgopt
,
pgtty
,
pgdbname
,
pguser
,
pgpasswd
);
pguser
,
pgpasswd
);
if
(
PQstatus
(
npgobj
->
cnx
)
==
CONNECTION_BAD
)
{
...
...
@@ -767,12 +1535,12 @@ pg_dealloc(pgobject * self)
/* close without deleting */
static
char
pg_close__doc__
[]
=
"close() -- close connection. All instances of the connection object and "
"derived objects (queries and large objects) can no longer be used after "
"this call."
;
"close() -- close connection. All instances of the connection object and "
"derived objects (queries and large objects) can no longer be used after "
"this call."
;
static
PyObject
*
pg_close
(
pgobject
*
self
,
PyObject
*
args
)
pg_close
(
pgobject
*
self
,
PyObject
*
args
)
{
/* gets args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
...
...
@@ -800,9 +1568,9 @@ pgquery_dealloc(pgqueryobject * self)
/* resets connection */
static
char
pg_reset__doc__
[]
=
"reset() -- reset connection with current parameters. All derived queries "
"and large objects derived from this connection will not be usable after "
"this call."
;
"reset() -- reset connection with current parameters. All derived queries "
"and large objects derived from this connection will not be usable after "
"this call."
;
static
PyObject
*
pg_reset
(
pgobject
*
self
,
PyObject
*
args
)
...
...
@@ -817,7 +1585,7 @@ pg_reset(pgobject * self, PyObject * args)
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method reset() takes no parameters."
);
"method reset() takes no parameters."
);
return
NULL
;
}
...
...
@@ -829,7 +1597,7 @@ pg_reset(pgobject * self, PyObject * args)
/* get connection socket */
static
char
pg_fileno__doc__
[]
=
"fileno() -- return database connection socket file handle."
;
"fileno() -- return database connection socket file handle."
;
static
PyObject
*
pg_fileno
(
pgobject
*
self
,
PyObject
*
args
)
...
...
@@ -844,7 +1612,7 @@ pg_fileno(pgobject * self, PyObject * args)
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method fileno() takes no parameters."
);
"method fileno() takes no parameters."
);
return
NULL
;
}
...
...
@@ -857,7 +1625,7 @@ pg_fileno(pgobject * self, PyObject * args)
/* get number of rows */
static
char
pgquery_ntuples__doc__
[]
=
"ntuples() -- returns number of tuples returned by query."
;
"ntuples() -- returns number of tuples returned by query."
;
static
PyObject
*
pgquery_ntuples
(
pgqueryobject
*
self
,
PyObject
*
args
)
...
...
@@ -866,7 +1634,7 @@ pgquery_ntuples(pgqueryobject * self, PyObject * args)
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method ntuples() takes no parameters."
);
"method ntuples() takes no parameters."
);
return
NULL
;
}
...
...
@@ -875,22 +1643,20 @@ pgquery_ntuples(pgqueryobject * self, PyObject * args)
/* list fields names from query result */
static
char
pgquery_listfields__doc__
[]
=
"listfields() -- Lists field names from result."
;
"listfields() -- Lists field names from result."
;
static
PyObject
*
pgquery_listfields
(
pgqueryobject
*
self
,
PyObject
*
args
)
{
int
i
,
n
;
char
*
name
;
PyObject
*
fieldstuple
,
*
str
;
int
i
,
n
;
char
*
name
;
PyObject
*
fieldstuple
,
*
str
;
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method listfields() takes no parameters."
);
"method listfields() takes no parameters."
);
return
NULL
;
}
...
...
@@ -902,7 +1668,7 @@ pgquery_listfields(pgqueryobject * self, PyObject * args)
{
name
=
PQfname
(
self
->
last_result
,
i
);
str
=
PyString_FromString
(
name
);
PyTuple_S
etItem
(
fieldstuple
,
i
,
str
);
PyTuple_S
ET_ITEM
(
fieldstuple
,
i
,
str
);
}
return
fieldstuple
;
...
...
@@ -910,19 +1676,19 @@ pgquery_listfields(pgqueryobject * self, PyObject * args)
/* get field name from last result */
static
char
pgquery_fieldname__doc__
[]
=
"fieldname() -- returns name of field from result from its position."
;
"fieldname() -- returns name of field from result from its position."
;
static
PyObject
*
pgquery_fieldname
(
pgqueryobject
*
self
,
PyObject
*
args
)
{
int
i
;
char
*
name
;
int
i
;
char
*
name
;
/* gets args */
if
(
!
PyArg_ParseTuple
(
args
,
"i"
,
&
i
))
{
PyErr_SetString
(
PyExc_TypeError
,
"fieldname(number), with number(integer)."
);
"fieldname(number), with number(integer)."
);
return
NULL
;
}
...
...
@@ -940,13 +1706,13 @@ pgquery_fieldname(pgqueryobject * self, PyObject * args)
/* gets fields number from name in last result */
static
char
pgquery_fieldnum__doc__
[]
=
"fieldnum() -- returns position in query for field from its name."
;
"fieldnum() -- returns position in query for field from its name."
;
static
PyObject
*
pgquery_fieldnum
(
pgqueryobject
*
self
,
PyObject
*
args
)
{
char
*
name
;
int
num
;
char
*
name
;
int
num
;
/* gets args */
if
(
!
PyArg_ParseTuple
(
args
,
"s"
,
&
name
))
...
...
@@ -967,34 +1733,28 @@ pgquery_fieldnum(pgqueryobject * self, PyObject * args)
/* retrieves last result */
static
char
pgquery_getresult__doc__
[]
=
"getresult() -- Gets the result of a query. The result is returned "
"as a list of rows, each one a list of fields in the order returned "
"by the server."
;
"getresult() -- Gets the result of a query. The result is returned "
"as a list of rows, each one a list of fields in the order returned "
"by the server."
;
static
PyObject
*
pgquery_getresult
(
pgqueryobject
*
self
,
PyObject
*
args
)
{
PyObject
*
rowtuple
,
*
reslist
,
*
val
;
int
i
,
j
,
m
,
n
,
*
typ
;
PyObject
*
rowtuple
,
*
reslist
,
*
val
;
int
i
,
j
,
m
,
n
,
*
typ
;
/* checks args (args == NULL for an internal call) */
if
((
args
!=
NULL
)
&&
(
!
PyArg_ParseTuple
(
args
,
""
)))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method getresult() takes no parameters."
);
"method getresult() takes no parameters."
);
return
NULL
;
}
/* stores result in tuple */
reslist
=
PyList_New
(
0
);
m
=
PQntuples
(
self
->
last_result
);
n
=
PQnfields
(
self
->
last_result
);
reslist
=
PyList_New
(
m
);
if
((
typ
=
malloc
(
sizeof
(
int
)
*
n
))
==
NULL
)
{
...
...
@@ -1029,14 +1789,25 @@ pgquery_getresult(pgqueryobject * self, PyObject * args)
for
(
i
=
0
;
i
<
m
;
i
++
)
{
rowtuple
=
PyTuple_New
(
n
);
if
((
rowtuple
=
PyTuple_New
(
n
))
==
NULL
)
{
Py_DECREF
(
reslist
);
reslist
=
NULL
;
goto
exit
;
}
for
(
j
=
0
;
j
<
n
;
j
++
)
{
int
k
;
char
*
s
=
PQgetvalue
(
self
->
last_result
,
i
,
j
);
char
cashbuf
[
64
];
int
k
;
char
*
s
=
PQgetvalue
(
self
->
last_result
,
i
,
j
);
char
cashbuf
[
64
];
switch
(
typ
[
j
])
if
(
PQgetisnull
(
self
->
last_result
,
i
,
j
))
{
Py_INCREF
(
Py_None
);
val
=
Py_None
;
}
else
switch
(
typ
[
j
])
{
case
1
:
val
=
PyInt_FromLong
(
strtol
(
s
,
NULL
,
10
));
...
...
@@ -1046,9 +1817,8 @@ pgquery_getresult(pgqueryobject * self, PyObject * args)
val
=
PyFloat_FromDouble
(
strtod
(
s
,
NULL
));
break
;
case
3
:
/* get rid of the '$' and commas */
if
(
*
s
==
'$'
)
/* there's talk of getting rid of
* it */
case
3
:
/* get rid of the '$' and commas */
if
(
*
s
==
'$'
)
/* there's talk of getting rid of it */
s
++
;
if
((
s
[
0
]
==
'-'
||
s
[
0
]
==
'('
)
&&
s
[
1
]
==
'$'
)
...
...
@@ -1067,13 +1837,21 @@ pgquery_getresult(pgqueryobject * self, PyObject * args)
break
;
}
PyTuple_SetItem
(
rowtuple
,
j
,
val
);
if
(
val
==
NULL
)
{
Py_DECREF
(
reslist
);
Py_DECREF
(
rowtuple
);
reslist
=
NULL
;
goto
exit
;
}
PyTuple_SET_ITEM
(
rowtuple
,
j
,
val
);
}
PyList_Append
(
reslist
,
rowtuple
);
Py_XDECREF
(
rowtuple
);
PyList_SET_ITEM
(
reslist
,
i
,
rowtuple
);
}
exit:
free
(
typ
);
/* returns list */
...
...
@@ -1082,34 +1860,28 @@ pgquery_getresult(pgqueryobject * self, PyObject * args)
/* retrieves last result as a list of dictionaries*/
static
char
pgquery_dictresult__doc__
[]
=
"dictresult() -- Gets the result of a query. The result is returned "
"as a list of rows, each one a dictionary with the field names used "
"as the labels."
;
"dictresult() -- Gets the result of a query. The result is returned "
"as a list of rows, each one a dictionary with the field names used "
"as the labels."
;
static
PyObject
*
pgquery_dictresult
(
pgqueryobject
*
self
,
PyObject
*
args
)
{
PyObject
*
dict
,
*
reslist
,
*
val
;
int
i
,
j
,
m
,
n
,
*
typ
;
PyObject
*
dict
,
*
reslist
,
*
val
;
int
i
,
j
,
m
,
n
,
*
typ
;
/* checks args (args == NULL for an internal call) */
if
((
args
!=
NULL
)
&&
(
!
PyArg_ParseTuple
(
args
,
""
)))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method getresult() takes no parameters."
);
"method getresult() takes no parameters."
);
return
NULL
;
}
/* stores result in list */
reslist
=
PyList_New
(
0
);
m
=
PQntuples
(
self
->
last_result
);
n
=
PQnfields
(
self
->
last_result
);
reslist
=
PyList_New
(
m
);
if
((
typ
=
malloc
(
sizeof
(
int
)
*
n
))
==
NULL
)
{
...
...
@@ -1144,14 +1916,25 @@ pgquery_dictresult(pgqueryobject * self, PyObject * args)
for
(
i
=
0
;
i
<
m
;
i
++
)
{
dict
=
PyDict_New
();
if
((
dict
=
PyDict_New
())
==
NULL
)
{
Py_DECREF
(
reslist
);
reslist
=
NULL
;
goto
exit
;
}
for
(
j
=
0
;
j
<
n
;
j
++
)
{
int
k
;
char
*
s
=
PQgetvalue
(
self
->
last_result
,
i
,
j
);
char
cashbuf
[
64
];
int
k
;
char
*
s
=
PQgetvalue
(
self
->
last_result
,
i
,
j
);
char
cashbuf
[
64
];
switch
(
typ
[
j
])
if
(
PQgetisnull
(
self
->
last_result
,
i
,
j
))
{
Py_INCREF
(
Py_None
);
val
=
Py_None
;
}
else
switch
(
typ
[
j
])
{
case
1
:
val
=
PyInt_FromLong
(
strtol
(
s
,
NULL
,
10
));
...
...
@@ -1161,9 +1944,8 @@ pgquery_dictresult(pgqueryobject * self, PyObject * args)
val
=
PyFloat_FromDouble
(
strtod
(
s
,
NULL
));
break
;
case
3
:
/* get rid of the '$' and commas */
if
(
*
s
==
'$'
)
/* there's talk of getting rid of
* it */
case
3
:
/* get rid of the '$' and commas */
if
(
*
s
==
'$'
)
/* there's talk of getting rid of it */
s
++
;
if
((
s
[
0
]
==
'-'
||
s
[
0
]
==
'('
)
&&
s
[
1
]
==
'$'
)
...
...
@@ -1182,14 +1964,22 @@ pgquery_dictresult(pgqueryobject * self, PyObject * args)
break
;
}
if
(
val
==
NULL
)
{
Py_DECREF
(
dict
);
Py_DECREF
(
reslist
);
reslist
=
NULL
;
goto
exit
;
}
PyDict_SetItemString
(
dict
,
PQfname
(
self
->
last_result
,
j
),
val
);
Py_
X
DECREF
(
val
);
Py_DECREF
(
val
);
}
PyList_Append
(
reslist
,
dict
);
Py_XDECREF
(
dict
);
PyList_SET_ITEM
(
reslist
,
i
,
dict
);
}
exit:
free
(
typ
);
/* returns list */
...
...
@@ -1198,15 +1988,14 @@ pgquery_dictresult(pgqueryobject * self, PyObject * args)
/* gets asynchronous notify */
static
char
pg_getnotify__doc__
[]
=
"getnotify() -- get database notify for this connection."
;
"getnotify() -- get database notify for this connection."
;
static
PyObject
*
pg_getnotify
(
pgobject
*
self
,
PyObject
*
args
)
{
PGnotify
*
notify
;
PGresult
*
result
;
PyObject
*
notify_result
,
*
temp
;
PGnotify
*
notify
;
PGresult
*
result
;
PyObject
*
notify_result
,
*
temp
;
if
(
!
self
->
cnx
)
{
...
...
@@ -1218,25 +2007,40 @@ pg_getnotify(pgobject * self, PyObject * args)
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method getnotify() takes no parameters."
);
"method getnotify() takes no parameters."
);
return
NULL
;
}
/* gets notify and builds result */
/*
* notifies only come back as result of a query, so I send an empty
* query
*/
/* notifies only come back as result of a query, so I send an empty query */
Py_BEGIN_ALLOW_THREADS
result
=
PQexec
(
self
->
cnx
,
" "
);
Py_END_ALLOW_THREADS
if
((
notify
=
PQnotifies
(
self
->
cnx
))
!=
NULL
)
{
notify_result
=
PyTuple_New
(
2
);
temp
=
PyString_FromString
(
notify
->
relname
);
PyTuple_SetItem
(
notify_result
,
0
,
temp
);
temp
=
PyInt_FromLong
(
notify
->
be_pid
);
PyTuple_SetItem
(
notify_result
,
1
,
temp
);
if
((
notify_result
=
PyTuple_New
(
2
))
==
NULL
)
{
PQclear
(
result
);
return
NULL
;
}
if
((
temp
=
PyString_FromString
(
notify
->
relname
))
==
NULL
)
{
PQclear
(
result
);
return
NULL
;
}
PyTuple_SET_ITEM
(
notify_result
,
0
,
temp
);
if
((
temp
=
PyInt_FromLong
(
notify
->
be_pid
))
==
NULL
)
{
PQclear
(
result
);
Py_DECREF
(
notify_result
);
return
NULL
;
}
PyTuple_SET_ITEM
(
notify_result
,
1
,
temp
);
free
(
notify
);
}
else
...
...
@@ -1251,17 +2055,40 @@ pg_getnotify(pgobject * self, PyObject * args)
return
notify_result
;
}
/* source creation */
static
char
pg_source__doc__
[]
=
"source() -- creates a new source object for this connection"
;
static
PyObject
*
pg_source
(
pgobject
*
self
,
PyObject
*
args
)
{
/* checks validity */
if
(
!
check_cnx_obj
(
self
))
return
NULL
;
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_TypeError
,
"method source() takes no parameter."
);
return
NULL
;
}
/* allocate new pg query object */
return
(
PyObject
*
)
pgsource_new
(
self
);
}
/* database query */
static
char
pg_query__doc__
[]
=
"query() -- creates a new query object for this connection."
;
"query(sql) -- creates a new query object for this connection,"
" using sql (string) request."
;
static
PyObject
*
pg_query
(
pgobject
*
self
,
PyObject
*
args
)
{
char
*
query
;
PGresult
*
result
;
pgqueryobject
*
npgobj
;
int
status
;
char
*
query
;
PGresult
*
result
;
pgqueryobject
*
npgobj
;
int
status
;
if
(
!
self
->
cnx
)
{
...
...
@@ -1276,8 +2103,17 @@ pg_query(pgobject * self, PyObject * args)
return
NULL
;
}
/* frees previous result */
if
(
self
->
last_result
)
{
PQclear
(
self
->
last_result
);
self
->
last_result
=
NULL
;
}
/* gets result */
Py_BEGIN_ALLOW_THREADS
result
=
PQexec
(
self
->
cnx
,
query
);
Py_END_ALLOW_THREADS
/* checks result validity */
if
(
!
result
)
...
...
@@ -1303,7 +2139,7 @@ pg_query(pgobject * self, PyObject * args)
case
PGRES_NONFATAL_ERROR
:
PyErr_SetString
(
PGError
,
PQerrorMessage
(
self
->
cnx
));
break
;
case
PGRES_COMMAND_OK
:
/* could be an INSERT */
case
PGRES_COMMAND_OK
:
/* could be an INSERT */
if
(
*
(
str
=
PQoidStatus
(
result
))
==
0
)
/* nope */
{
Py_INCREF
(
Py_None
);
...
...
@@ -1313,13 +2149,13 @@ pg_query(pgobject * self, PyObject * args)
/* otherwise, return the oid */
return
PyInt_FromLong
(
strtol
(
str
,
NULL
,
10
));
case
PGRES_COPY_OUT
:
/* no data will be received */
case
PGRES_COPY_OUT
:
/* no data will be received */
case
PGRES_COPY_IN
:
Py_INCREF
(
Py_None
);
return
Py_None
;
default:
PyErr_SetString
(
PGError
,
"internal error: "
"unknown result status."
);
"unknown result status."
);
break
;
}
...
...
@@ -1336,13 +2172,13 @@ pg_query(pgobject * self, PyObject * args)
#ifdef DIRECT_ACCESS
static
char
pg_putline__doc__
[]
=
"putline() -- sends a line directly to the backend"
;
"putline() -- sends a line directly to the backend"
;
/* direct acces function : putline */
static
PyObject
*
pg_putline
(
pgobject
*
self
,
PyObject
*
args
)
{
char
*
line
;
char
*
line
;
if
(
!
self
->
cnx
)
{
...
...
@@ -1365,14 +2201,13 @@ pg_putline(pgobject * self, PyObject * args)
/* direct access function : getline */
static
char
pg_getline__doc__
[]
=
"getline() -- gets a line directly from the backend."
;
"getline() -- gets a line directly from the backend."
;
static
PyObject
*
pg_getline
(
pgobject
*
self
,
PyObject
*
args
)
{
char
line
[
MAX_BUFFER_SIZE
];
PyObject
*
str
=
NULL
;
/* GCC */
int
ret
;
PyObject
*
str
=
NULL
;
/* GCC */
if
(
!
self
->
cnx
)
{
...
...
@@ -1384,7 +2219,7 @@ pg_getline(pgobject * self, PyObject * args)
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method getline() takes no parameters."
);
"method getline() takes no parameters."
);
return
NULL
;
}
...
...
@@ -1409,7 +2244,7 @@ pg_getline(pgobject * self, PyObject * args)
/* direct access function : end copy */
static
char
pg_endcopy__doc__
[]
=
"endcopy() -- synchronizes client and server"
;
"endcopy() -- synchronizes client and server"
;
static
PyObject
*
pg_endcopy
(
pgobject
*
self
,
PyObject
*
args
)
...
...
@@ -1424,7 +2259,7 @@ pg_endcopy(pgobject * self, PyObject * args)
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method endcopy() takes no parameters."
);
"method endcopy() takes no parameters."
);
return
NULL
;
}
...
...
@@ -1433,14 +2268,13 @@ pg_endcopy(pgobject * self, PyObject * args)
Py_INCREF
(
Py_None
);
return
Py_None
;
}
#endif
/* DIRECT_ACCESS */
#endif
/* DIRECT_ACCESS */
static
PyObject
*
pgquery_print
(
pgqueryobject
*
self
,
FILE
*
fp
,
int
flags
)
pgquery_print
(
pgqueryobject
*
self
,
FILE
*
fp
,
int
flags
)
{
PQprintOpt
op
;
PQprintOpt
op
;
memset
(
&
op
,
0
,
sizeof
(
op
));
op
.
align
=
1
;
...
...
@@ -1451,26 +2285,27 @@ pgquery_print(pgqueryobject * self, FILE *fp, int flags)
return
0
;
}
static
PyObject
*
pgquery_repr
(
pgqueryobject
*
self
)
{
return
PyString_FromString
(
"<pg query result>"
);
}
/* insert table */
static
char
pg_inserttable__doc__
[]
=
"inserttable(string, list) -- insert list in table. The fields in the list
"
"
must be in the same order as in the table."
;
"inserttable(string, list) -- insert list in table. The fields in the
"
"list
must be in the same order as in the table."
;
static
PyObject
*
pg_inserttable
(
pgobject
*
self
,
PyObject
*
args
)
{
PGresult
*
result
;
char
*
table
,
*
buffer
,
*
temp
;
PGresult
*
result
;
char
*
table
,
*
buffer
,
*
temp
;
char
temp_buffer
[
256
];
PyObject
*
list
,
*
sublist
,
*
item
;
PyObject
*
(
*
getitem
)
(
PyObject
*
,
int
);
PyObject
*
(
*
getsubitem
)
(
PyObject
*
,
int
);
int
i
,
j
;
PyObject
*
list
,
*
sublist
,
*
item
;
PyObject
*
(
*
getitem
)
(
PyObject
*
,
int
);
PyObject
*
(
*
getsubitem
)
(
PyObject
*
,
int
);
int
i
,
j
;
if
(
!
self
->
cnx
)
{
...
...
@@ -1482,8 +2317,8 @@ pg_inserttable(pgobject * self, PyObject * args)
if
(
!
PyArg_ParseTuple
(
args
,
"sO:filter"
,
&
table
,
&
list
))
{
PyErr_SetString
(
PyExc_TypeError
,
"tableinsert(table, content), with table (string) "
"and content (list)."
);
"tableinsert(table, content), with table (string) "
"and content (list)."
);
return
NULL
;
}
...
...
@@ -1495,7 +2330,7 @@ pg_inserttable(pgobject * self, PyObject * args)
else
{
PyErr_SetString
(
PyExc_TypeError
,
"second arg must be some kind of array."
);
"second arg must be some kind of array."
);
return
NULL
;
}
...
...
@@ -1505,7 +2340,7 @@ pg_inserttable(pgobject * self, PyObject * args)
if
(
!
PyTuple_Check
(
sublist
)
&&
!
PyList_Check
(
sublist
))
{
PyErr_SetString
(
PyExc_TypeError
,
"second arg must contain some kind of arrays."
);
"second arg must contain some kind of arrays."
);
return
NULL
;
}
}
...
...
@@ -1520,7 +2355,11 @@ pg_inserttable(pgobject * self, PyObject * args)
/* starts query */
sprintf
(
buffer
,
"copy %s from stdin"
,
table
);
if
(
!
(
result
=
PQexec
(
self
->
cnx
,
buffer
)))
Py_BEGIN_ALLOW_THREADS
result
=
PQexec
(
self
->
cnx
,
buffer
);
Py_END_ALLOW_THREADS
if
(
!
result
)
{
free
(
buffer
);
PyErr_SetString
(
PyExc_ValueError
,
PQerrorMessage
(
self
->
cnx
));
...
...
@@ -1544,28 +2383,28 @@ pg_inserttable(pgobject * self, PyObject * args)
{
/* converts item to string */
if
(
PyString_Check
(
item
))
PyArg_ParseTuple
(
item
,
"s"
,
&
temp
);
temp
=
PyString_AS_STRING
(
item
);
else
if
(
PyInt_Check
(
item
))
{
int
k
;
long
k
;
PyArg_ParseTuple
(
item
,
"i"
,
&
k
);
sprintf
(
temp_buffer
,
"%d"
,
k
);
k
=
PyInt_AsLong
(
item
);
sprintf
(
temp_buffer
,
"%
l
d"
,
k
);
temp
=
temp_buffer
;
}
else
if
(
PyLong_Check
(
item
))
{
long
k
;
long
k
;
PyArg_ParseTuple
(
item
,
"l"
,
&
k
);
k
=
PyLong_AsLong
(
item
);
sprintf
(
temp_buffer
,
"%ld"
,
k
);
temp
=
temp_buffer
;
}
else
if
(
PyFloat_Check
(
item
))
{
double
k
;
double
k
;
PyArg_ParseTuple
(
item
,
"d"
,
&
k
);
k
=
PyFloat_AS_DOUBLE
(
item
);
sprintf
(
temp_buffer
,
"%g"
,
k
);
temp
=
temp_buffer
;
}
...
...
@@ -1573,8 +2412,8 @@ pg_inserttable(pgobject * self, PyObject * args)
{
free
(
buffer
);
PyErr_SetString
(
PyExc_ValueError
,
"items must be strings, integers, "
"longs or double (real)."
);
"items must be strings, integers, "
"longs or double (real)."
);
return
NULL
;
}
...
...
@@ -1582,7 +2421,6 @@ pg_inserttable(pgobject * self, PyObject * args)
if
(
strlen
(
buffer
))
strncat
(
buffer
,
"
\t
"
,
MAX_BUFFER_SIZE
-
strlen
(
buffer
));
fprintf
(
stderr
,
"Buffer: '%s', Temp: '%s'
\n
"
,
buffer
,
temp
);
strncat
(
buffer
,
temp
,
MAX_BUFFER_SIZE
-
strlen
(
buffer
));
}
...
...
@@ -1593,7 +2431,7 @@ pg_inserttable(pgobject * self, PyObject * args)
}
/* ends query */
PQputline
(
self
->
cnx
,
".
\n
"
);
PQputline
(
self
->
cnx
,
"
\\
.
\n
"
);
PQendcopy
(
self
->
cnx
);
free
(
buffer
);
...
...
@@ -1602,15 +2440,16 @@ pg_inserttable(pgobject * self, PyObject * args)
return
Py_None
;
}
/* creates large object */
static
char
pg_locreate__doc__
[]
=
"locreate() -- creates a new large object in the database."
;
"locreate() -- creates a new large object in the database."
;
static
PyObject
*
pg_locreate
(
pgobject
*
self
,
PyObject
*
args
)
{
int
mode
;
Oid
lo_oid
;
int
mode
;
Oid
lo_oid
;
/* checks validity */
if
(
!
check_cnx_obj
(
self
))
...
...
@@ -1620,7 +2459,7 @@ pg_locreate(pgobject * self, PyObject * args)
if
(
!
PyArg_ParseTuple
(
args
,
"i"
,
&
mode
))
{
PyErr_SetString
(
PyExc_TypeError
,
"locreate(mode), with mode (integer)."
);
"locreate(mode), with mode (integer)."
);
return
NULL
;
}
...
...
@@ -1637,12 +2476,12 @@ pg_locreate(pgobject * self, PyObject * args)
/* init from already known oid */
static
char
pg_getlo__doc__
[]
=
"getlo(long) -- create a large object instance for the specified oid."
;
"getlo(long) -- create a large object instance for the specified oid."
;
static
PyObject
*
pg_getlo
(
pgobject
*
self
,
PyObject
*
args
)
{
int
lo_oid
;
int
lo_oid
;
/* checks validity */
if
(
!
check_cnx_obj
(
self
))
...
...
@@ -1651,7 +2490,7 @@ pg_getlo(pgobject * self, PyObject * args)
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"i"
,
&
lo_oid
))
{
PyErr_SetString
(
PyExc_TypeError
,
"
loopen
(oid), with oid (integer)."
);
PyErr_SetString
(
PyExc_TypeError
,
"
getlo
(oid), with oid (integer)."
);
return
NULL
;
}
...
...
@@ -1667,13 +2506,13 @@ pg_getlo(pgobject * self, PyObject * args)
/* import unix file */
static
char
pg_loimport__doc__
[]
=
"loimport(string) -- create a new large object from specified file."
;
"loimport(string) -- create a new large object from specified file."
;
static
PyObject
*
pg_loimport
(
pgobject
*
self
,
PyObject
*
args
)
{
char
*
name
;
Oid
lo_oid
;
char
*
name
;
Oid
lo_oid
;
/* checks validity */
if
(
!
check_cnx_obj
(
self
))
...
...
@@ -1700,24 +2539,25 @@ pg_loimport(pgobject * self, PyObject * args)
/* connection object methods */
static
struct
PyMethodDef
pgobj_methods
[]
=
{
{
"query"
,
(
PyCFunction
)
pg_query
,
1
,
pg_query__doc__
},
{
"reset"
,
(
PyCFunction
)
pg_reset
,
1
,
pg_reset__doc__
},
{
"close"
,
(
PyCFunction
)
pg_close
,
1
,
pg_close__doc__
},
{
"fileno"
,
(
PyCFunction
)
pg_fileno
,
1
,
pg_fileno__doc__
},
{
"getnotify"
,
(
PyCFunction
)
pg_getnotify
,
1
,
pg_getnotify__doc__
},
{
"inserttable"
,
(
PyCFunction
)
pg_inserttable
,
1
,
pg_inserttable__doc__
},
{
"source"
,
(
PyCFunction
)
pg_source
,
1
,
pg_source__doc__
},
{
"query"
,
(
PyCFunction
)
pg_query
,
1
,
pg_query__doc__
},
{
"reset"
,
(
PyCFunction
)
pg_reset
,
1
,
pg_reset__doc__
},
{
"close"
,
(
PyCFunction
)
pg_close
,
1
,
pg_close__doc__
},
{
"fileno"
,
(
PyCFunction
)
pg_fileno
,
1
,
pg_fileno__doc__
},
{
"getnotify"
,
(
PyCFunction
)
pg_getnotify
,
1
,
pg_getnotify__doc__
},
{
"inserttable"
,
(
PyCFunction
)
pg_inserttable
,
1
,
pg_inserttable__doc__
},
#ifdef DIRECT_ACCESS
{
"putline"
,
(
PyCFunction
)
pg_putline
,
1
,
pg_putline__doc__
},
{
"getline"
,
(
PyCFunction
)
pg_getline
,
1
,
pg_getline__doc__
},
{
"endcopy"
,
(
PyCFunction
)
pg_endcopy
,
1
,
pg_endcopy__doc__
},
#endif
/* DIRECT_ACCESS */
{
"putline"
,
(
PyCFunction
)
pg_putline
,
1
,
pg_putline__doc__
},
{
"getline"
,
(
PyCFunction
)
pg_getline
,
1
,
pg_getline__doc__
},
{
"endcopy"
,
(
PyCFunction
)
pg_endcopy
,
1
,
pg_endcopy__doc__
},
#endif
/* DIRECT_ACCESS */
#ifdef LARGE_OBJECTS
{
"locreate"
,
(
PyCFunction
)
pg_locreate
,
1
,
pg_locreate__doc__
},
{
"getlo"
,
(
PyCFunction
)
pg_getlo
,
1
,
pg_getlo__doc__
},
{
"loimport"
,
(
PyCFunction
)
pg_loimport
,
1
,
pg_loimport__doc__
},
#endif
/* LARGE_OBJECTS */
{
"locreate"
,
(
PyCFunction
)
pg_locreate
,
1
,
pg_locreate__doc__
},
{
"getlo"
,
(
PyCFunction
)
pg_getlo
,
1
,
pg_getlo__doc__
},
{
"loimport"
,
(
PyCFunction
)
pg_loimport
,
1
,
pg_loimport__doc__
},
#endif
/* LARGE_OBJECTS */
{
NULL
,
NULL
}
/* sentinel */
};
...
...
@@ -1726,11 +2566,9 @@ static struct PyMethodDef pgobj_methods[] = {
static
PyObject
*
pg_getattr
(
pgobject
*
self
,
char
*
name
)
{
/*
* Although we could check individually, there are only a few
* attributes that don't require a live connection and unless someone
* has an urgent need, this will have to do
/* Although we could check individually, there are only a few
* attributes that don't require a live connection and unless
* someone has an urgent need, this will have to do
*/
if
(
!
self
->
cnx
)
{
...
...
@@ -1743,8 +2581,7 @@ pg_getattr(pgobject * self, char *name)
/* postmaster host */
if
(
!
strcmp
(
name
,
"host"
))
{
char
*
r
=
PQhost
(
self
->
cnx
);
char
*
r
=
PQhost
(
self
->
cnx
);
return
r
?
PyString_FromString
(
r
)
:
PyString_FromString
(
"localhost"
);
}
...
...
@@ -1775,23 +2612,23 @@ pg_getattr(pgobject * self, char *name)
/* provided user name */
if
(
!
strcmp
(
name
,
"user"
))
return
PyString_FromString
(
"Deprecated facility"
);
/* return PyString_FromString(fe_getauthname("<unknown user>")); */
/* return PyString_FromString(fe_getauthname("<unknown user>")); */
/* attributes list */
if
(
!
strcmp
(
name
,
"__members__"
))
{
PyObject
*
list
=
PyList_New
(
8
);
PyObject
*
list
=
PyList_New
(
8
);
if
(
list
)
{
PyList_S
etItem
(
list
,
0
,
PyString_FromString
(
"host"
));
PyList_S
etItem
(
list
,
1
,
PyString_FromString
(
"port"
));
PyList_S
etItem
(
list
,
2
,
PyString_FromString
(
"db"
));
PyList_S
etItem
(
list
,
3
,
PyString_FromString
(
"options"
));
PyList_S
etItem
(
list
,
4
,
PyString_FromString
(
"tty"
));
PyList_S
etItem
(
list
,
5
,
PyString_FromString
(
"error"
));
PyList_S
etItem
(
list
,
6
,
PyString_FromString
(
"status"
));
PyList_S
etItem
(
list
,
7
,
PyString_FromString
(
"user"
));
PyList_S
ET_ITEM
(
list
,
0
,
PyString_FromString
(
"host"
));
PyList_S
ET_ITEM
(
list
,
1
,
PyString_FromString
(
"port"
));
PyList_S
ET_ITEM
(
list
,
2
,
PyString_FromString
(
"db"
));
PyList_S
ET_ITEM
(
list
,
3
,
PyString_FromString
(
"options"
));
PyList_S
ET_ITEM
(
list
,
4
,
PyString_FromString
(
"tty"
));
PyList_S
ET_ITEM
(
list
,
5
,
PyString_FromString
(
"error"
));
PyList_S
ET_ITEM
(
list
,
6
,
PyString_FromString
(
"status"
));
PyList_S
ET_ITEM
(
list
,
7
,
PyString_FromString
(
"user"
));
}
return
list
;
...
...
@@ -1823,12 +2660,12 @@ staticforward PyTypeObject PgType = {
/* query object methods */
static
struct
PyMethodDef
pgquery_methods
[]
=
{
{
"getresult"
,
(
PyCFunction
)
pgquery_getresult
,
1
,
pgquery_getresult__doc__
},
{
"dictresult"
,
(
PyCFunction
)
pgquery_dictresult
,
1
,
pgquery_dictresult__doc__
},
{
"fieldname"
,
(
PyCFunction
)
pgquery_fieldname
,
1
,
pgquery_fieldname__doc__
},
{
"fieldnum"
,
(
PyCFunction
)
pgquery_fieldnum
,
1
,
pgquery_fieldnum__doc__
},
{
"listfields"
,
(
PyCFunction
)
pgquery_listfields
,
1
,
pgquery_listfields__doc__
},
{
"ntuples"
,
(
PyCFunction
)
pgquery_ntuples
,
1
,
pgquery_ntuples__doc__
},
{
"getresult"
,
(
PyCFunction
)
pgquery_getresult
,
1
,
pgquery_getresult__doc__
},
{
"dictresult"
,
(
PyCFunction
)
pgquery_dictresult
,
1
,
pgquery_dictresult__doc__
},
{
"fieldname"
,
(
PyCFunction
)
pgquery_fieldname
,
1
,
pgquery_fieldname__doc__
},
{
"fieldnum"
,
(
PyCFunction
)
pgquery_fieldnum
,
1
,
pgquery_fieldnum__doc__
},
{
"listfields"
,
(
PyCFunction
)
pgquery_listfields
,
1
,
pgquery_listfields__doc__
},
{
"ntuples"
,
(
PyCFunction
)
pgquery_ntuples
,
1
,
pgquery_ntuples__doc__
},
{
NULL
,
NULL
}
};
...
...
@@ -1843,21 +2680,21 @@ pgquery_getattr(pgqueryobject * self, char *name)
/* query type definition */
staticforward
PyTypeObject
PgQueryType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/* ob_size */
"pgqueryobject"
,
/* tp_name */
sizeof
(
pgqueryobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
0
,
/* ob_size */
"pgqueryobject"
,
/* tp_name */
sizeof
(
pgqueryobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
(
destructor
)
pgquery_dealloc
,
/* tp_dealloc */
(
printfunc
)
pgquery_print
,
/* tp_print */
(
getattrfunc
)
pgquery_getattr
,
/* tp_getattr */
0
,
/* tp_setattr */
0
,
/* tp_compare */
0
,
/* tp_repr */
0
,
/* tp_as_number */
0
,
/* tp_as_sequence */
0
,
/* tp_as_mapping */
0
,
/* tp_hash */
(
destructor
)
pgquery_dealloc
,
/* tp_dealloc */
(
printfunc
)
pgquery_print
,
/* tp_print */
(
getattrfunc
)
pgquery_getattr
,
/* tp_getattr */
0
,
/* tp_setattr */
0
,
/* tp_compare */
(
reprfunc
)
pgquery_repr
,
/* tp_repr */
0
,
/* tp_as_number */
0
,
/* tp_as_sequence */
0
,
/* tp_as_mapping */
0
,
/* tp_hash */
};
...
...
@@ -1870,16 +2707,16 @@ staticforward PyTypeObject PgQueryType = {
/* gets default host */
static
char
getdefhost__doc__
[]
=
"get_defhost() -- return default database host."
;
"get_defhost() -- return default database host."
;
static
PyObject
*
pggetdefhost
(
PyObject
*
self
,
PyObject
*
args
)
pggetdefhost
(
PyObject
*
self
,
PyObject
*
args
)
{
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method get_defhost() takes no parameter."
);
"method get_defhost() takes no parameter."
);
return
NULL
;
}
...
...
@@ -1889,19 +2726,19 @@ pggetdefhost(PyObject * self, PyObject * args)
/* sets default host */
static
char
setdefhost__doc__
[]
=
"set_defhost(string) -- set default database host. Return previous value."
;
"set_defhost(string) -- set default database host. Return previous value."
;
static
PyObject
*
pgsetdefhost
(
PyObject
*
self
,
PyObject
*
args
)
pgsetdefhost
(
PyObject
*
self
,
PyObject
*
args
)
{
char
*
temp
=
NULL
;
PyObject
*
old
;
char
*
temp
=
NULL
;
PyObject
*
old
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"z"
,
&
temp
))
{
PyErr_SetString
(
PyExc_TypeError
,
"set_defhost(name), with name (string/None)."
);
"set_defhost(name), with name (string/None)."
);
return
NULL
;
}
...
...
@@ -1921,16 +2758,16 @@ pgsetdefhost(PyObject * self, PyObject * args)
/* gets default base */
static
char
getdefbase__doc__
[]
=
"get_defbase() -- return default database name."
;
"get_defbase() -- return default database name."
;
static
PyObject
*
pggetdefbase
(
PyObject
*
self
,
PyObject
*
args
)
pggetdefbase
(
PyObject
*
self
,
PyObject
*
args
)
{
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method get_defbase() takes no parameter."
);
"method get_defbase() takes no parameter."
);
return
NULL
;
}
...
...
@@ -1940,19 +2777,19 @@ pggetdefbase(PyObject * self, PyObject * args)
/* sets default base */
static
char
setdefbase__doc__
[]
=
"set_defbase(string) -- set default database name. Return previous value"
;
"set_defbase(string) -- set default database name. Return previous value"
;
static
PyObject
*
pgsetdefbase
(
PyObject
*
self
,
PyObject
*
args
)
pgsetdefbase
(
PyObject
*
self
,
PyObject
*
args
)
{
char
*
temp
=
NULL
;
PyObject
*
old
;
char
*
temp
=
NULL
;
PyObject
*
old
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"z"
,
&
temp
))
{
PyErr_SetString
(
PyExc_TypeError
,
"set_defbase(name), with name (string/None)."
);
"set_defbase(name), with name (string/None)."
);
return
NULL
;
}
...
...
@@ -1972,16 +2809,16 @@ pgsetdefbase(PyObject * self, PyObject * args)
/* gets default options */
static
char
getdefopt__doc__
[]
=
"get_defopt() -- return default database options."
;
"get_defopt() -- return default database options."
;
static
PyObject
*
pggetdefopt
(
PyObject
*
self
,
PyObject
*
args
)
pggetdefopt
(
PyObject
*
self
,
PyObject
*
args
)
{
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method get_defopt() takes no parameter."
);
"method get_defopt() takes no parameter."
);
return
NULL
;
}
...
...
@@ -1991,19 +2828,19 @@ pggetdefopt(PyObject * self, PyObject * args)
/* sets default opt */
static
char
setdefopt__doc__
[]
=
"set_defopt(string) -- set default database options. Return previous value."
;
"set_defopt(string) -- set default database options. Return previous value."
;
static
PyObject
*
pgsetdefopt
(
PyObject
*
self
,
PyObject
*
args
)
pgsetdefopt
(
PyObject
*
self
,
PyObject
*
args
)
{
char
*
temp
=
NULL
;
PyObject
*
old
;
char
*
temp
=
NULL
;
PyObject
*
old
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"z"
,
&
temp
))
{
PyErr_SetString
(
PyExc_TypeError
,
"set_defopt(name), with name (string/None)."
);
"set_defopt(name), with name (string/None)."
);
return
NULL
;
}
...
...
@@ -2023,16 +2860,16 @@ pgsetdefopt(PyObject * self, PyObject * args)
/* gets default tty */
static
char
getdeftty__doc__
[]
=
"get_deftty() -- return default database debug terminal."
;
"get_deftty() -- return default database debug terminal."
;
static
PyObject
*
pggetdeftty
(
PyObject
*
self
,
PyObject
*
args
)
pggetdeftty
(
PyObject
*
self
,
PyObject
*
args
)
{
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method get_deftty() takes no parameter."
);
"method get_deftty() takes no parameter."
);
return
NULL
;
}
...
...
@@ -2042,20 +2879,20 @@ pggetdeftty(PyObject * self, PyObject * args)
/* sets default tty */
static
char
setdeftty__doc__
[]
=
"set_deftty(string) -- set default database debug terminal. "
"Return previous value."
;
"set_deftty(string) -- set default database debug terminal. "
"Return previous value."
;
static
PyObject
*
pgsetdeftty
(
PyObject
*
self
,
PyObject
*
args
)
pgsetdeftty
(
PyObject
*
self
,
PyObject
*
args
)
{
char
*
temp
=
NULL
;
PyObject
*
old
;
char
*
temp
=
NULL
;
PyObject
*
old
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"z"
,
&
temp
))
{
PyErr_SetString
(
PyExc_TypeError
,
"set_deftty(name), with name (string/None)."
);
"set_deftty(name), with name (string/None)."
);
return
NULL
;
}
...
...
@@ -2075,16 +2912,16 @@ pgsetdeftty(PyObject * self, PyObject * args)
/* gets default username */
static
char
getdefuser__doc__
[]
=
"get_defuser() -- return default database username."
;
"get_defuser() -- return default database username."
;
static
PyObject
*
pggetdefuser
(
PyObject
*
self
,
PyObject
*
args
)
pggetdefuser
(
PyObject
*
self
,
PyObject
*
args
)
{
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method get_defuser() takes no parameter."
);
"method get_defuser() takes no parameter."
);
return
NULL
;
}
...
...
@@ -2095,19 +2932,19 @@ pggetdefuser(PyObject * self, PyObject * args)
/* sets default username */
static
char
setdefuser__doc__
[]
=
"set_defuser() -- set default database username. Return previous value."
;
"set_defuser() -- set default database username. Return previous value."
;
static
PyObject
*
pgsetdefuser
(
PyObject
*
self
,
PyObject
*
args
)
pgsetdefuser
(
PyObject
*
self
,
PyObject
*
args
)
{
char
*
temp
=
NULL
;
PyObject
*
old
;
char
*
temp
=
NULL
;
PyObject
*
old
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"z"
,
&
temp
))
{
PyErr_SetString
(
PyExc_TypeError
,
"set_defuser(name), with name (string/None)."
);
"set_defuser(name), with name (string/None)."
);
return
NULL
;
}
...
...
@@ -2127,19 +2964,20 @@ pgsetdefuser(PyObject * self, PyObject * args)
/* sets default password */
static
char
setdefpasswd__doc__
[]
=
"set_defpasswd() -- set default database password."
;
"set_defpasswd() -- set default database password."
;
static
PyObject
*
pgsetdefpasswd
(
PyObject
*
self
,
PyObject
*
args
)
pgsetdefpasswd
(
PyObject
*
self
,
PyObject
*
args
)
{
char
*
temp
=
NULL
;
PyObject
*
old
;
char
*
temp
=
NULL
;
PyObject
*
old
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"z"
,
&
temp
))
{
PyErr_SetString
(
PyExc_TypeError
,
"set_defpasswd(password), with password (string/None)."
);
"set_defpasswd(password), with password (string/
None)."
);
return
NULL
;
}
...
...
@@ -2160,16 +2998,16 @@ pgsetdefpasswd(PyObject * self, PyObject * args)
/* gets default port */
static
char
getdefport__doc__
[]
=
"get_defport() -- return default database port."
;
"get_defport() -- return default database port."
;
static
PyObject
*
pggetdefport
(
PyObject
*
self
,
PyObject
*
args
)
pggetdefport
(
PyObject
*
self
,
PyObject
*
args
)
{
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method get_defport() takes no parameter."
);
"method get_defport() takes no parameter."
);
return
NULL
;
}
...
...
@@ -2179,19 +3017,19 @@ pggetdefport(PyObject * self, PyObject * args)
/* sets default port */
static
char
setdefport__doc__
[]
=
"set_defport(integer) -- set default database port. Return previous value."
;
"set_defport(integer) -- set default database port. Return previous value."
;
static
PyObject
*
pgsetdefport
(
PyObject
*
self
,
PyObject
*
args
)
pgsetdefport
(
PyObject
*
self
,
PyObject
*
args
)
{
long
int
port
=
-
2
;
PyObject
*
old
;
PyObject
*
old
;
/* gets arguments */
if
((
!
PyArg_ParseTuple
(
args
,
"l"
,
&
port
))
||
(
port
<
-
1
))
{
PyErr_SetString
(
PyExc_TypeError
,
"set_defport(port), with port "
"(positive integer/-1)."
);
"(positive integer/-1)."
);
return
NULL
;
}
...
...
@@ -2209,41 +3047,39 @@ pgsetdefport(PyObject * self, PyObject * args)
return
old
;
}
#endif
/* DEFAULT_VARS */
#endif
/* DEFAULT_VARS */
/* List of functions defined in the module */
static
struct
PyMethodDef
pg_methods
[]
=
{
{
"connect"
,
(
PyCFunction
)
pgconnect
,
3
,
connect__doc__
},
{
"connect"
,
(
PyCFunction
)
pgconnect
,
3
,
connect__doc__
},
#ifdef DEFAULT_VARS
{
"get_defhost"
,
pggetdefhost
,
1
,
getdefhost__doc__
},
{
"set_defhost"
,
pgsetdefhost
,
1
,
setdefhost__doc__
},
{
"get_defbase"
,
pggetdefbase
,
1
,
getdefbase__doc__
},
{
"set_defbase"
,
pgsetdefbase
,
1
,
setdefbase__doc__
},
{
"get_defopt"
,
pggetdefopt
,
1
,
getdefopt__doc__
},
{
"set_defopt"
,
pgsetdefopt
,
1
,
setdefopt__doc__
},
{
"get_deftty"
,
pggetdeftty
,
1
,
getdeftty__doc__
},
{
"set_deftty"
,
pgsetdeftty
,
1
,
setdeftty__doc__
},
{
"get_defport"
,
pggetdefport
,
1
,
getdefport__doc__
},
{
"set_defport"
,
pgsetdefport
,
1
,
setdefport__doc__
},
{
"get_defuser"
,
pggetdefuser
,
1
,
getdefuser__doc__
},
{
"set_defuser"
,
pgsetdefuser
,
1
,
setdefuser__doc__
},
{
"set_defpasswd"
,
pgsetdefpasswd
,
1
,
setdefpasswd__doc__
},
#endif
/* DEFAULT_VARS */
{
"get_defhost"
,
pggetdefhost
,
1
,
getdefhost__doc__
},
{
"set_defhost"
,
pgsetdefhost
,
1
,
setdefhost__doc__
},
{
"get_defbase"
,
pggetdefbase
,
1
,
getdefbase__doc__
},
{
"set_defbase"
,
pgsetdefbase
,
1
,
setdefbase__doc__
},
{
"get_defopt"
,
pggetdefopt
,
1
,
getdefopt__doc__
},
{
"set_defopt"
,
pgsetdefopt
,
1
,
setdefopt__doc__
},
{
"get_deftty"
,
pggetdeftty
,
1
,
getdeftty__doc__
},
{
"set_deftty"
,
pgsetdeftty
,
1
,
setdeftty__doc__
},
{
"get_defport"
,
pggetdefport
,
1
,
getdefport__doc__
},
{
"set_defport"
,
pgsetdefport
,
1
,
setdefport__doc__
},
{
"get_defuser"
,
pggetdefuser
,
1
,
getdefuser__doc__
},
{
"set_defuser"
,
pgsetdefuser
,
1
,
setdefuser__doc__
},
{
"set_defpasswd"
,
pgsetdefpasswd
,
1
,
setdefpasswd__doc__
},
#endif
/* DEFAULT_VARS */
{
NULL
,
NULL
}
/* sentinel */
};
static
char
pg__doc__
[]
=
"Python interface to PostgreSQL DB"
;
/* Initialization function for the module */
void
init_pg
(
void
);
/* Python doesn't prototype this */
void
init_pg
(
void
);
/* Python doesn't prototype this */
void
init_pg
(
void
)
{
PyObject
*
mod
,
*
dict
,
*
v
;
PyObject
*
mod
,
*
dict
,
*
v
;
/* Initialize here because some WIN platforms get confused otherwise */
PglargeType
.
ob_type
=
PgType
.
ob_type
=
PgQueryType
.
ob_type
=
&
PyType_Type
;
...
...
@@ -2253,7 +3089,7 @@ init_pg(void)
dict
=
PyModule_GetDict
(
mod
);
/* Add some symbolic constants to the module */
PGError
=
PyString_FromString
(
"pg.error"
);
PGError
=
PyString_FromString
(
"
_
pg.error"
);
PyDict_SetItemString
(
dict
,
"error"
,
PGError
);
/* Make the version available */
...
...
@@ -2262,6 +3098,12 @@ init_pg(void)
PyDict_SetItemString
(
dict
,
"__version__"
,
v
);
Py_DECREF
(
v
);
/* results type for queries */
PyDict_SetItemString
(
dict
,
"RESULT_EMPTY"
,
PyInt_FromLong
(
RESULT_EMPTY
));
PyDict_SetItemString
(
dict
,
"RESULT_DML"
,
PyInt_FromLong
(
RESULT_DML
));
PyDict_SetItemString
(
dict
,
"RESULT_DDL"
,
PyInt_FromLong
(
RESULT_DDL
));
PyDict_SetItemString
(
dict
,
"RESULT_DQL"
,
PyInt_FromLong
(
RESULT_DQL
));
#ifdef LARGE_OBJECTS
/* create mode for large objects */
PyDict_SetItemString
(
dict
,
"INV_READ"
,
PyInt_FromLong
(
INV_READ
));
...
...
@@ -2271,25 +3113,18 @@ init_pg(void)
PyDict_SetItemString
(
dict
,
"SEEK_SET"
,
PyInt_FromLong
(
SEEK_SET
));
PyDict_SetItemString
(
dict
,
"SEEK_CUR"
,
PyInt_FromLong
(
SEEK_CUR
));
PyDict_SetItemString
(
dict
,
"SEEK_END"
,
PyInt_FromLong
(
SEEK_END
));
#endif
/* LARGE_OBJECTS */
#endif
/* LARGE_OBJECTS */
#ifdef DEFAULT_VARS
/* prepares default values */
Py_INCREF
(
Py_None
);
pg_default_host
=
Py_None
;
Py_INCREF
(
Py_None
);
pg_default_base
=
Py_None
;
Py_INCREF
(
Py_None
);
pg_default_opt
=
Py_None
;
Py_INCREF
(
Py_None
);
pg_default_port
=
Py_None
;
Py_INCREF
(
Py_None
);
pg_default_tty
=
Py_None
;
Py_INCREF
(
Py_None
);
pg_default_user
=
Py_None
;
Py_INCREF
(
Py_None
);
pg_default_passwd
=
Py_None
;
#endif
/* DEFAULT_VARS */
Py_INCREF
(
Py_None
);
pg_default_host
=
Py_None
;
Py_INCREF
(
Py_None
);
pg_default_base
=
Py_None
;
Py_INCREF
(
Py_None
);
pg_default_opt
=
Py_None
;
Py_INCREF
(
Py_None
);
pg_default_port
=
Py_None
;
Py_INCREF
(
Py_None
);
pg_default_tty
=
Py_None
;
Py_INCREF
(
Py_None
);
pg_default_user
=
Py_None
;
Py_INCREF
(
Py_None
);
pg_default_passwd
=
Py_None
;
#endif
/* DEFAULT_VARS */
/* Check for errors */
if
(
PyErr_Occurred
())
...
...
src/interfaces/python/pgsqldb.py
deleted
100644 → 0
View file @
0bd84442
# pgsqldb.py
# Written by D'Arcy J.M. Cain
# This library implements the DB-SIG API
# It includes the pg module and builds on it
from
_pg
import
*
import
string
class
_cursor
:
"""For cursor object"""
def
__init__
(
self
,
conn
):
self
.
conn
=
conn
self
.
cursor
=
None
self
.
arraysize
=
1
self
.
description
=
None
self
.
name
=
string
.
split
(
`self`
)[
3
][:
-
1
]
def
close
(
self
):
if
self
.
conn
==
None
:
raise
self
.
conn
.
error
,
"Cursor has been closed"
if
self
.
cursor
==
None
:
raise
self
.
conn
.
error
,
"No cursor created"
self
.
conn
.
query
(
'CLOSE
%
s'
%
self
.
name
)
self
.
conn
=
None
def
__del__
(
self
):
if
self
.
cursor
!=
None
and
self
.
conn
!=
None
:
self
.
conn
.
query
(
'CLOSE
%
s'
%
self
.
name
)
class
pgsqldb
:
"""This class wraps the pg connection type in a DB-SIG API interface"""
def
__init__
(
self
,
*
args
,
**
kw
):
self
.
db
=
apply
(
connect
,
args
,
kw
)
# Create convience methods, in a way that is still overridable.
for
e
in
(
'query'
,
'reset'
,
'close'
,
'getnotify'
,
'inserttable'
,
'putline'
,
'getline'
,
'endcopy'
,
'host'
,
'port'
,
'db'
,
'options'
,
'tty'
,
'error'
,
'status'
,
'user'
,
'locreate'
,
'getlo'
,
'loimport'
):
if
not
hasattr
(
self
,
e
)
and
hasattr
(
self
.
db
,
e
):
exec
'self.
%
s = self.db.
%
s'
%
(
e
,
e
)
src/interfaces/python/setup.py
0 → 100755
View file @
f36e7ff0
#!/usr/bin/env python
include_dirs
=
[
'/usr/include/pgsql'
]
library_dirs
=
[
'usr/lib/pgsql'
]
optional_libs
=
[
'pq'
]
# Setup script for the PyGreSQL version 3
# created 2000/04 Mark Alexander <mwa@gate.net>
# tweaked 2000/05 Jeremy Hylton <jeremy@cnri.reston.va.us>
# requires distutils; standard in Python 1.6, otherwise download from
# http://www.python.org/sigs/distutils-sig/download.html
# You may have to change the first 3 variables (include_dirs,
# library_dirs, optional_libs) to match your postgres distribution.
# Now, you can:
# python setup.py build # to build the module
# python setup.py install # to install it
# See http://www.python.org/sigs/distutils-sig/doc/ for more information
# on using distutils to install Python programs.
from
distutils.core
import
setup
setup
(
name
=
"PyGreSQL"
,
version
=
"3.0"
,
description
=
"Python PostgreSQL Interfaces"
,
author
=
"D'Arcy J. M. Cain"
,
author_email
=
"darcy@druid.net"
,
url
=
"http://www.druid.net/pygresql/"
,
licence
=
"Python"
,
py_modules
=
[
'pg'
,
'pgdb'
],
ext_modules
=
[
(
'_pgmodule'
,
{
'sources'
:
[
'pgmodule.c'
],
'include_dirs'
:
include_dirs
,
'library_dirs'
:
library_dirs
,
'libraries'
:
optional_libs
}
)]
)
src/interfaces/python/tutorial/advanced.py
deleted
100755 → 0
View file @
0bd84442
#! /usr/local/bin/python
# advanced.py - demo of advanced features of PostGres. Some may not be ANSI.
# inspired from the Postgres tutorial
# adapted to Python 1995 by Pascal Andre
print
"__________________________________________________________________"
print
"MODULE ADVANCED.PY : ADVANCED POSTGRES SQL COMMANDS TUTORIAL"
print
print
"This module is designed for being imported from python prompt"
print
print
"In order to run the samples included here, first create a connection"
print
"using : cnx = advanced.DB(...)"
print
"then start the demo with: advanced.demo(cnx)"
print
"__________________________________________________________________"
from
pgtools
import
*
from
pg
import
DB
# inheritance features
def
inherit_demo
(
pgcnx
):
print
"-----------------------------"
print
"-- Inheritance:"
print
"-- a table can inherit from zero or more tables. A query"
print
"-- can reference either all rows of a table or all rows "
print
"-- of a table plus all of its descendants."
print
"-----------------------------"
print
print
"-- For example, the capitals table inherits from cities table."
print
"-- (It inherits all data fields from cities.)"
print
print
"CREATE TABLE cities ("
print
" name text,"
print
" population float8,"
print
" altitude int"
print
")"
print
print
"CREATE TABLE capitals ("
print
" state varchar(2)"
print
") INHERITS (cities)"
pgcnx
.
query
(
"CREATE TABLE cities ("
\
"name text,"
\
"population float8,"
\
"altitude int)"
)
pgcnx
.
query
(
"CREATE TABLE capitals ("
\
"state varchar(2)) INHERITS (cities)"
)
wait_key
()
print
print
"-- now, let's populate the tables"
print
print
"INSERT INTO cities VALUES ('San Francisco', 7.24E+5, 63)"
print
"INSERT INTO cities VALUES ('Las Vegas', 2.583E+5, 2174)"
print
"INSERT INTO cities VALUES ('Mariposa', 1200, 1953)"
print
print
"INSERT INTO capitals VALUES ('Sacramento', 3.694E+5, 30, 'CA')"
print
"INSERT INTO capitals VALUES ('Madison', 1.913E+5, 845, 'WI')"
print
pgcnx
.
query
(
"INSERT INTO cities VALUES ('San Francisco', 7.24E+5, 63)"
)
pgcnx
.
query
(
"INSERT INTO cities VALUES ('Las Vegas', 2.583E+5, 2174)"
)
pgcnx
.
query
(
"INSERT INTO cities VALUES ('Mariposa', 1200, 1953)"
)
pgcnx
.
query
(
"INSERT INTO capitals"
\
" VALUES ('Sacramento', 3.694E+5, 30, 'CA')"
)
pgcnx
.
query
(
"INSERT INTO capitals"
\
" VALUES ('Madison', 1.913E+5, 845, 'WI')"
)
print
print
"SELECT * FROM cities"
print
pgcnx
.
query
(
"SELECT * FROM cities"
)
print
"SELECT * FROM capitals"
print
pgcnx
.
query
(
"SELECT * FROM capitals"
)
print
print
"-- like before, a regular query references rows of the base"
print
"-- table only"
print
print
"SELECT name, altitude"
print
"FROM cities"
print
"WHERE altitude > 500;"
print
pgcnx
.
query
(
"SELECT name, altitude "
\
"FROM cities "
\
"WHERE altitude > 500"
)
print
print
"-- on the other hand, you can find all cities, including "
print
"-- capitals, that are located at an altitude of 500 'ft "
print
"-- or higher by:"
print
print
"SELECT c.name, c.altitude"
print
"FROM cities* c"
print
"WHERE c.altitude > 500"
print
pgcnx
.
query
(
"SELECT c.name, c.altitude "
\
"FROM cities* c "
\
"WHERE c.altitude > 500"
)
# arrays attributes
def
array_demo
(
pgcnx
):
print
"----------------------"
print
"-- Arrays:"
print
"-- attributes can be arrays of base types or user-defined "
print
"-- types"
print
"----------------------"
print
print
"CREATE TABLE sal_emp ("
print
" name text,"
print
" pay_by_quarter int4[],"
print
" schedule text[][]"
print
")"
pgcnx
.
query
(
"CREATE TABLE sal_emp ("
\
"name text,"
\
"pay_by_quarter int4[],"
\
"schedule text[][])"
)
wait_key
()
print
print
"-- insert instances with array attributes. "
print
" Note the use of braces"
print
print
"INSERT INTO sal_emp VALUES ("
print
" 'Bill',"
print
" '{10000,10000,10000,10000}',"
print
" '{{
\"
meeting
\"
,
\"
lunch
\"
}, {}}')"
print
print
"INSERT INTO sal_emp VALUES ("
print
" 'Carol',"
print
" '{20000,25000,25000,25000}',"
print
" '{{
\"
talk
\"
,
\"
consult
\"
}, {
\"
meeting
\"
}}')"
print
pgcnx
.
query
(
"INSERT INTO sal_emp VALUES ("
\
"'Bill', '{10000,10000,10000,10000}',"
\
"'{{
\"
meeting
\"
,
\"
lunch
\"
}, {}}')"
)
pgcnx
.
query
(
"INSERT INTO sal_emp VALUES ("
\
"'Carol', '{20000,25000,25000,25000}',"
\
"'{{
\"
talk
\"
,
\"
consult
\"
}, {
\"
meeting
\"
}}')"
)
wait_key
()
print
print
"----------------------"
print
"-- queries on array attributes"
print
"----------------------"
print
print
"SELECT name FROM sal_emp WHERE"
print
" sal_emp.pay_by_quarter[1] <> sal_emp.pay_by_quarter[2]"
print
print
pgcnx
.
query
(
"SELECT name FROM sal_emp WHERE "
\
"sal_emp.pay_by_quarter[1] <> sal_emp.pay_by_quarter[2]"
)
print
print
"-- retrieve third quarter pay of all employees"
print
print
"SELECT sal_emp.pay_by_quarter[3] FROM sal_emp"
print
print
pgcnx
.
query
(
"SELECT sal_emp.pay_by_quarter[3] FROM sal_emp"
)
print
print
"-- select subarrays"
print
print
"SELECT sal_emp.schedule[1:2][1:1] FROM sal_emp WHERE "
print
" sal_emp.name = 'Bill'"
print
pgcnx
.
query
(
"SELECT sal_emp.schedule[1:2][1:1] FROM sal_emp WHERE "
\
"sal_emp.name = 'Bill'"
)
# base cleanup
def
demo_cleanup
(
pgcnx
):
print
"-- clean up (you must remove the children first)"
print
"DROP TABLE sal_emp"
print
"DROP TABLE capitals"
print
"DROP TABLE cities;"
pgcnx
.
query
(
"DROP TABLE sal_emp"
)
pgcnx
.
query
(
"DROP TABLE capitals"
)
pgcnx
.
query
(
"DROP TABLE cities"
)
# main demo function
def
demo
(
pgcnx
):
inherit_demo
(
pgcnx
)
array_demo
(
pgcnx
)
demo_cleanup
(
pgcnx
)
src/interfaces/python/tutorial/basics.py
deleted
100755 → 0
View file @
0bd84442
#! /usr/local/bin/python
# basics.py - basic SQL commands tutorial
# inspired from the Postgres95 tutorial
# adapted to Python 1995 by Pascal ANDRE
print
"__________________________________________________________________"
print
"MODULE BASICS.PY : BASIC SQL COMMANDS TUTORIAL"
print
print
"This module is designed for being imported from python prompt"
print
print
"In order to run the samples included here, first create a connection"
print
"using : cnx = basics.DB(...)"
print
"then start the demo with: basics.demo(cnx)"
print
"__________________________________________________________________"
from
pg
import
DB
from
pgtools
import
*
# table creation commands
def
create_table
(
pgcnx
):
print
"-----------------------------"
print
"-- Creating a table:"
print
"-- a CREATE TABLE is used to create base tables. POSTGRES"
print
"-- SQL has its own set of built-in types. (Note that"
print
"-- keywords are case-insensitive but identifiers are "
print
"-- case-sensitive.)"
print
"-----------------------------"
print
print
"Sending query :"
print
"CREATE TABLE weather ("
print
" city varchar(80),"
print
" temp_lo int,"
print
" temp_hi int,"
print
" prcp float8,"
print
" date date"
print
")"
pgcnx
.
query
(
"CREATE TABLE weather (city varchar(80), temp_lo int,"
\
"temp_hi int, prcp float8, date date)"
)
print
print
"Sending query :"
print
"CREATE TABLE cities ("
print
" name varchar(80),"
print
" location point"
print
")"
pgcnx
.
query
(
"CREATE TABLE cities ("
\
"name varchar(80),"
\
"location point)"
)
# data insertion commands
def
insert_data
(
pgcnx
):
print
"-----------------------------"
print
"-- Inserting data:"
print
"-- an INSERT statement is used to insert a new row into"
print
"-- a table. There are several ways you can specify what"
print
"-- columns the data should go to."
print
"-----------------------------"
print
print
"-- 1. the simplest case is when the list of value correspond to"
print
"-- the order of the columns specified in CREATE TABLE."
print
print
"Sending query :"
print
"INSERT INTO weather "
print
" VALUES ('San Francisco', 46, 50, 0.25, '11/27/1994')"
pgcnx
.
query
(
"INSERT INTO weather "
\
"VALUES ('San Francisco', 46, 50, 0.25, '11/27/1994')"
)
print
print
"Sending query :"
print
"INSERT INTO cities "
print
" VALUES ('San Francisco', '(-194.0, 53.0)')"
pgcnx
.
query
(
"INSERT INTO cities "
\
"VALUES ('San Francisco', '(-194.0, 53.0)')"
)
print
wait_key
()
print
"-- 2. you can also specify what column the values correspond "
print
" to. (The columns can be specified in any order. You may "
print
" also omit any number of columns. eg. unknown precipitation"
print
" below)"
print
"Sending query :"
print
"INSERT INTO weather (city, temp_lo, temp_hi, prcp, date)"
print
" VALUES ('San Francisco', 43, 57, 0.0, '11/29/1994')"
pgcnx
.
query
(
"INSERT INTO weather (date, city, temp_hi, temp_lo)"
\
"VALUES ('11/29/1994', 'Hayward', 54, 37)"
)
# direct selection commands
def
select_data1
(
pgcnx
):
print
"-----------------------------"
print
"-- Retrieving data:"
print
"-- a SELECT statement is used for retrieving data. The "
print
"-- basic syntax is:"
print
"-- SELECT columns FROM tables WHERE predicates"
print
"-----------------------------"
print
print
"-- a simple one would be the query:"
print
"SELECT * FROM weather"
print
print
"The result is :"
q
=
pgcnx
.
query
(
"SELECT * FROM weather"
)
print
q
print
print
"-- you may also specify expressions in the target list (the "
print
"-- 'AS column' specifies the column name of the result. It is "
print
"-- optional.)"
print
"The query :"
print
" SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date "
print
" FROM weather"
print
"Gives :"
print
pgcnx
.
query
(
"SELECT city, (temp_hi+temp_lo)/2 "
\
"AS temp_avg, date FROM weather"
)
print
print
"-- if you want to retrieve rows that satisfy certain condition"
print
"-- (ie. a restriction), specify the condition in WHERE. The "
print
"-- following retrieves the weather of San Francisco on rainy "
print
"-- days."
print
"SELECT *"
print
"FROM weather"
print
"WHERE city = 'San Francisco' "
print
" and prcp > 0.0"
print
pgcnx
.
query
(
"SELECT * FROM weather WHERE city = 'San Francisco'"
\
" AND prcp > 0.0"
)
print
print
"-- here is a more complicated one. Duplicates are removed when "
print
"-- DISTINCT is specified. ORDER BY specifies the column to sort"
print
"-- on. (Just to make sure the following won't confuse you, "
print
"-- DISTINCT and ORDER BY can be used separately.)"
print
"SELECT DISTINCT city"
print
"FROM weather"
print
"ORDER BY city;"
print
pgcnx
.
query
(
"SELECT DISTINCT city FROM weather ORDER BY city"
)
# selection to a temporary table
def
select_data2
(
pgcnx
):
print
"-----------------------------"
print
"-- Retrieving data into other classes:"
print
"-- a SELECT ... INTO statement can be used to retrieve "
print
"-- data into another class."
print
"-----------------------------"
print
print
"The query :"
print
"SELECT * INTO TABLE temp "
print
"FROM weather"
print
"WHERE city = 'San Francisco' "
print
" and prcp > 0.0"
pgcnx
.
query
(
"SELECT * INTO TABLE temp FROM weather "
\
"WHERE city = 'San Francisco' and prcp > 0.0"
)
print
"Fills the table temp, that can be listed with :"
print
"SELECT * from temp"
print
pgcnx
.
query
(
"SELECT * from temp"
)
# aggregate creation commands
def
create_aggregate
(
pgcnx
):
print
"-----------------------------"
print
"-- Aggregates"
print
"-----------------------------"
print
print
"Let's consider the query :"
print
"SELECT max(temp_lo)"
print
"FROM weather;"
print
pgcnx
.
query
(
"SELECT max(temp_lo) FROM weather"
)
print
print
"-- Aggregate with GROUP BY"
print
"SELECT city, max(temp_lo)"
print
"FROM weather "
print
"GROUP BY city;"
print
pgcnx
.
query
(
"SELECT city, max(temp_lo)"
\
"FROM weather GROUP BY city"
)
# table join commands
def
join_table
(
pgcnx
):
print
"-----------------------------"
print
"-- Joining tables:"
print
"-- queries can access multiple tables at once or access"
print
"-- the same table in such a way that multiple instances"
print
"-- of the table are being processed at the same time."
print
"-----------------------------"
print
print
"-- suppose we want to find all the records that are in the "
print
"-- temperature range of other records. W1 and W2 are aliases "
print
"--for weather."
print
print
"SELECT W1.city, W1.temp_lo, W1.temp_hi, "
print
" W2.city, W2.temp_lo, W2.temp_hi"
print
"FROM weather W1, weather W2"
print
"WHERE W1.temp_lo < W2.temp_lo "
print
" and W1.temp_hi > W2.temp_hi"
print
print
pgcnx
.
query
(
"SELECT W1.city, W1.temp_lo, W1.temp_hi, "
\
"W2.city, W2.temp_lo, W2.temp_hi FROM weather W1, weather W2 "
\
"WHERE W1.temp_lo < W2.temp_lo and W1.temp_hi > W2.temp_hi"
)
print
print
"-- let's join two tables. The following joins the weather table"
print
"-- and the cities table."
print
print
"SELECT city, location, prcp, date"
print
"FROM weather, cities"
print
"WHERE name = city"
print
print
pgcnx
.
query
(
"SELECT city, location, prcp, date FROM weather, cities"
\
" WHERE name = city"
)
print
print
"-- since the column names are all different, we don't have to "
print
"-- specify the table name. If you want to be clear, you can do "
print
"-- the following. They give identical results, of course."
print
print
"SELECT w.city, c.location, w.prcp, w.date"
print
"FROM weather w, cities c"
print
"WHERE c.name = w.city;"
print
print
pgcnx
.
query
(
"SELECT w.city, c.location, w.prcp, w.date "
\
"FROM weather w, cities c WHERE c.name = w.city"
)
# data updating commands
def
update_data
(
pgcnx
):
print
"-----------------------------"
print
"-- Updating data:"
print
"-- an UPDATE statement is used for updating data. "
print
"-----------------------------"
print
print
"-- suppose you discover the temperature readings are all off by"
print
"-- 2 degrees as of Nov 28, you may update the data as follow:"
print
print
"UPDATE weather"
print
" SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2"
print
" WHERE date > '11/28/1994'"
print
pgcnx
.
query
(
"UPDATE weather "
\
"SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2"
\
"WHERE date > '11/28/1994'"
)
print
print
"SELECT * from weather"
print
pgcnx
.
query
(
"SELECT * from weather"
)
# data deletion commands
def
delete_data
(
pgcnx
):
print
"-----------------------------"
print
"-- Deleting data:"
print
"-- a DELETE statement is used for deleting rows from a "
print
"-- table."
print
"-----------------------------"
print
print
"-- suppose you are no longer interested in the weather of "
print
"-- Hayward, you can do the following to delete those rows from"
print
"-- the table"
print
print
"DELETE FROM weather WHERE city = 'Hayward'"
pgcnx
.
query
(
"DELETE FROM weather WHERE city = 'Hayward'"
)
print
print
"SELECT * from weather"
print
print
pgcnx
.
query
(
"SELECT * from weather"
)
print
print
"-- you can also delete all the rows in a table by doing the "
print
"-- following. (This is different from DROP TABLE which removes "
print
"-- the table in addition to the removing the rows.)"
print
print
"DELETE FROM weather"
pgcnx
.
query
(
"DELETE FROM weather"
)
print
print
"SELECT * from weather"
print
pgcnx
.
query
(
"SELECT * from weather"
)
# table removal commands
def
remove_table
(
pgcnx
):
print
"-----------------------------"
print
"-- Removing the tables:"
print
"-- DROP TABLE is used to remove tables. After you have"
print
"-- done this, you can no longer use those tables."
print
"-----------------------------"
print
print
"DROP TABLE weather, cities, temp"
pgcnx
.
query
(
"DROP TABLE weather, cities, temp"
)
# main demo function
def
demo
(
pgcnx
):
create_table
(
pgcnx
)
wait_key
()
insert_data
(
pgcnx
)
wait_key
()
select_data1
(
pgcnx
)
select_data2
(
pgcnx
)
create_aggregate
(
pgcnx
)
join_table
(
pgcnx
)
update_data
(
pgcnx
)
delete_data
(
pgcnx
)
remove_table
(
pgcnx
)
src/interfaces/python/tutorial/func.py
deleted
100755 → 0
View file @
0bd84442
# func.py - demonstrate the use of SQL functions
# inspired from the PostgreSQL tutorial
# adapted to Python 1995 by Pascal ANDRE
print
"__________________________________________________________________"
print
"MODULE FUNC.PY : SQL FUNCTION DEFINITION TUTORIAL"
print
print
"This module is designed for being imported from python prompt"
print
print
"In order to run the samples included here, first create a connection"
print
"using : cnx = func.DB(...)"
print
"then start the demo with: func.demo(cnx)"
print
"__________________________________________________________________"
from
pgtools
import
*
from
pg
import
DB
# basic functions declaration
def
base_func
(
pgcnx
):
print
"-----------------------------"
print
"-- Creating SQL Functions on Base Types"
print
"-- a CREATE FUNCTION statement lets you create a new "
print
"-- function that can be used in expressions (in SELECT, "
print
"-- INSERT, etc.). We will start with functions that "
print
"-- return values of base types."
print
"-----------------------------"
print
print
"--"
print
"-- let's create a simple SQL function that takes no arguments"
print
"-- and returns 1"
print
print
"CREATE FUNCTION one() RETURNS int4"
print
" AS 'SELECT 1 as ONE' LANGUAGE 'sql'"
pgcnx
.
query
(
"CREATE FUNCTION one() RETURNS int4 "
\
"AS 'SELECT 1 as ONE' LANGUAGE 'sql'"
)
wait_key
()
print
print
"--"
print
"-- functions can be used in any expressions (eg. in the target"
print
"-- list or qualifications)"
print
print
"SELECT one() AS answer"
print
pgcnx
.
query
(
"SELECT one() AS answer"
)
print
print
"--"
print
"-- here's how you create a function that takes arguments. The"
print
"-- following function returns the sum of its two arguments:"
print
print
"CREATE FUNCTION add_em(int4, int4) RETURNS int4"
print
" AS 'SELECT $1 + $2' LANGUAGE 'sql'"
pgcnx
.
query
(
"CREATE FUNCTION add_em(int4, int4) RETURNS int4 "
\
"AS 'SELECT $1 + $2' LANGUAGE 'sql'"
)
print
print
"SELECT add_em(1, 2) AS answer"
print
pgcnx
.
query
(
"SELECT add_em(1, 2) AS answer"
)
# functions on composite types
def
comp_func
(
pgcnx
):
print
"-----------------------------"
print
"-- Creating SQL Functions on Composite Types"
print
"-- it is also possible to create functions that return"
print
"-- values of composite types."
print
"-----------------------------"
print
print
"-- before we create more sophisticated functions, let's "
print
"-- populate an EMP table"
print
print
"CREATE TABLE EMP ("
print
" name text,"
print
" salary int4,"
print
" age int4,"
print
" dept varchar(16)"
print
")"
pgcnx
.
query
(
"CREATE TABLE EMP ("
\
"name text,"
\
"salary int4,"
\
"age int4,"
\
"dept varchar(16))"
)
print
print
"INSERT INTO EMP VALUES ('Sam', 1200, 16, 'toy')"
print
"INSERT INTO EMP VALUES ('Claire', 5000, 32, 'shoe')"
print
"INSERT INTO EMP VALUES ('Andy', -1000, 2, 'candy')"
print
"INSERT INTO EMP VALUES ('Bill', 4200, 36, 'shoe')"
print
"INSERT INTO EMP VALUES ('Ginger', 4800, 30, 'candy')"
pgcnx
.
query
(
"INSERT INTO EMP VALUES ('Sam', 1200, 16, 'toy')"
)
pgcnx
.
query
(
"INSERT INTO EMP VALUES ('Claire', 5000, 32, 'shoe')"
)
pgcnx
.
query
(
"INSERT INTO EMP VALUES ('Andy', -1000, 2, 'candy')"
)
pgcnx
.
query
(
"INSERT INTO EMP VALUES ('Bill', 4200, 36, 'shoe')"
)
pgcnx
.
query
(
"INSERT INTO EMP VALUES ('Ginger', 4800, 30, 'candy')"
)
wait_key
()
print
print
"-- the argument of a function can also be a tuple. For "
print
"-- instance, double_salary takes a tuple of the EMP table"
print
print
"CREATE FUNCTION double_salary(EMP) RETURNS int4"
print
" AS 'SELECT $1.salary * 2 AS salary' LANGUAGE 'sql'"
pgcnx
.
query
(
"CREATE FUNCTION double_salary(EMP) RETURNS int4 "
\
"AS 'SELECT $1.salary * 2 AS salary' LANGUAGE 'sql'"
)
print
print
"SELECT name, double_salary(EMP) AS dream"
print
"FROM EMP"
print
"WHERE EMP.dept = 'toy'"
print
pgcnx
.
query
(
"SELECT name, double_salary(EMP) AS dream "
\
"FROM EMP WHERE EMP.dept = 'toy'"
)
print
print
"-- the return value of a function can also be a tuple. However,"
print
"-- make sure that the expressions in the target list is in the "
print
"-- same order as the columns of EMP."
print
print
"CREATE FUNCTION new_emp() RETURNS EMP"
print
" AS 'SELECT
\'
None
\'
::text AS name,"
print
" 1000 AS salary,"
print
" 25 AS age,"
print
"
\'
none
\'
::varchar(16) AS dept'"
print
" LANGUAGE 'sql'"
pgcnx
.
query
(
"CREATE FUNCTION new_emp() RETURNS EMP "
\
"AS 'SELECT
\\\'
None
\\\'
::text AS name, "
\
"1000 AS salary, "
\
"25 AS age, "
\
"
\\\'
none
\\\'
::varchar(16) AS dept' "
\
"LANGUAGE 'sql'"
)
wait_key
()
print
print
"-- you can then project a column out of resulting the tuple by"
print
"-- using the
\"
function notation
\"
for projection columns. "
print
"-- (ie. bar(foo) is equivalent to foo.bar) Note that we don't"
print
"-- support new_emp().name at this moment."
print
print
"SELECT name(new_emp()) AS nobody"
print
pgcnx
.
query
(
"SELECT name(new_emp()) AS nobody"
)
print
print
"-- let's try one more function that returns tuples"
print
"CREATE FUNCTION high_pay() RETURNS setof EMP"
print
" AS 'SELECT * FROM EMP where salary > 1500'"
print
" LANGUAGE 'sql'"
pgcnx
.
query
(
"CREATE FUNCTION high_pay() RETURNS setof EMP "
\
"AS 'SELECT * FROM EMP where salary > 1500' "
\
"LANGUAGE 'sql'"
)
print
print
"SELECT name(high_pay()) AS overpaid"
print
pgcnx
.
query
(
"SELECT name(high_pay()) AS overpaid"
)
# function with multiple SQL commands
def
mult_func
(
pgcnx
):
print
"-----------------------------"
print
"-- Creating SQL Functions with multiple SQL statements"
print
"-- you can also create functions that do more than just a"
print
"-- SELECT."
print
"-----------------------------"
print
print
"-- you may have noticed that Andy has a negative salary. We'll"
print
"-- create a function that removes employees with negative "
print
"-- salaries."
print
print
"SELECT * FROM EMP"
print
pgcnx
.
query
(
"SELECT * FROM EMP"
)
print
print
"CREATE FUNCTION clean_EMP () RETURNS int4"
print
" AS 'DELETE FROM EMP WHERE EMP.salary <= 0"
print
" SELECT 1 AS ignore_this'"
print
" LANGUAGE 'sql'"
pgcnx
.
query
(
"CREATE FUNCTION clean_EMP () RETURNS int4 AS 'DELETE FROM EMP WHERE EMP.salary <= 0; SELECT 1 AS ignore_this' LANGUAGE 'sql'"
)
print
print
"SELECT clean_EMP()"
print
pgcnx
.
query
(
"SELECT clean_EMP()"
)
print
print
"SELECT * FROM EMP"
print
pgcnx
.
query
(
"SELECT * FROM EMP"
)
# base cleanup
def
demo_cleanup
(
pgcnx
):
print
"-- remove functions that were created in this file"
print
print
"DROP FUNCTION clean_EMP()"
print
"DROP FUNCTION high_pay()"
print
"DROP FUNCTION new_emp()"
print
"DROP FUNCTION add_em(int4, int4)"
print
"DROP FUNCTION one()"
print
print
"DROP TABLE EMP"
pgcnx
.
query
(
"DROP FUNCTION clean_EMP()"
)
pgcnx
.
query
(
"DROP FUNCTION high_pay()"
)
pgcnx
.
query
(
"DROP FUNCTION new_emp()"
)
pgcnx
.
query
(
"DROP FUNCTION add_em(int4, int4)"
)
pgcnx
.
query
(
"DROP FUNCTION one()"
)
pgcnx
.
query
(
"DROP TABLE EMP"
)
# main demo function
def
demo
(
pgcnx
):
base_func
(
pgcnx
)
comp_func
(
pgcnx
)
mult_func
(
pgcnx
)
demo_cleanup
(
pgcnx
)
src/interfaces/python/tutorial/pgtools.py
deleted
100755 → 0
View file @
0bd84442
#! /usr/local/bin/python
# pgtools.py - valuable functions for PostGreSQL tutorial
# written 1995 by Pascal ANDRE
import
sys
# number of rows
scr_size
=
24
# waits for a key
def
wait_key
():
print
"Press <enter>"
sys
.
stdin
.
read
(
1
)
# displays a table for a select query result
def
display
(
fields
,
result
):
print
result
# gets cols width
fmt
=
[]
sep
=
'+'
head
=
'|'
for
i
in
range
(
0
,
len
(
fields
)):
max
=
len
(
fields
[
i
])
for
j
in
range
(
0
,
len
(
result
)):
if
i
<
len
(
result
[
j
]):
if
len
(
result
[
j
][
i
])
>
max
:
max
=
len
(
result
[
j
][
i
])
fmt
.
append
(
"
%%%
ds |"
%
max
)
for
j
in
range
(
0
,
max
):
sep
=
sep
+
'-'
sep
=
sep
+
'--+'
for
i
in
range
(
0
,
len
(
fields
)):
head
=
head
+
fmt
[
i
]
%
fields
[
i
]
print
sep
+
'
\n
'
+
head
+
'
\n
'
+
sep
pos
=
6
for
i
in
range
(
0
,
len
(
result
)):
str
=
'|'
for
j
in
range
(
0
,
len
(
result
[
i
])):
str
=
str
+
fmt
[
j
]
%
result
[
i
][
j
]
print
str
pos
=
pos
+
1
if
pos
==
scr_size
:
print
sep
wait_key
()
print
sep
+
'
\n
'
+
head
+
'
\n
'
+
sep
pos
=
6
print
sep
wait_key
()
src/interfaces/python/tutorial/syscat.py
deleted
100755 → 0
View file @
0bd84442
# syscat.py - parses some system catalogs
# inspired from the PostgreSQL tutorial
# adapted to Python 1995 by Pascal ANDRE
print
"____________________________________________________________________"
print
print
"MODULE SYSCAT.PY : PARSES SOME POSTGRESQL SYSTEM CATALOGS"
print
print
"This module is designed for being imported from python prompt"
print
print
"In order to run the samples included here, first create a connection"
print
"using : cnx = syscat.DB(...)"
print
"then start the demo with: syscat.demo(cnx)"
print
print
"Some results may be empty, depending on your base status."
print
print
"____________________________________________________________________"
print
from
pg
import
DB
from
pgtools
import
*
# lists all simple indices
def
list_simple_ind
(
pgcnx
):
result
=
pgcnx
.
query
(
"select bc.relname "
\
"as class_name, ic.relname as index_name, a.attname "
\
"from pg_class bc, pg_class ic, pg_index i, pg_attribute a "
\
"where i.indrelid = bc.oid and i.indexrelid = bc.oid "
\
" and i.indkey[0] = a.attnum and a.attrelid = bc.oid "
\
" and i.indproc = '0'::oid "
\
"order by class_name, index_name, attname"
)
return
result
# list all user defined attributes and their type in user-defined classes
def
list_all_attr
(
pgcnx
):
result
=
pgcnx
.
query
(
"select c.relname, a.attname, t.typname "
\
"from pg_class c, pg_attribute a, pg_type t "
\
"where c.relkind = 'r' and c.relname !~ '^pg_' "
\
" and c.relname !~ '^Inv' and a.attnum > 0 "
\
" and a.attrelid = c.oid and a.atttypid = t.oid "
\
"order by relname, attname"
)
return
result
# list all user defined base type
def
list_user_base_type
(
pgcnx
):
result
=
pgcnx
.
query
(
"select u.usename, t.typname "
\
"from pg_type t, pg_user u "
\
"where u.usesysid = int2in(int4out(t.typowner)) "
\
" and t.typrelid = '0'::oid and t.typelem = '0'::oid "
\
" and u.usename <> 'postgres' order by usename, typname"
)
return
result
# list all right-unary operators
def
list_right_unary_operator
(
pgcnx
):
result
=
pgcnx
.
query
(
"select o.oprname as right_unary, "
\
" lt.typname as operand, result.typname as return_type "
\
"from pg_operator o, pg_type lt, pg_type result "
\
"where o.oprkind='r' and o.oprleft = lt.oid "
\
" and o.oprresult = result.oid order by operand"
)
return
result
# list all left-unary operators
def
list_left_unary_operator
(
pgcnx
):
result
=
pgcnx
.
query
(
"select o.oprname as left_unary, "
\
" rt.typname as operand, result.typname as return_type "
\
"from pg_operator o, pg_type rt, pg_type result "
\
"where o.oprkind='l' and o.oprright = rt.oid "
\
" and o.oprresult = result.oid order by operand"
)
return
result
# list all binary operators
def
list_binary_operator
(
pgcnx
):
result
=
pgcnx
.
query
(
"select o.oprname as binary_op, "
\
" rt.typname as right_opr, lt.typname as left_opr, "
\
" result.typname as return_type "
\
"from pg_operator o, pg_type rt, pg_type lt, pg_type result "
\
"where o.oprkind = 'b' and o.oprright = rt.oid "
\
" and o.oprleft = lt.oid and o.oprresult = result.oid"
)
return
result
# returns the name, args and return type from all function of lang l
def
list_lang_func
(
pgcnx
,
l
):
result
=
pgcnx
.
query
(
"select p.proname, p.pronargs, t.typname "
\
"from pg_proc p, pg_language l, pg_type t "
\
"where p.prolang = l.oid and p.prorettype = t.oid "
\
" and l.lanname = '
%
s' order by proname"
%
l
)
return
result
# lists all the aggregate functions and the type to which they can be applied
def
list_agg_func
(
pgcnx
):
result
=
pgcnx
.
query
(
"select a.aggname, t.typname "
\
"from pg_aggregate a, pg_type t "
\
"where a.aggbasetype = t.oid order by aggname, typname"
)
return
result
# lists all the operator classes that can be used with each access method as
# well as the operators that can be used with the respective operator classes
def
list_op_class
(
pgcnx
):
result
=
pgcnx
.
query
(
"select am.amname, opc.opcname, opr.oprname "
\
"from pg_am am, pg_amop amop, pg_opclass opc, pg_operator opr "
\
"where amop.amopid = am.oid and amop.amopclaid = opc.oid "
\
" and amop.amopopr = opr.oid order by amname, opcname, oprname"
)
return
result
# demo function - runs all examples
def
demo
(
pgcnx
):
#import sys, os
#save_stdout = sys.stdout
#sys.stdout = os.popen("more", "w")
print
"Listing simple indices ..."
print
list_simple_ind
(
pgcnx
)
print
"Listing all attributes ..."
print
list_all_attr
(
pgcnx
)
print
"Listing all user-defined base types ..."
print
list_user_base_type
(
pgcnx
)
print
"Listing all left-unary operators defined ..."
print
list_left_unary_operator
(
pgcnx
)
print
"Listing all right-unary operators defined ..."
print
list_right_unary_operator
(
pgcnx
)
print
"Listing all binary operators ..."
print
list_binary_operator
(
pgcnx
)
print
"Listing C external function linked ..."
print
list_lang_func
(
pgcnx
,
'C'
)
print
"Listing C internal functions ..."
print
list_lang_func
(
pgcnx
,
'internal'
)
print
"Listing SQL functions defined ..."
print
list_lang_func
(
pgcnx
,
'sql'
)
print
"Listing 'aggregate functions' ..."
print
list_agg_func
(
pgcnx
)
print
"Listing 'operator classes' ..."
print
list_op_class
(
pgcnx
)
#del sys.stdout
#sys.stdout = save_stdout
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment