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
e55213a5
Commit
e55213a5
authored
May 17, 1999
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Re-add python.
parent
716b8e2d
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
3414 additions
and
0 deletions
+3414
-0
src/interfaces/python/ChangeLog
src/interfaces/python/ChangeLog
+65
-0
src/interfaces/python/README
src/interfaces/python/README
+986
-0
src/interfaces/python/README.linux
src/interfaces/python/README.linux
+33
-0
src/interfaces/python/mkdefines
src/interfaces/python/mkdefines
+11
-0
src/interfaces/python/pg.py
src/interfaces/python/pg.py
+237
-0
src/interfaces/python/pgmodule.c
src/interfaces/python/pgmodule.c
+2036
-0
src/interfaces/python/pgsqldb.py
src/interfaces/python/pgsqldb.py
+46
-0
No files found.
src/interfaces/python/ChangeLog
0 → 100644
View file @
e55213a5
PyGreSQL changelog.
===================
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 2.3
- connect.host returns "localhost" when connected to Unix socket
(torppa@tuhnu.cutery.fi)
- Use PyArg_ParseTupleAndKeywords in connect() (torppa@tuhnu.cutery.fi)
- fixes and cleanups (torppa@tuhnu.cutery.fi)
- Fixed memory leak in dictresult() (terekhov@emc.com)
- Deprecated pgext.py - functionality now in pg.py
- More cleanups to the tutorial
- Added fileno() method - terekhov@emc.com (Mikhail Terekhov)
- added money type to quoting function
- Compiles cleanly with more warnings turned on
- Returns PostgreSQL error message on error
- Init accepts keywords (Jarkko Torppa)
- Convenience functions can be overridden (Jarkko Torppa)
- added close() method
Version 2.2
- Added user and password support thanks to Ng Pheng Siong <ngps@post1.com>
- Insert queries return the inserted oid
- Add new pg wrapper (C modile renamed to _pg)
- Wrapped database connection in a class.
- Cleaned up some of the tutorial. (More work needed.)
- Added version and __version__. Thanks to thilo@eevolute.com for
the suggestion.
Version 2.1
- return fields as proper Python objects for field type
- Cleaned up pgext.py
- Added dictresult method
Version 2.0 (23/12/1997):
- updated code for PostgreSQL 6.2.1 and Python 1.5
- reformatted code and converted to ANSI
- Changed name to PyGreSQL (from PyGres95)
- changed order of arguments to connect function
- Created new type pgqueryobject and moved certain methods to it.
- Added a print function for pgqueryobject
Version 1.0b (4/11/1995):
- keyword support for connect function moved from library file to C code
and taken away from library.
- rewrote documentation
- bug fix in connect function
- enhancements in large objects interface methods
Version 1.0a (30/10/1995) (limited release):
- module adapted to standard Python syntax
- keyword support for connect function in library file
- rewrote default parameters interface (internal use of strings)
- fixed minor bugs in module interface
- redefinition of error messages
Version 0.9b (10/10/1995) (first public release):
- large objects implementation
- many bug fixes, enhancements, ...
Version 0.1a (7/10/1995):
- basic libpq functions (SQL access)
src/interfaces/python/README
0 → 100644
View file @
e55213a5
PyGreSQL
-
v2
.3
:
PostgreSQL
module
for
Python
==============================================
0.
Copyright
notice
===================
PyGreSQL
,
version
2.3
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.
Copyright (c) 1995, Pascal ANDRE (andre@via.ecp.fr)
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose, without fee, and without a written agreement
is hereby granted, provided that the above copyright notice and this
paragraph and the following two paragraphs appear in all copies or in any
new file that contains a substantial portion of this file.
IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE
AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
ENHANCEMENTS, OR MODIFICATIONS.
Further modifications copyright 1997, 1998 and 1999 by D'
Arcy
J
.
M
.
Cain
(
darcy
@
druid
.
net
)
subject
to
the
same
terms
and
conditions
as
above
.
1.
Presentation
===============
1.1
.
Introduction
-----------------
PostgreSQL
is
a
database
system
derived
from
Postgres4
.2
.
It
conforms
to
(
most
of
)
ANSI
SQL
and
offers
many
interesting
capabilities
(
C
dynamic
linking
for
functions
or
type
definition
,
etc
.).
This
package
is
copyright
by
the
Regents
of
the
University
of
California
,
and
is
freely
distributable
.
Python
is
an
interpreted
programming
language
.
It
is
object
oriented
,
simple
to
use
(
light
syntax
,
simple
and
straightforward
statements
),
and
has
many
extensions
for
building
GUIs
,
interfacing
with
WWW
,
etc
.
An
intelligent
web
browser
(
HotJava
like
)
is
currently
under
development
(
November
1995
),
and
this
should
open
programmers
many
doors
.
Python
is
copyrighted
by
Stichting
S
Mathematisch
Centrum
,
Amsterdam
,
The
Netherlands
,
and
is
freely
distributable
.
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
.
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
.
1.2
.
Distribution
files
-----------------------
README
-
this
file
Announce
-
announcement
of
this
release
ChangeLog
-
changes
that
affected
this
package
during
its
history
pgmodule
.
c
-
the
C
python
module
pg
.
py
-
PyGreSQL
DB
class
.
tutorial
/
-
demos
directory
Content
:
basics
.
py
,
syscat
.
py
,
advanced
.
py
,
func
.
py
and
pgtools
.
py
.
The
samples
here
have
been
taken
from
the
PostgreSQL
manual
and
were
used
for
module
testing
.
They
demonstrate
some
PostgreSQL
features
.
Pgtools
.
py
is
an
add
-
in
used
for
demonstration
.
1.3
.
Installation
-----------------
*
You
first
have
to
get
and
build
Python
and
PostgreSQL
.
*
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
.
*
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
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_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
.
*
If
you
want
a
shared
module
,
make
sure
that
the
"*shared*"
keyword
is
uncommented
and
add
the
above
line
below
it
.
You
used
to
need
to
install
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
example
,
that
's /usr/local/lib/Python on my system.
* Do '
make
-
f
Makefile
.
pre
.
in
boot
' and do '
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
...
?
-----------------------
The
home
sites
of
the
different
packages
are
:
-
Python
:
ftp
://
ftp
.
python
.
org
:/
pub
/
python
-
PosgreSQL
:
ftp
://
ftp
.
PostgreSQL
.
org
/
pub
/
postgresql
-
6.4
.
tar
.
gz
-
PyGreSQL
:
ftp
://
ftp
.
druid
.
net
/
pub
/
distrib
/
pygresql
-
2.2
.
tgz
A
Linux
RPM
can
be
picked
up
from
ftp
://
www
.
eevolute
.
com
/
pub
/
python
/.
1.5
.
Information
and
support
----------------------------
If
you
need
information
about
these
packages
please
check
their
web
sites
:
-
Python
:
http
://
www
.
python
.
org
/
-
PostgreSQL
:
http
://
www
.
postgresql
.
org
/
-
PyGres95
:
http
://
www
.
via
.
ecp
.
fr
/
via
/
products
/
pygres
.
html
-
PyGreSQL
:
http
://
www
.
druid
.
net
/
pygresql
/
For
support
:
-
Python
:
newgroup
comp
.
lang
.
python
-
PostgreSQL
:
mailing
list
(
see
package
documentation
for
information
)
-
PyGres95
:
contact
me
(
andre
@
via
.
ecp
.
fr
)
for
bug
reports
,
ideas
,
remarks
I
will
try
to
answer
as
long
as
my
free
time
allow
me
to
do
that
.
-
PyGreSQL
:
contact
me
(
darcy
@
druid
.
net
)
concerning
the
changes
to
2.
x
.
2.
Programming
information
==========================
This
module
defines
three
objects
:
the
pgobject
that
handles
the
connection
and
all
the
requests
to
the
database
,
the
pglargeobject
that
handles
all
the
accesses
to
Postgres
large
objects
and
pgqueryobject
that
handles
query
results
.
2.1
.
pg
module
description
----------------------------
The
module
defines
only
a
few
methods
that
allow
to
connect
to
a
database
and
to
allow
to
define
"default variables"
that
override
the
environment
variables
used
by
PostgreSQL
.
These
"default variables"
were
designed
to
allow
you
to
handle
general
connection
parameters
without
heavy
code
in
your
programs
.
You
can
prompt
the
user
for
a
value
,
put
it
in
the
default
variable
,
and
forget
it
,
without
having
to
modify
your
environment
.
The
support
for
default
variables
can
be
disabled
by
setting
the
-
DNO_DEF_VAR
option
in
the
Python
Setup
file
.
Methods
relative
to
this
are
specified
by
te
tag
[
DV
].
All
variables
are
set
to
None
at
module
initialization
,
specifying
that
standard
environment
variables
should
be
used
.
2.1.1
.
connect
-
opens
a
pg
connection
----------------------------------------
Syntax
:
connect
(
dbname
,
host
,
port
,
opt
,
tty
,
user
,
passwd
)
Parameters
:
dbname
-
name
of
connected
database
(
string
/
None
)
host
-
name
of
the
server
host
(
string
/
None
)
port
-
port
used
by
the
database
server
(
integer
/-
1
)
opt
-
connection
options
(
string
/
None
)
tty
-
debug
terminal
(
string
/
None
)
user
-
PostgreSQL
user
(
string
/
None
)
passwd
-
password
for
user
(
string
/
None
)
Return
type
:
pgobject
-
the
object
handling
the
connection
Exceptions
raised
:
TypeError
-
bad
argument
type
,
or
too
many
arguments
SyntaxError
-
duplicate
argument
definition
pg
.
error
-
some
error
occurred
during
pg
connection
definition
(+
all
exceptions
relative
to
object
allocation
)
Description
:
This
method
opens
a
connection
to
a
specified
database
on
a
given
PostgreSQL
server
.
You
can
use
keywords
here
,
as
described
in
the
Python
tutorial
;
the
names
of
the
keywords
are
the
name
of
the
parameters
given
in
the
syntax
line
.
For
a
precise
description
of
the
parameters
,
please
refer
to
the
PostgreSQL
user
manual
.
2.1.2
.
get_defhost
,
set_defhost
-
default
server
host
name
handling
[
DV
]
------------------------------------------------------------------------
Syntax
:
get_defhost
()
Parameters
:
none
Return
type
:
string
,
None
-
default
host
specification
Exceptions
raised
:
SyntaxError
-
too
many
arguments
Description
:
This
method
returns
the
current
default
host
specification
,
or
None
if
the
environment
variables
should
be
used
.
Environment
variables
won
't be looked
up.
Syntax: set_defhost(host)
Parameters:
host - new default host (string/None)
Return type:
string, None - previous default host specification
Exceptions raised:
TypeError - bad argument type, or too many arguments
Description:
This methods sets the default host value for new connections. If None is
supplied as parameter, environment variables will be used in future
connections. It returns the previous setting for default host.
2.1.3. get_defport, set_defport - default server port handling [DV]
-------------------------------------------------------------------
Syntax: get_defport()
Parameters: none
Return type:
integer, None - default port specification
Exceptions raised:
SyntaxError - too many arguments
Description:
This method returns the current default port specification, or None if
the environment variables should be used. Environment variables won'
t
be
looked
up
.
Syntax
:
set_defport
(
port
)
Parameters
:
port
-
new
default
port
(
integer
/-
1
)
Return
type
:
integer
,
None
-
previous
default
port
specification
Description
:
This
methods
sets
the
default
port
value
for
new
connections
.
If
-
1
is
supplied
as
parameter
,
environment
variables
will
be
used
in
future
connections
.
It
returns
the
previous
setting
for
default
port
.
2.1.4
.
get_defopt
,
set_defopt
-
default
connection
options
handling
[
DV
]
------------------------------------------------------------------------
Syntax
:
get_defopt
()
Parameters
:
none
Return
type
:
string
,
None
-
default
options
specification
Exceptions
raised
:
SyntaxError
-
too
many
arguments
Description
:
This
method
returns
the
current
default
connection
options
specification
,
or
None
if
the
environment
variables
should
be
used
.
Environment
variables
won
't be looked up.
Syntax: set_defopt(options)
Parameters:
options - new default connection options (string/None)
Return type:
string, None - previous default options specification
Exceptions raised:
TypeError - bad argument type, or too many arguments
Description:
This methods sets the default connection options value for new connections.
If None is supplied as parameter, environment variables will be used in
future connections. It returns the previous setting for default options.
2.1.5. get_deftty, set_deftty - default connection debug tty handling [DV]
--------------------------------------------------------------------------
Syntax: get_deftty()
Parameters: none
Return type:
string, None - default debug terminal specification
Exceptions raised:
SyntaxError - too many arguments
Description:
This method returns the current default debug terminal specification, or
None if the environment variables should be used. Environment variables
won'
t
be
looked
up
.
Syntax
:
set_deftty
(
terminal
)
Parameters
:
terminal
-
new
default
debug
terminal
(
string
/
None
)
Return
type
:
string
,
None
-
previous
default
debug
terminal
specification
Exceptions
raised
:
TypeError
-
bad
argument
type
,
or
too
many
arguments
Description
:
This
methods
sets
the
default
debug
terminal
value
for
new
connections
.
If
None
is
supplied
as
parameter
,
environment
variables
will
be
used
in
future
connections
.
It
returns
the
previous
setting
for
default
terminal
.
2.1.6
.
get_defbase
,
set_defbase
-
default
database
name
handling
[
DV
]
---------------------------------------------------------------------
Syntax
:
get_defbase
()
Parameters
:
none
Return
type
:
string
,
None
-
default
database
name
specification
Exceptions
raised
:
SyntaxError
-
too
many
arguments
Description
:
This
method
returns
the
current
default
database
name
specification
,
or
None
if
the
environment
variables
should
be
used
.
Environment
variables
won
't be looked up.
Syntax: set_defbase(base)
Parameters:
base - new default base name (string/None)
Return type:
string, None - previous default database name specification
Exceptions raised:
TypeError - bad argument type, or too many arguments
Description:
This method sets the default database name value for new connections. If
None is supplied as parameter, environment variables will be used in
future connections. It returns the previous setting for default host.
2.1.7. Module constants
-----------------------
Some constants are defined in the module dictionary. They are intended to be
used as parameters for methods calls. You should refer to PostgreSQL user
manual for more information about them. These constants are:
- large objects access modes, used by (pgobject.)locreate and
(pglarge.)open: (pg.)INV_READ, (pg.)INV_WRITE, (pg.)INV_ARCHIVE
- positional flags, used by (pglarge.)seek: (pg.)SEEK_SET,
(pg.)SEEK_CUR, (pg.)SEEK_END.
- version and __version__ constants that give the current version.
2.1.9.
2.1.10. Miscellaneous attributes
The following methods return information about the current connection.
-
2.2. pgobject description
---------------------------
This object handle a connection to a PostgreSQL database. It embeds and
hides all the parameters that define this connection, thus just leaving really
significant parameters in function calls.
Some methods give direct access to the connection socket. They are specified
by the tag [DA]. DO NOT USE THEM UNLESS YOU REALLY KNOW WHAT YOU ARE DOING. If
you prefer disabling them, set the -DNO_DIRECT option in the Python Setup file.
Some other methods give access to large objects (refer to PostgreSQL user
manual for more information about these). if you want to forbid access to these
from the module, set the -DNO_LARGE option in the Python Setup file. These
methods are specified by the tag [LO].
2.2.1. query - executes a SQL command string
--------------------------------------------
Syntax: query(command)
Parameters:
command - SQL command (string)
Return type:
pgqueryobject, None - result values
Exceptions raised:
TypeError - bad argument type, or too many arguments.
ValueError - empty SQL query
pg.error - error during query processing, or invalid connection
Description:
This method simply sends a SQL query to the database. If the query is
an insert statement, the return value is the OID of the newly
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.
pgqueryobject methods
---------------------
2.2.1.1. getresult - gets the values returned by the query
-------------------------------------------------------------
Syntax: getresult()
Parameters: none
Return type:
list - result values
Exceptions raised:
SyntaxError - too many parameters
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.
2.2.1.2. dictresult - like getresult but returns list of dictionaries
---------------------------------------------------------------------
Syntax: dictresult()
Parameters: none
Return type:
list - result values as a dictionary
Exceptions raised:
SyntaxError - too many parameters
pg.error - invalid previous result
Description:
This method returns the list of the values returned by the query
with each tuple returned as a dictionary with the field names
used as the dictionary index.
2.2.1.3. listfields - lists the fields names of the previous query result
-----------------------------------------------------------------------
Syntax: listfields()
Parameters: none
Return type:
list - fields names
Exceptions raised:
SyntaxError - too many parameters
pg.error - invalid previous result, or invalid connection
Description:
This method returns the list of names of the fields defined for the
query result. The fields are in the same order as the result values.
2.2.1.4. fieldname, fieldnum - field name-number conversion
---------------------------------------------------------
Syntax: fieldname(i)
Parameters:
i - field number (integer)
Return type:
string - field name
Exceptions raised:
TypeError - bad parameter type, or too many parameters
ValueError - invalid field number
pg.error - invalid previous result, or invalid connection
Description:
This method allows to find a field name from its rank number. It can be
useful for displaying a result. The fields are in the same order than the
result values.
Syntax: fieldnum(name)
Parameters:
name - field name (string)
Return type:
integer - field number
Exceptions raised:
TypeError - bad parameter type, or too many parameters
ValueError - unknown field name
pg.error - invalid previous result, or invalid connection
Description:
This method returns a field number from its name. It can be used to
build a function that converts result list strings to their correct
type, using a hardcoded table definition. The number returned is the
field rank in the result values list.
2.2.2. reset - resets the connection
------------------------------------
Syntax: reset()
Parameters: None
Return type: None
Exceptions raised:
TypeError - too many (any) arguments
Description:
This method resets the current database.
2.2.3. close - close the database connection
--------------------------------------------
Syntax: close()
Parameters: none
Return type: None
Exceptions raised:
TypeError - too many (any) arguments
Description:
This method closes the database connection. The connection will
be closed in any case when the connection is deleted but this
allows you to explicitly close it. It is mainly here to allow
the DB-SIG API wrapper to implement a close function.
2.2.4. fileno - returns the socket used to connect to the database
------------------------------------------------------------------
Syntax: fileno()
Parameters: none
Exceptions raised:
TypeError - too many (any) arguments
Description:
This method returns the underlying socket id used to connect
to the database. This is useful for use in select calls, etc.
Note: This function depends on having a recent version of the
database. See "-DNO_PQSOCKET" described above.
2.2.5. getnotify - gets the last notify from the server
-------------------------------------------------------
Syntax: getnotify()
Parameters: none
Return type:
tuple, None - last notify from server
Exceptions raised:
SyntaxError - too many parameters
pg.error - invalid connection
Description:
This methods try to get a notify from the server (from the SQL statement
NOTIFY). If the server returns no notify, the methods returns None.
Otherwise, it returns a tuple (couple) (relname, pid), where relname is the
name of the notify and pid the process id of the connection that triggered
the notify. Remember to do a listen query first otherwise getnotify
will always return None.
2.2.6. inserttable - insert a list into a table
-----------------------------------------------
Syntax: inserttable(table, values)
Parameters:
table - the table name (string)
values - list of rows values (list)
Return type:
None
Exception raised:
pg.error - invalid connection
TypeError - bad argument type, or too many arguments
Description:
This method allow to quickly insert large blocks of data in a table: it
inserts the whole values list into the given table. The list is a list of
tuples/lists that define the values for each inserted row. The rows values
may contain string, integer, long or double (real) values.
BE VERY CAREFUL: this method doesn'
t
typecheck
the
fields
according
to
the
table
definition
;
it
just
look
whether
or
not
it
knows
how
to
handle
such
types
.
2.2.7
.
putline
-
writes
a
line
to
the
server
socket
[
DA
]
--------------------------------------------------------
Syntax
:
putline
(
line
)
Parameters
:
line
-
line
to
be
written
(
string
)
Return
type
:
None
Exceptions
raised
:
pg
.
error
-
invalid
connection
TypeError
-
bad
parameter
type
,
or
too
many
parameters
Description
:
This
method
allows
to
directly
write
a
string
to
the
server
socket
.
2.2.8
.
getline
-
gets
a
line
from
server
socket
[
DA
]
----------------------------------------------------
Syntax
:
getline
()
Parameters
:
none
Return
type
:
string
-
the
line
read
Exceptions
raised
:
pg
.
error
-
invalid
connection
SyntaxError
-
too
many
parameters
Description
:
This
method
allows
to
directly
read
a
string
from
the
server
socket
.
2.2.9
.
endcopy
-
synchronizes
client
and
server
[
DA
]
----------------------------------------------------
Syntax
:
endcopy
()
Parameters
:
none
Return
type
:
None
Exceptions
raised
:
pg
.
error
-
invalid
connection
SyntaxError
-
too
many
parameters
Description
:
The
use
of
direct
access
methods
may
desynchonize
client
and
server
.
This
method
ensure
that
client
and
server
will
be
synchronized
.
2.2.10
.
locreate
-
creates
of
large
object
in
the
database
[
LO
]
---------------------------------------------------------------
Syntax
:
locreate
(
mode
)
Parameters
:
mode
-
large
object
create
mode
Return
type
:
pglarge
-
object
handling
the
postgres
large
object
Exceptions
raised
:
pg
.
error
-
invalid
connection
,
or
creation
error
TypeError
-
bad
parameter
type
,
or
too
many
parameters
Description
:
This
method
creates
a
large
object
in
the
database
.
The
mode
can
be
defined
by
OR
-
ing
the
constants
defined
in
the
pg
module
(
INV_READ
,
INV_WRITE
and
INV_ARCHIVE
).
Please
refer
to
PostgreSQL
user
manual
for
a
description
of
the
mode
values
.
2.2.11
.
getlo
-
builds
a
large
object
from
given
oid
[
LO
]
---------------------------------------------------------
Syntax
:
getlo
(
oid
)
Parameters
:
oid
-
oid
of
the
existing
large
object
(
integer
)
Return
type
:
pglarge
-
object
handling
the
postgres
large
object
Exceptions
raised
:
pg
.
error
-
invalid
connection
TypeError
-
bad
parameter
type
,
or
too
many
parameters
ValueError
-
bad
oid
value
(
0
is
invalid_oid
)
Description
:
This
method
allows
to
reuse
a
formerly
created
large
object
through
the
pglarge
interface
,
providing
the
user
have
its
oid
.
2.2.12
.
loimport
-
import
a
file
to
a
postgres
large
object
[
LO
]
----------------------------------------------------------------
Syntax
:
loimport
(
name
)
Parameters
:
name
-
the
name
of
the
file
to
be
imported
(
string
)
Return
type
:
pglarge
-
object
handling
the
postgres
large
object
Exceptions
raised
:
pg
.
error
-
invalid
connection
,
or
error
during
file
import
TypeError
-
bad
argument
type
,
or
too
many
arguments
Description
:
This
methods
allows
to
create
large
objects
in
a
very
simple
way
.
You
just
give
the
name
of
a
file
containing
the
data
to
be
use
.
2.2.13
.
pgobject
attributes
-----------------------------
Every
pgobject
defines
a
set
of
read
-
only
attributes
that
describe
the
connection
and
its
status
.
These
attributes
are
:
host
-
the
hostname
of
the
server
(
string
)
port
-
the
port
of
the
server
(
integer
)
db
-
the
selected
database
(
string
)
options
-
the
connection
options
(
string
)
tty
-
the
connection
debug
terminal
(
string
)
user
-
the
username
on
the
database
system
(
string
)
status
-
the
status
of
the
connection
(
integer
:
1
-
OK
,
0
-
BAD
)
error
-
the
last
warning
/
error
message
from
the
server
(
string
)
2.3
.
pglarge
description
--------------------------
This
object
handles
all
the
request
concerning
a
postgres
large
object
.
It
embeds
and
hides
all
the
'recurrent'
variables
(
object
oid
and
connection
),
exactly
in
the
same
way
pgobjects
do
,
thus
only
keeping
significant
parameters
in
function
calls
.
It
keeps
a
reference
to
the
pgobject
used
for
its
creation
,
sending
requests
though
with
its
parameters
.
Any
modification
but
dereferencing
the
pgobject
will
thus
affect
the
pglarge
object
.
Dereferencing
the
initial
pgobject
is
not
a
problem
since
Python
won
't
deallocate it before the large object dereference it.
All functions return a generic error message on call error, whatever the
exact error was. The '
error
' attribute of the object allow to get the exact
error message.
2.3.1. open - opens a large object
----------------------------------
Syntax: open(mode)
Parameters:
mode - open mode definition (integer)
Return type:
None
Exceptions raised:
pg.error - invalid connection
TypeError - bad parameter type, or too many parameters
IOError - already opened object, or open error
Description:
This method opens a large object for reading/writing, in the same way than
the UNIX open() function. The mode value can be obtained by OR-ing the
constants defined in the pgmodule (INV_READ, INV_WRITE).
2.3.2. close - closes a large object
------------------------------------
Syntax: close()
Parameters: none
Return type:
None
Exceptions raised:
pg.error - invalid connection
SyntaxError - too many parameters
IOError - object is not opened, or close error
Description:
This method closes a previously opened large object, in the same way than
the UNIX close() function.
2.3.4. read, write, tell, seek, unlink - file like large object handling
------------------------------------------------------------------------
Syntax: read(size)
Parameters:
size - maximal size of the buffer to be read
Return type:
sized string - the read buffer
Exceptions raised:
pg.error - invalid connection or invalid object
TypeError - bad parameter type, or too many parameters
IOError - object is not opened, or read error
Description:
This function allows to read data from a large object, starting at current
position.
Syntax: write(string)
Parameters:
(sized) string - buffer to be written
Return type:
None
Exceptions raised:
pg.error - invalid connection or invalid object
TypeError - bad parameter type, or too many parameters
IOError - object is not opened, or write error
Description:
This function allows to write data to a large object, starting at current
position.
Syntax: seek(offset, whence)
Parameters:
offset - position offset
whence - positional parameter
Return type:
integer - new position in object
Exception raised:
pg.error - invalid connection or invalid object
TypeError - bad parameter type, or too many parameters
IOError - object is not opened, or seek error
Description:
This method allows to move the position cursor in the large object. The
whence parameter can be obtained by OR-ing the constants defined in the
pg module (SEEK_SET, SEEK_CUR, SEEK_END).
Syntax: tell()
Parameters: none
Return type:
integer - current position in large object
Exception raised:
pg.error - invalid connection or invalid object
SyntaxError - too many parameters
IOError - object is not opened, or seek error
Description:
This method allows to get the current position in the large object.
Syntax: unlink()
Parameter: none
Return type:
None
Exception raised:
pg.error - invalid connection or invalid object
SyntaxError - too many parameters
IOError - object is not closed, or unlink error
Description:
This methods unlinks (deletes) the postgres large object.
2.3.5. size - gives the large object size
-----------------------------------------
Syntax: size()
Parameters: none
Return type:
integer - large object size
Exceptions raised:
pg.error - invalid connection or invalid object
SyntaxError - too many parameters
IOError - object is not opened, or seek/tell error
Description:
This (composite) method allows to get the size of a large object. Currently
the large object needs to be opened. It was implemented because this
function is very useful for a WWW interfaced database.
2.3.6. export - saves a large object to a file
----------------------------------------------
Syntax: export(name)
Parameters:
name - file to be created
Return type:
None
Exception raised:
pg.error - invalid connection or invalid object
TypeError - bad parameter type, or too many parameters
IOError - object is not closed, or export error
Description:
This methods allows to dump the content of a large object in a very simple
way. The exported file is created on the host of the program, not the
server host.
2.3.7. Object attributes
------------------------
pglarge objects define a read-only set of attributes that allow to get some
information about it. These attributes are:
oid - the oid associated with the object
pgcnx - the pgobject associated with the object
error - the last warning/error message of the connection
BE CAREFUL: in multithreaded environments, '
error
' may be modified by another
thread using the same pgobject. Remember these object are shared, not
duplicated. You should provide some locking to be able if you want to check
this.
The oid attribute is very interesting because it allow you reuse the oid
later, creating the pglarge object with a pgobject getlo() method call.
3. The pg wrapper
================
The previous functions are wrapped in a module called pg. The module
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
.
The
following
describes
the
methods
and
variables
of
this
class
.
3.1
.
Initialization
-------------------
The
DB
class
is
initialized
with
the
same
arguments
as
the
connect
method
described
in
section
2.
It
also
initializes
a
few
internal
variables
.
The
statement
'db = DB()'
will
open
the
local
database
with
the
name
of
the
user
just
like
connect
()
does
.
3.2
.
pkey
---------
Syntax
:
pkey
(
table
)
Parameters
:
table
-
name
of
table
Returns
:
Name
of
field
which
is
the
primary
key
of
the
table
.
Description
:
This
method
returns
the
primary
key
of
a
table
.
Note
that
this
raises
an
exception
if
the
table
doesn
't have a primary key. Further, in the
currently released implementation of PostgreSQL the '
PRIMARY
KEY
' syntax
doesn'
t
actually
fill
in
the
necessary
tables
to
determine
primary
keys
.
You
can
do
this
yourself
with
the
following
query
.
#
Set
up
table
and
primary_field
variables
...
"""UPDATE pg_index SET indisprimary = 't'
WHERE pg_index.oid in (SELECT pg_index.oid
FROM pg_class, pg_attribute, pg_index
WHERE pg_class.oid = pg_attribute.attrelid AND
pg_class.oid = pg_index.indrelid AND
pg_index.indkey[0] = pg_attribute.attnum AND
pg_class.relname = '%(table)s' AND
pg_attribute.attname = '%(primary_field)');"""
%
locals
()
This
will
be
fixed
in
the
upcoming
6.5
release
of
PostgreSQL
or
you
can
download
the
current
sources
now
.
Downloading
current
is
,
as
usual
,
at
your
own
risk
.
3.3
.
get_databases
-
get
list
of
databases
in
the
system
--------------------------------------------------------
Syntax
:
get_databases
()
Parameters
:
none
Returns
:
list
of
databases
in
the
system
Description
:
Although
you
can
do
this
with
a
simple
select
,
it
is
added
here
for
convenience
3.4
.
get_tables
-
get
list
of
tables
in
connected
database
----------------------------------------------------------
Syntax
:
get_tables
()
Parameters
:
none
Returns
:
list
of
tables
in
connected
database
3.5
.
get_attnames
-----------------
Syntax
:
get_attnames
(
table
)
Parameters
:
table
-
name
of
table
Returns
:
List
of
attribute
names
Description
:
Given
the
name
of
a
table
,
digs
out
the
list
of
attribute
names
.
3.6
.
get
-
get
a
tuple
from
a
database
table
--------------------------------------------
Syntax
:
get
(
table
,
arg
,
[
keyname
])
Parameters
:
table
-
name
of
table
arg
-
either
a
dictionary
or
the
value
to
be
looked
up
keyname
-
name
of
field
to
use
as
key
(
optional
)
Returns
:
A
dictionary
mapping
attribute
names
to
row
values
.
Description
:
This
method
is
the
basic
mechanism
to
get
a
single
row
.
It
assumes
that
the
key
specifies
a
unique
row
.
If
keyname
is
not
specified
then
the
primary
key
for
the
table
is
used
.
If
arg
is
a
dictionary
then
the
value
for
the
key
is
taken
from
it
and
it
is
modified
to
include
the
new
values
,
replacing
existing
values
where
necessary
.
The
oid
is
also
put
into
the
dictionary
but
in
order
to
allow
the
caller
to
work
with
multiple
tables
,
the
attribute
name
is
munged
to
make
it
unique
.
It
consists
of
the
string
"oid_"
followed
by
the
name
of
the
table
.
3.7
.
insert
-
insert
a
tuple
into
a
database
table
--------------------------------------------------
Syntax
:
insert
(
table
,
a
)
Parameters
:
table
-
name
of
table
a
-
a
dictionary
of
values
Returns
:
The
OID
of
the
newly
inserted
row
.
Description
:
This
method
inserts
values
into
the
table
specified
filling
in
the
values
from
the
dictionary
.
It
then
reloads
the
dictionary
with
the
values
from
the
database
.
This
causes
the
dictionary
to
be
updated
with
values
that
are
modified
by
rules
,
triggers
,
etc
.
3.8
.
update
-----------
Syntax
:
update
(
table
,
a
)
Parameters
:
table
-
name
of
table
a
-
a
dictionary
of
values
Returns
:
A
dictionary
with
the
new
row
Description
:
Similar
to
insert
but
updates
an
existing
row
.
The
update
is
based
on
the
OID
value
as
munged
by
get
.
The
array
returned
is
the
one
sent
modified
to
reflect
any
changes
caused
by
the
update
due
to
triggers
,
rules
,
defaults
,
etc
.
3.9
.
clear
----------
Syntax
:
clear
(
table
,
[
a
])
Parameters
:
table
-
name
of
table
a
-
a
dictionary
of
values
Returns
:
A
dictionary
with
an
empty
row
Description
:
This
method
clears
all
the
attributes
to
values
determined
by
the
types
.
Numeric
types
are
set
to
0
,
dates
are
set
to
'TODAY'
and
everything
else
is
set
to
the
empty
string
.
If
the
array
argument
is
present
,
it
is
used
as
the
array
and
any
entries
matching
attribute
names
are
cleared
with
everything
else
left
unchanged
.
3.8
.
delete
-----------
Syntax
:
delete
(
table
,
a
)
Parameters
:
table
-
name
of
table
a
-
a
dictionary
of
values
Returns
:
None
Description
:
This
method
deletes
the
row
from
a
table
.
It
deletes
based
on
the
OID
as
munged
as
described
above
.
4.
Future
directions
====================
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
.
src/interfaces/python/README.linux
0 → 100644
View file @
e55213a5
Thanks to thilo@eevolute.com for this README and the RPM
INSTALLING PyGreSQL on Redhat Linux 5.1 or 5.2
==============================================
Things are pretty easy on Redhat Linux. You can either get a precompiled
RPM package from
ftp://www.eevolute.com/pub/python/
or try in compile and install it yourself:
bash$ make redhat # this just compiles the module as a shared object
cc -fpic -shared -o _pg.so -I/usr/include/python1.5 pgmodule.c -lpq
bash$ python # you can test it from your local directory
Python 1.5.1 (#1, May 6 1998, 01:48:27) [GCC 2.7.2.3] on linux-i386
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> 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)
bash$ su # Yow! Seems to work - now install it properly
bash# cp _pg.so /usr/lib/python1.5/lib-dynload
done!
src/interfaces/python/mkdefines
0 → 100755
View file @
e55213a5
#! /usr/local/bin/python
import
string
# change this if you have it somewhere else
for
l
in
open
(
"/usr/local/pgsql/src/include/catalog/pg_type.h"
)
.
readlines
():
tokens
=
string
.
split
(
l
)
if
len
(
tokens
)
==
0
or
tokens
[
0
]
!=
"#define"
:
continue
if
tokens
[
1
]
in
(
'CASHOID'
,
'INT2OID'
,
'INT4OID'
,
'OIDOID'
,
'FLOAT4OID'
,
'FLOAT8OID'
):
print
l
,
src/interfaces/python/pg.py
0 → 100644
View file @
e55213a5
# pgutil.py
# Written by D'Arcy J.M. Cain
# This library implements some basic database management stuff
# It includes the pg module and builds on it
from
_pg
import
*
import
string
,
re
,
sys
# utility function
# We expect int, seq, decimal, text or date (more later)
def
_quote
(
d
,
t
):
if
t
in
[
'int'
,
'decimal'
,
'seq'
]:
if
d
==
""
:
return
0
return
"
%
s"
%
d
if
t
==
'money'
:
if
d
==
""
:
return
'0.00'
return
"'
%.2
f'"
%
d
if
t
==
'bool'
:
if
string
.
upper
(
d
)
in
[
'T'
,
'TRUE'
,
'Y'
,
'YES'
,
1
,
'1'
,
'ON'
]:
return
"'t'"
else
:
return
"'f'"
if
d
==
""
:
return
"null"
return
"'
%
s'"
%
string
.
strip
(
re
.
sub
(
'
\'
'
,
'
\'\'
'
,
"
%
s"
%
d
))
class
DB
:
"""This class wraps the pg connection type"""
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
)
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>"
# Get all the primary keys at once
for
rel
,
att
in
self
.
db
.
query
(
"""SELECT
pg_class.relname, pg_attribute.attname
FROM pg_class, pg_attribute, pg_index
WHERE pg_class.oid = pg_attribute.attrelid AND
pg_class.oid = pg_index.indrelid AND
pg_index.indkey[0] = pg_attribute.attnum AND
pg_index.indisprimary = 't'"""
)
.
getresult
():
self
.
pkeys
[
rel
]
=
att
def
pkey
(
self
,
cl
):
# will raise an exception if primary key doesn't exist
return
self
.
pkeys
[
cl
]
def
get_databases
(
self
):
l
=
[]
for
n
in
self
.
db
.
query
(
"SELECT datname FROM pg_database"
)
.
getresult
():
l
.
append
(
n
[
0
])
return
l
def
get_tables
(
self
):
l
=
[]
for
n
in
self
.
db
.
query
(
"""SELECT relname FROM pg_class
WHERE relkind = 'r' AND
relname !~ '^Inv' AND
relname !~ '^pg_'"""
)
.
getresult
():
l
.
append
(
n
[
0
])
return
l
def
get_attnames
(
self
,
cl
):
# May as well cache them
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
WHERE pg_class.relname = '
%
s' AND
pg_attribute.attnum > 0 AND
pg_attribute.attrelid = pg_class.oid AND
pg_attribute.atttypid = pg_type.oid"""
l
=
{}
for
attname
,
typname
in
self
.
db
.
query
(
query
%
cl
)
.
getresult
():
if
re
.
match
(
"^int"
,
typname
):
l
[
attname
]
=
'int'
elif
re
.
match
(
"^oid"
,
typname
):
l
[
attname
]
=
'int'
elif
re
.
match
(
"^text"
,
typname
):
l
[
attname
]
=
'text'
elif
re
.
match
(
"^char"
,
typname
):
l
[
attname
]
=
'text'
elif
re
.
match
(
"^name"
,
typname
):
l
[
attname
]
=
'text'
elif
re
.
match
(
"^abstime"
,
typname
):
l
[
attname
]
=
'date'
elif
re
.
match
(
"^date"
,
typname
):
l
[
attname
]
=
'date'
elif
re
.
match
(
"^bool"
,
typname
):
l
[
attname
]
=
'bool'
elif
re
.
match
(
"^float"
,
typname
):
l
[
attname
]
=
'decimal'
elif
re
.
match
(
"^money"
,
typname
):
l
[
attname
]
=
'money'
else
:
l
[
attname
]
=
'text'
self
.
attnames
[
cl
]
=
l
return
self
.
attnames
[
cl
]
# return a tuple from a database
def
get
(
self
,
cl
,
arg
,
keyname
=
None
):
if
keyname
==
None
:
# use the primary key by default
keyname
=
self
.
pkeys
[
cl
]
fnames
=
self
.
get_attnames
(
cl
)
if
type
(
arg
)
==
type
({}):
# To allow users to work with multiple tables we munge the
# name when the key is "oid"
if
keyname
==
'oid'
:
k
=
arg
[
'oid_
%
s'
%
cl
]
else
:
k
=
arg
[
keyname
]
else
:
k
=
arg
arg
=
{}
# 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
)
else
:
q
=
"SELECT oid AS oid_
%
s,
%
s FROM
%
s WHERE
%
s =
%
s"
%
\
(
cl
,
string
.
join
(
fnames
.
keys
(),
','
),
\
cl
,
keyname
,
_quote
(
k
,
fnames
[
keyname
]))
if
self
.
debug
!=
None
:
print
self
.
debug
%
q
res
=
self
.
db
.
query
(
q
)
.
dictresult
()
if
res
==
[]:
raise
error
,
\
"No such record in
%
s where
%
s is
%
s"
%
\
(
cl
,
keyname
,
_quote
(
k
,
fnames
[
keyname
]))
return
None
for
k
in
res
[
0
]
.
keys
():
arg
[
k
]
=
res
[
0
][
k
]
return
arg
# Inserts a new tuple into a table
def
insert
(
self
,
cl
,
a
):
fnames
=
self
.
get_attnames
(
cl
)
l
=
[]
n
=
[]
for
f
in
fnames
.
keys
():
if
a
.
has_key
(
f
):
if
a
[
f
]
==
""
:
l
.
append
(
"null"
)
else
:
l
.
append
(
_quote
(
a
[
f
],
fnames
[
f
]))
n
.
append
(
f
)
try
:
q
=
"INSERT INTO
%
s (
%
s) VALUES (
%
s)"
%
\
(
cl
,
string
.
join
(
n
,
','
),
string
.
join
(
l
,
','
))
if
self
.
debug
!=
None
:
print
self
.
debug
%
q
a
[
'oid_
%
s'
%
cl
]
=
self
.
db
.
query
(
q
)
except
:
raise
error
,
"Error inserting into
%
s:
%
s"
%
(
cl
,
sys
.
exc_value
)
# reload the dictionary to catch things modified by engine
# note that get() changes 'oid' below to oid_table
return
self
.
get
(
cl
,
a
,
'oid'
)
# update always works on the oid which get returns
def
update
(
self
,
cl
,
a
):
q
=
"SELECT oid FROM
%
s WHERE oid =
%
s"
%
(
cl
,
a
[
'oid_
%
s'
%
cl
])
if
self
.
debug
!=
None
:
print
self
.
debug
%
q
res
=
self
.
db
.
query
(
q
)
.
getresult
()
if
len
(
res
)
<
1
:
raise
error
,
"No record in
%
s where oid =
%
s (
%
s)"
%
\
(
cl
,
a
[
'oid_
%
s'
%
cl
],
sys
.
exc_value
)
v
=
[]
k
=
0
fnames
=
self
.
get_attnames
(
cl
)
for
ff
in
fnames
.
keys
():
if
a
.
has_key
(
ff
)
and
a
[
ff
]
!=
res
[
0
][
k
]:
v
.
append
(
"
%
s =
%
s"
%
(
ff
,
_quote
(
a
[
ff
],
fnames
[
ff
])))
if
v
==
[]:
return
None
try
:
q
=
"UPDATE
%
s SET
%
s WHERE oid =
%
s"
%
\
(
cl
,
string
.
join
(
v
,
','
),
a
[
'oid_
%
s'
%
cl
])
if
self
.
debug
!=
None
:
print
self
.
debug
%
q
self
.
db
.
query
(
q
)
except
:
raise
error
,
"Can't update
%
s:
%
s"
%
(
cl
,
sys
.
exc_value
)
# reload the dictionary to catch things modified by engine
return
self
.
get
(
cl
,
a
,
'oid'
)
# At some point we will need a way to get defaults from a table
def
clear
(
self
,
cl
,
a
=
{}):
fnames
=
self
.
get_attnames
(
cl
)
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
]
=
""
a
[
'oid'
]
=
0
return
a
# Like update, delete works on the oid
# one day we will be testing that the record to be deleted
# isn't referenced somewhere (or else PostgreSQL will)
def
delete
(
self
,
cl
,
a
):
try
:
q
=
"DELETE FROM
%
s WHERE oid =
%
s"
%
(
cl
,
a
[
'oid_
%
s'
%
cl
])
if
self
.
debug
!=
None
:
print
self
.
debug
%
q
self
.
db
.
query
(
q
)
except
:
raise
error
,
"Can't delete
%
s:
%
s"
%
(
cl
,
sys
.
exc_value
)
return
None
src/interfaces/python/pgmodule.c
0 → 100644
View file @
e55213a5
/*
* PyGres, version 2.2 A Python interface for PostgreSQL database. Written by
* D'Arcy J.M. Cain, (darcy@druid.net). Based heavily on code written by
* Pascal Andre, andre@chimay.via.ecp.fr. Copyright (c) 1995, Pascal Andre
* (andre@via.ecp.fr).
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without a written
* agreement is hereby granted, provided that the above copyright notice and
* this paragraph and the following two paragraphs appear in all copies or in
* any new file that contains a substantial portion of this file.
*
* IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
* SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
* AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE
* AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS.
*
* Further modifications copyright 1997 by D'Arcy J.M. Cain (darcy@druid.net)
* subject to the same terms and conditions as above.
*
*/
#include <Python.h>
#include <libpq-fe.h>
#include <libpq/libpq-fs.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 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
static
PyObject
*
PGError
;
static
const
char
*
PyPgVersion
=
"2.3"
;
/* taken from fileobject.c */
#define BUF(v) PyString_AS_STRING((PyStringObject *)(v))
#define CHECK_OPEN 1
#define CHECK_CLOSE 2
#define MAX_BUFFER_SIZE 8192
/* maximum transaction size */
#ifndef 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 */
#ifndef NO_DEF_VAR
#define DEFAULT_VARS 1
/* enables default variables use */
#endif
/* NO_DEF_VAR */
/* --------------------------------------------------------------------- */
/* MODULE GLOBAL VARIABLES */
#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 */
#endif
/* DEFAULT_VARS */
/* --------------------------------------------------------------------- */
/* OBJECTS DECLARATION */
/* pg connection object */
typedef
struct
{
PyObject_HEAD
int
valid
;
/* validity flag */
PGconn
*
cnx
;
/* PostGres connection handle */
}
pgobject
;
staticforward
PyTypeObject
PgType
;
#define is_pgobject(v) ((v)->ob_type == &PgType)
/* pg query object */
typedef
struct
{
PyObject_HEAD
PGresult
*
last_result
;
/* last result content */
}
pgqueryobject
;
staticforward
PyTypeObject
PgQueryType
;
#define is_pgqueryobject(v) ((v)->ob_type == &PgQueryType)
#ifdef LARGE_OBJECTS
/* pg large object */
typedef
struct
{
PyObject_HEAD
pgobject
*
pgcnx
;
Oid
lo_oid
;
int
lo_fd
;
}
pglargeobject
;
staticforward
PyTypeObject
PglargeType
;
#define is_pglargeobject(v) ((v)->ob_type == &PglargeType)
#endif
/* LARGE_OBJECTS */
/* --------------------------------------------------------------------- */
/* INTERNAL FUNCTIONS */
#ifdef LARGE_OBJECTS
/* validity check (large object) */
static
int
check_lo
(
pglargeobject
*
self
,
int
level
)
{
if
(
!
self
->
lo_oid
)
{
PyErr_SetString
(
PGError
,
"object is not valid (null oid)."
);
return
0
;
}
if
(
level
&
CHECK_OPEN
)
{
if
(
self
->
lo_fd
<
0
)
{
PyErr_SetString
(
PyExc_IOError
,
"object is not opened."
);
return
0
;
}
}
if
(
level
&
CHECK_CLOSE
)
{
if
(
self
->
lo_fd
>=
0
)
{
PyErr_SetString
(
PyExc_IOError
,
"object is already opened."
);
return
0
;
}
}
return
1
;
}
#endif
/* LARGE_OBJECTS */
/* --------------------------------------------------------------------- */
#ifdef LARGE_OBJECTS
/* PG CONNECTION OBJECT IMPLEMENTATION */
/* pglargeobject initialisation (from pgobject) */
/* creates large object */
static
PyObject
*
pg_locreate
(
pgobject
*
self
,
PyObject
*
args
)
{
int
mode
;
pglargeobject
*
npglo
;
if
(
!
self
->
cnx
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Connection is not valid"
);
return
NULL
;
}
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"i"
,
&
mode
))
{
PyErr_SetString
(
PyExc_TypeError
,
"locreate(mode), with mode (integer)."
);
return
NULL
;
}
if
((
npglo
=
PyObject_NEW
(
pglargeobject
,
&
PglargeType
))
==
NULL
)
return
NULL
;
npglo
->
pgcnx
=
self
;
Py_XINCREF
(
self
);
npglo
->
lo_fd
=
-
1
;
npglo
->
lo_oid
=
lo_creat
(
self
->
cnx
,
mode
);
/* checks result validity */
if
(
npglo
->
lo_oid
==
0
)
{
PyErr_SetString
(
PGError
,
"can't create large object."
);
Py_XDECREF
(
npglo
);
return
NULL
;
}
return
(
PyObject
*
)
npglo
;
}
/* init from already known oid */
static
PyObject
*
pg_getlo
(
pgobject
*
self
,
PyObject
*
args
)
{
int
lo_oid
;
pglargeobject
*
npglo
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"i"
,
&
lo_oid
))
{
PyErr_SetString
(
PyExc_TypeError
,
"loopen(oid), with oid (integer)."
);
return
NULL
;
}
if
(
!
lo_oid
)
{
PyErr_SetString
(
PyExc_ValueError
,
"the object oid can't be null."
);
return
NULL
;
}
/* creates object */
if
((
npglo
=
PyObject_NEW
(
pglargeobject
,
&
PglargeType
))
==
NULL
)
return
NULL
;
npglo
->
pgcnx
=
self
;
Py_XINCREF
(
self
);
npglo
->
lo_fd
=
-
1
;
npglo
->
lo_oid
=
lo_oid
;
return
(
PyObject
*
)
npglo
;
}
/* import unix file */
static
PyObject
*
pg_loimport
(
pgobject
*
self
,
PyObject
*
args
)
{
char
*
name
;
pglargeobject
*
npglo
;
if
(
!
self
->
cnx
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Connection is not valid"
);
return
NULL
;
}
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"s"
,
&
name
))
{
PyErr_SetString
(
PyExc_TypeError
,
"loimport(name), with name (string)."
);
return
NULL
;
}
if
((
npglo
=
PyObject_NEW
(
pglargeobject
,
&
PglargeType
))
==
NULL
)
return
NULL
;
npglo
->
pgcnx
=
self
;
Py_XINCREF
(
self
);
npglo
->
lo_fd
=
-
1
;
npglo
->
lo_oid
=
lo_import
(
self
->
cnx
,
name
);
/* checks result validity */
if
(
npglo
->
lo_oid
==
0
)
{
PyErr_SetString
(
PGError
,
"can't create large object."
);
Py_XDECREF
(
npglo
);
return
NULL
;
}
return
(
PyObject
*
)
npglo
;
}
/* pglargeobject methods */
/* destructor */
static
void
pglarge_dealloc
(
pglargeobject
*
self
)
{
if
(
self
->
lo_fd
>=
0
&&
self
->
pgcnx
->
valid
==
1
)
lo_close
(
self
->
pgcnx
->
cnx
,
self
->
lo_fd
);
Py_XDECREF
(
self
->
pgcnx
);
PyMem_DEL
(
self
);
}
/* opens large object */
static
PyObject
*
pglarge_open
(
pglargeobject
*
self
,
PyObject
*
args
)
{
int
mode
,
fd
;
/* check validity */
if
(
!
check_lo
(
self
,
CHECK_CLOSE
))
return
NULL
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"i"
,
&
mode
))
{
PyErr_SetString
(
PyExc_TypeError
,
"open(mode), with mode(integer)."
);
return
NULL
;
}
/* opens large object */
if
((
fd
=
lo_open
(
self
->
pgcnx
->
cnx
,
self
->
lo_oid
,
mode
))
<
0
)
{
PyErr_SetString
(
PyExc_IOError
,
"can't open large object."
);
return
NULL
;
}
self
->
lo_fd
=
fd
;
/* no error : returns Py_None */
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* close large object */
static
PyObject
*
pglarge_close
(
pglargeobject
*
self
,
PyObject
*
args
)
{
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method close() takes no parameters."
);
return
NULL
;
}
/* checks validity */
if
(
!
check_lo
(
self
,
CHECK_OPEN
))
return
NULL
;
/* closes large object */
if
(
lo_close
(
self
->
pgcnx
->
cnx
,
self
->
lo_fd
))
{
PyErr_SetString
(
PyExc_IOError
,
"error while closing large object fd."
);
return
NULL
;
}
self
->
lo_fd
=
-
1
;
/* no error : returns Py_None */
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* reads from large object */
static
PyObject
*
pglarge_read
(
pglargeobject
*
self
,
PyObject
*
args
)
{
int
size
;
PyObject
*
buffer
;
/* checks validity */
if
(
!
check_lo
(
self
,
CHECK_OPEN
))
return
NULL
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"i"
,
&
size
))
{
PyErr_SetString
(
PyExc_TypeError
,
"read(size), wih size (integer)."
);
return
NULL
;
}
if
(
size
<=
0
)
{
PyErr_SetString
(
PyExc_ValueError
,
"size must be positive."
);
return
NULL
;
}
/* allocate buffer and runs read */
buffer
=
PyString_FromStringAndSize
((
char
*
)
NULL
,
size
);
if
((
size
=
lo_read
(
self
->
pgcnx
->
cnx
,
self
->
lo_fd
,
BUF
(
buffer
),
size
))
<
0
)
{
PyErr_SetString
(
PyExc_IOError
,
"error while reading."
);
Py_XDECREF
(
buffer
);
return
NULL
;
}
/* resize buffer and returns it */
_PyString_Resize
(
&
buffer
,
size
);
return
buffer
;
}
/* write to large object */
static
PyObject
*
pglarge_write
(
pglargeobject
*
self
,
PyObject
*
args
)
{
char
*
buffer
;
int
size
;
/* checks validity */
if
(
!
check_lo
(
self
,
CHECK_OPEN
))
return
NULL
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"s"
,
&
buffer
))
{
PyErr_SetString
(
PyExc_TypeError
,
"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
))
{
PyErr_SetString
(
PyExc_IOError
,
"buffer truncated during write."
);
return
NULL
;
}
/* no error : returns Py_None */
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* go to position in large object */
static
PyObject
*
pglarge_lseek
(
pglargeobject
*
self
,
PyObject
*
args
)
{
int
ret
,
offset
,
whence
;
/* checks validity */
if
(
!
check_lo
(
self
,
CHECK_OPEN
))
return
NULL
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"ii"
,
&
offset
,
&
whence
))
{
PyErr_SetString
(
PyExc_TypeError
,
"lseek(offset, whence), with offset and whence (integers)."
);
return
NULL
;
}
/* sends query */
if
((
ret
=
lo_lseek
(
self
->
pgcnx
->
cnx
,
self
->
lo_fd
,
offset
,
whence
))
==
-
1
)
{
PyErr_SetString
(
PyExc_IOError
,
"error while moving cursor."
);
return
NULL
;
}
/* returns position */
return
PyInt_FromLong
(
ret
);
}
/* gets large object size */
static
PyObject
*
pglarge_size
(
pglargeobject
*
self
,
PyObject
*
args
)
{
int
start
,
end
;
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method size() takes no parameters."
);
return
NULL
;
}
/* checks validity */
if
(
!
check_lo
(
self
,
CHECK_OPEN
))
return
NULL
;
/* gets current position */
if
((
start
=
lo_tell
(
self
->
pgcnx
->
cnx
,
self
->
lo_fd
))
==
-
1
)
{
PyErr_SetString
(
PyExc_IOError
,
"error while getting current position."
);
return
NULL
;
}
/* gets end position */
if
((
end
=
lo_lseek
(
self
->
pgcnx
->
cnx
,
self
->
lo_fd
,
0
,
SEEK_END
))
==
-
1
)
{
PyErr_SetString
(
PyExc_IOError
,
"error while getting end position."
);
return
NULL
;
}
/* move back to start position */
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."
);
return
NULL
;
}
/* returns size */
return
PyInt_FromLong
(
end
);
}
/* gets large object cursor position */
static
PyObject
*
pglarge_tell
(
pglargeobject
*
self
,
PyObject
*
args
)
{
int
start
;
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method tell() takes no parameters."
);
return
NULL
;
}
/* checks validity */
if
(
!
check_lo
(
self
,
CHECK_OPEN
))
return
NULL
;
/* gets current position */
if
((
start
=
lo_tell
(
self
->
pgcnx
->
cnx
,
self
->
lo_fd
))
==
-
1
)
{
PyErr_SetString
(
PyExc_IOError
,
"error while getting position."
);
return
NULL
;
}
/* returns size */
return
PyInt_FromLong
(
start
);
}
/* exports large object as unix file */
static
PyObject
*
pglarge_export
(
pglargeobject
*
self
,
PyObject
*
args
)
{
char
*
name
;
/* checks validity */
if
(
!
check_lo
(
self
,
CHECK_CLOSE
))
return
NULL
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"s"
,
&
name
))
{
PyErr_SetString
(
PyExc_TypeError
,
"export(filename), with filename (string)."
);
return
NULL
;
}
/* runs command */
if
(
!
lo_export
(
self
->
pgcnx
->
cnx
,
self
->
lo_oid
,
name
))
{
PyErr_SetString
(
PyExc_IOError
,
"error while exporting large object."
);
return
NULL
;
}
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* deletes a large object */
static
PyObject
*
pglarge_unlink
(
pglargeobject
*
self
,
PyObject
*
args
)
{
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method unlink() takes no parameters."
);
return
NULL
;
}
/* checks validity */
if
(
!
check_lo
(
self
,
CHECK_CLOSE
))
return
NULL
;
/* deletes the object, invalidate it on success */
if
(
!
lo_unlink
(
self
->
pgcnx
->
cnx
,
self
->
lo_oid
))
{
PyErr_SetString
(
PyExc_IOError
,
"error while unlinking large object"
);
return
NULL
;
}
self
->
lo_oid
=
0
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* large object methods */
static
struct
PyMethodDef
pglarge_methods
[]
=
{
{
"open"
,
(
PyCFunction
)
pglarge_open
,
1
},
/* opens large object */
{
"close"
,
(
PyCFunction
)
pglarge_close
,
1
},
/* closes large object */
{
"read"
,
(
PyCFunction
)
pglarge_read
,
1
},
/* reads from large object */
{
"write"
,
(
PyCFunction
)
pglarge_write
,
1
},
/* writes to large object */
{
"seek"
,
(
PyCFunction
)
pglarge_lseek
,
1
},
/* seeks position */
{
"size"
,
(
PyCFunction
)
pglarge_size
,
1
},
/* gives object size */
{
"tell"
,
(
PyCFunction
)
pglarge_tell
,
1
},
/* gives position in lobj */
{
"export"
,
(
PyCFunction
)
pglarge_export
,
1
},
/* exports to unix file */
{
"unlink"
,
(
PyCFunction
)
pglarge_unlink
,
1
},
/* deletes a large object */
{
NULL
,
NULL
}
/* sentinel */
};
/* get attribute */
static
PyObject
*
pglarge_getattr
(
pglargeobject
*
self
,
char
*
name
)
{
/* list postgreSQL large object fields */
/* associated pg connection object */
if
(
!
strcmp
(
name
,
"pgcnx"
))
{
if
(
check_lo
(
self
,
0
))
{
Py_INCREF
(
self
->
pgcnx
);
return
(
PyObject
*
)
(
self
->
pgcnx
);
}
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* large object oid */
if
(
!
strcmp
(
name
,
"oid"
))
{
if
(
check_lo
(
self
,
0
))
return
PyInt_FromLong
(
self
->
lo_oid
);
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* error (status) message */
if
(
!
strcmp
(
name
,
"error"
))
return
PyString_FromString
(
PQerrorMessage
(
self
->
pgcnx
->
cnx
));
/* attributes list */
if
(
!
strcmp
(
name
,
"__members__"
))
{
PyObject
*
list
=
PyList_New
(
3
);
if
(
list
)
{
PyList_SetItem
(
list
,
0
,
PyString_FromString
(
"oid"
));
PyList_SetItem
(
list
,
1
,
PyString_FromString
(
"pgcnx"
));
PyList_SetItem
(
list
,
2
,
PyString_FromString
(
"error"
));
}
return
list
;
}
return
Py_FindMethod
(
pglarge_methods
,
(
PyObject
*
)
self
,
name
);
}
/* object type definition */
staticforward
PyTypeObject
PglargeType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/* ob_size */
"pglarge"
,
/* tp_name */
sizeof
(
pglargeobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
(
destructor
)
pglarge_dealloc
,
/* tp_dealloc */
0
,
/* 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 */
/* --------------------------------------------------------------------- */
/* PG CONNECTION OBJECT IMPLEMENTATION */
/* pgobject initialisation (from module) */
static
PyObject
*
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 */
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
dict
,
"|zzlzzzz"
,
kwlist
,
&
pgdbname
,
&
pghost
,
&
pgport
,
&
pgopt
,
&
pgtty
,
&
pguser
,
&
pgpasswd
))
return
NULL
;
#ifdef DEFAULT_VARS
/* handles defaults variables (for unintialised vars) */
if
((
!
pghost
)
&&
(
pg_default_host
!=
Py_None
))
pghost
=
PyString_AsString
(
pg_default_host
);
if
((
pgport
==
-
1
)
&&
(
pg_default_port
!=
Py_None
))
pgport
=
PyInt_AsLong
(
pg_default_port
);
if
((
!
pgopt
)
&&
(
pg_default_opt
!=
Py_None
))
pgopt
=
PyString_AsString
(
pg_default_opt
);
if
((
!
pgtty
)
&&
(
pg_default_tty
!=
Py_None
))
pgtty
=
PyString_AsString
(
pg_default_tty
);
if
((
!
pgdbname
)
&&
(
pg_default_base
!=
Py_None
))
pgdbname
=
PyString_AsString
(
pg_default_base
);
if
((
!
pguser
)
&&
(
pg_default_user
!=
Py_None
))
pguser
=
PyString_AsString
(
pg_default_user
);
if
((
!
pgpasswd
)
&&
(
pg_default_passwd
!=
Py_None
))
pgpasswd
=
PyString_AsString
(
pg_default_passwd
);
#endif
/* DEFAULT_VARS */
if
((
npgobj
=
PyObject_NEW
(
pgobject
,
&
PgType
))
==
NULL
)
return
NULL
;
if
(
pgport
!=
-
1
)
{
bzero
(
port_buffer
,
sizeof
(
port_buffer
));
sprintf
(
port_buffer
,
"%d"
,
pgport
);
npgobj
->
cnx
=
PQsetdbLogin
(
pghost
,
port_buffer
,
pgopt
,
pgtty
,
pgdbname
,
pguser
,
pgpasswd
);
}
else
npgobj
->
cnx
=
PQsetdbLogin
(
pghost
,
NULL
,
pgopt
,
pgtty
,
pgdbname
,
pguser
,
pgpasswd
);
if
(
PQstatus
(
npgobj
->
cnx
)
==
CONNECTION_BAD
)
{
PyErr_SetString
(
PGError
,
PQerrorMessage
(
npgobj
->
cnx
));
Py_XDECREF
(
npgobj
);
return
NULL
;
}
return
(
PyObject
*
)
npgobj
;
}
/* pgobject methods */
/* destructor */
static
void
pg_dealloc
(
pgobject
*
self
)
{
if
(
self
->
cnx
)
PQfinish
(
self
->
cnx
);
PyMem_DEL
(
self
);
}
/* close without deleting */
static
PyObject
*
pg_close
(
pgobject
*
self
,
PyObject
*
args
)
{
/* gets args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_TypeError
,
"close()."
);
return
NULL
;
}
if
(
self
->
cnx
)
PQfinish
(
self
->
cnx
);
self
->
cnx
=
NULL
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
void
pg_querydealloc
(
pgqueryobject
*
self
)
{
if
(
self
->
last_result
)
PQclear
(
self
->
last_result
);
PyMem_DEL
(
self
);
}
/* resets connection */
static
PyObject
*
pg_reset
(
pgobject
*
self
,
PyObject
*
args
)
{
if
(
!
self
->
cnx
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Connection is not valid"
);
return
NULL
;
}
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method reset() takes no parameters."
);
return
NULL
;
}
/* resets the connection */
PQreset
(
self
->
cnx
);
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* get connection socket */
static
PyObject
*
pg_fileno
(
pgobject
*
self
,
PyObject
*
args
)
{
if
(
!
self
->
cnx
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Connection is not valid"
);
return
NULL
;
}
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method fileno() takes no parameters."
);
return
NULL
;
}
#ifdef NO_PQSOCKET
return
PyInt_FromLong
((
long
)
self
->
cnx
->
sock
);
#else
return
PyInt_FromLong
((
long
)
PQsocket
(
self
->
cnx
));
#endif
}
/* list fields names from query result */
static
PyObject
*
pg_listfields
(
pgqueryobject
*
self
,
PyObject
*
args
)
{
int
i
,
n
;
char
*
name
;
PyObject
*
fieldstuple
,
*
str
;
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method listfields() takes no parameters."
);
return
NULL
;
}
/* builds tuple */
n
=
PQnfields
(
self
->
last_result
);
fieldstuple
=
PyTuple_New
(
n
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
name
=
PQfname
(
self
->
last_result
,
i
);
str
=
PyString_FromString
(
name
);
PyTuple_SetItem
(
fieldstuple
,
i
,
str
);
}
return
fieldstuple
;
}
/* get field name from last result */
static
PyObject
*
pg_fieldname
(
pgqueryobject
*
self
,
PyObject
*
args
)
{
int
i
;
char
*
name
;
/* gets args */
if
(
!
PyArg_ParseTuple
(
args
,
"i"
,
&
i
))
{
PyErr_SetString
(
PyExc_TypeError
,
"fieldname(number), with number(integer)."
);
return
NULL
;
}
/* checks number validity */
if
(
i
>=
PQnfields
(
self
->
last_result
))
{
PyErr_SetString
(
PyExc_ValueError
,
"invalid field number."
);
return
NULL
;
}
/* gets fields name and builds object */
name
=
PQfname
(
self
->
last_result
,
i
);
return
PyString_FromString
(
name
);
}
/* gets fields number from name in last result */
static
PyObject
*
pg_fieldnum
(
pgqueryobject
*
self
,
PyObject
*
args
)
{
char
*
name
;
int
num
;
/* gets args */
if
(
!
PyArg_ParseTuple
(
args
,
"s"
,
&
name
))
{
PyErr_SetString
(
PyExc_TypeError
,
"fieldnum(name), with name (string)."
);
return
NULL
;
}
/* gets field number */
if
((
num
=
PQfnumber
(
self
->
last_result
,
name
))
==
-
1
)
{
PyErr_SetString
(
PyExc_ValueError
,
"Unknown field."
);
return
NULL
;
}
return
PyInt_FromLong
(
num
);
}
/* retrieves last result */
static
PyObject
*
pg_getresult
(
pgqueryobject
*
self
,
PyObject
*
args
)
{
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."
);
return
NULL
;
}
/* stores result in tuple */
reslist
=
PyList_New
(
0
);
m
=
PQntuples
(
self
->
last_result
);
n
=
PQnfields
(
self
->
last_result
);
if
((
typ
=
malloc
(
sizeof
(
int
)
*
n
))
==
NULL
)
{
PyErr_SetString
(
PyExc_SyntaxError
,
"memory error in getresult()."
);
return
NULL
;
}
for
(
j
=
0
;
j
<
n
;
j
++
)
{
switch
(
PQftype
(
self
->
last_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
;
}
}
for
(
i
=
0
;
i
<
m
;
i
++
)
{
rowtuple
=
PyTuple_New
(
n
);
for
(
j
=
0
;
j
<
n
;
j
++
)
{
char
*
s
=
PQgetvalue
(
self
->
last_result
,
i
,
j
);
char
cashbuf
[
64
];
switch
(
typ
[
j
])
{
case
1
:
val
=
PyInt_FromLong
(
strtol
(
s
,
NULL
,
10
));
break
;
case
2
:
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 */
s
++
;
for
(
i
=
0
;
*
s
;
s
++
)
if
(
*
s
!=
','
)
cashbuf
[
i
++
]
=
*
s
;
cashbuf
[
i
]
=
0
;
val
=
PyFloat_FromDouble
(
strtod
(
cashbuf
,
NULL
));
break
;
default:
val
=
PyString_FromString
(
s
);
break
;
}
PyTuple_SetItem
(
rowtuple
,
j
,
val
);
}
PyList_Append
(
reslist
,
rowtuple
);
Py_XDECREF
(
rowtuple
);
}
free
(
typ
);
/* returns list */
return
reslist
;
}
/* retrieves last result as a list of dictionaries*/
static
PyObject
*
pg_dictresult
(
pgqueryobject
*
self
,
PyObject
*
args
)
{
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."
);
return
NULL
;
}
/* stores result in list */
reslist
=
PyList_New
(
0
);
m
=
PQntuples
(
self
->
last_result
);
n
=
PQnfields
(
self
->
last_result
);
if
((
typ
=
malloc
(
sizeof
(
int
)
*
n
))
==
NULL
)
{
PyErr_SetString
(
PyExc_SyntaxError
,
"memory error in getresult()."
);
return
NULL
;
}
for
(
j
=
0
;
j
<
n
;
j
++
)
{
switch
(
PQftype
(
self
->
last_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
;
}
}
for
(
i
=
0
;
i
<
m
;
i
++
)
{
dict
=
PyDict_New
();
for
(
j
=
0
;
j
<
n
;
j
++
)
{
int
k
;
char
*
s
=
PQgetvalue
(
self
->
last_result
,
i
,
j
);
char
cashbuf
[
64
];
switch
(
typ
[
j
])
{
case
1
:
val
=
PyInt_FromLong
(
strtol
(
s
,
NULL
,
10
));
break
;
case
2
:
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 */
s
++
;
for
(
k
=
0
;
*
s
;
s
++
)
if
(
*
s
!=
','
)
cashbuf
[
k
++
]
=
*
s
;
cashbuf
[
k
]
=
0
;
val
=
PyFloat_FromDouble
(
strtod
(
cashbuf
,
NULL
));
break
;
default:
val
=
PyString_FromString
(
s
);
break
;
}
PyDict_SetItemString
(
dict
,
PQfname
(
self
->
last_result
,
j
),
val
);
Py_XDECREF
(
val
);
}
PyList_Append
(
reslist
,
dict
);
Py_XDECREF
(
dict
);
}
free
(
typ
);
/* returns list */
return
reslist
;
}
/* getq asynchronous notify */
static
PyObject
*
pg_getnotify
(
pgobject
*
self
,
PyObject
*
args
)
{
PGnotify
*
notify
;
PGresult
*
result
;
PyObject
*
notify_result
,
*
temp
;
if
(
!
self
->
cnx
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Connection is not valid"
);
return
NULL
;
}
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"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 */
result
=
PQexec
(
self
->
cnx
,
" "
);
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
);
free
(
notify
);
}
else
{
Py_INCREF
(
Py_None
);
notify_result
=
Py_None
;
}
PQclear
(
result
);
/* returns result */
return
notify_result
;
}
/* database query */
static
PyObject
*
pg_query
(
pgobject
*
self
,
PyObject
*
args
)
{
char
*
query
;
PGresult
*
result
;
pgqueryobject
*
npgobj
;
int
status
;
if
(
!
self
->
cnx
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Connection is not valid"
);
return
NULL
;
}
/* get query args */
if
(
!
PyArg_ParseTuple
(
args
,
"s"
,
&
query
))
{
PyErr_SetString
(
PyExc_TypeError
,
"query(sql), with sql (string)."
);
return
NULL
;
}
/* gets result */
result
=
PQexec
(
self
->
cnx
,
query
);
/* checks result validity */
if
(
!
result
)
{
PyErr_SetString
(
PyExc_ValueError
,
PQerrorMessage
(
self
->
cnx
));
return
NULL
;
}
/* checks result status */
if
((
status
=
PQresultStatus
(
result
))
!=
PGRES_TUPLES_OK
)
{
const
char
*
str
;
PQclear
(
result
);
switch
(
status
)
{
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
->
cnx
));
break
;
case
PGRES_COMMAND_OK
:
/* could be an INSERT */
if
(
*
(
str
=
PQoidStatus
(
result
))
==
0
)
/* nope */
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* otherwise, return the oid */
return
PyInt_FromLong
(
strtol
(
str
,
NULL
,
10
));
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."
);
break
;
}
return
NULL
;
/* error detected on query */
}
if
((
npgobj
=
PyObject_NEW
(
pgqueryobject
,
&
PgQueryType
))
==
NULL
)
return
NULL
;
/* stores result and returns object */
npgobj
->
last_result
=
result
;
return
(
PyObject
*
)
npgobj
;
}
#ifdef DIRECT_ACCESS
/* direct acces function : putline */
static
PyObject
*
pg_putline
(
pgobject
*
self
,
PyObject
*
args
)
{
char
*
line
;
if
(
!
self
->
cnx
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Connection is not valid"
);
return
NULL
;
}
/* reads args */
if
(
!
PyArg_ParseTuple
(
args
,
"s"
,
&
line
))
{
PyErr_SetString
(
PyExc_TypeError
,
"putline(line), with line (string)."
);
return
NULL
;
}
/* sends line to backend */
PQputline
(
self
->
cnx
,
line
);
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* direct access function : getline */
static
PyObject
*
pg_getline
(
pgobject
*
self
,
PyObject
*
args
)
{
char
line
[
MAX_BUFFER_SIZE
];
PyObject
*
str
=
NULL
;
/* GCC */
int
ret
;
if
(
!
self
->
cnx
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Connection is not valid"
);
return
NULL
;
}
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method getline() takes no parameters."
);
return
NULL
;
}
/* gets line */
switch
(
PQgetline
(
self
->
cnx
,
line
,
MAX_BUFFER_SIZE
))
{
case
0
:
str
=
PyString_FromString
(
line
);
break
;
case
1
:
PyErr_SetString
(
PyExc_MemoryError
,
"buffer overflow"
);
str
=
NULL
;
break
;
case
EOF
:
Py_INCREF
(
Py_None
);
str
=
Py_None
;
break
;
}
return
str
;
}
/* direct access function : end copy */
static
PyObject
*
pg_endcopy
(
pgobject
*
self
,
PyObject
*
args
)
{
if
(
!
self
->
cnx
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Connection is not valid"
);
return
NULL
;
}
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method endcopy() takes no parameters."
);
return
NULL
;
}
/* ends direct copy */
PQendcopy
(
self
->
cnx
);
Py_INCREF
(
Py_None
);
return
Py_None
;
}
#endif
/* DIRECT_ACCESS */
static
PyObject
*
pg_print
(
pgqueryobject
*
self
,
FILE
*
fp
,
int
flags
)
{
PQprintOpt
op
;
memset
(
&
op
,
0
,
sizeof
(
op
));
op
.
align
=
1
;
op
.
header
=
1
;
op
.
fieldSep
=
"|"
;
op
.
pager
=
1
;
PQprint
(
fp
,
self
->
last_result
,
&
op
);
return
0
;
}
/* insert table */
static
PyObject
*
pg_inserttable
(
pgobject
*
self
,
PyObject
*
args
)
{
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
;
if
(
!
self
->
cnx
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Connection is not valid"
);
return
NULL
;
}
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"sO:filter"
,
&
table
,
&
list
))
{
PyErr_SetString
(
PyExc_TypeError
,
"tableinsert(table, content), with table (string) "
"and content (list)."
);
return
NULL
;
}
/* checks list type */
if
(
PyTuple_Check
(
list
))
getitem
=
PyTuple_GetItem
;
else
if
(
PyList_Check
(
list
))
getitem
=
PyList_GetItem
;
else
{
PyErr_SetString
(
PyExc_TypeError
,
"second arg must be some kind of array."
);
return
NULL
;
}
/* checks sublists type */
for
(
i
=
0
;
(
sublist
=
getitem
(
list
,
i
))
!=
NULL
;
i
++
)
{
if
(
!
PyTuple_Check
(
sublist
)
&&
!
PyList_Check
(
sublist
))
{
PyErr_SetString
(
PyExc_TypeError
,
"second arg must contain some kind of arrays."
);
return
NULL
;
}
}
/* allocate buffer */
if
(
!
(
buffer
=
malloc
(
MAX_BUFFER_SIZE
)))
{
PyErr_SetString
(
PyExc_MemoryError
,
"can't allocate insert buffer."
);
return
NULL
;
}
/* starts query */
sprintf
(
buffer
,
"copy %s from stdin"
,
table
);
if
(
!
(
result
=
PQexec
(
self
->
cnx
,
buffer
)))
{
free
(
buffer
);
PyErr_SetString
(
PyExc_ValueError
,
PQerrorMessage
(
self
->
cnx
));
return
NULL
;
}
PQclear
(
result
);
/* feeds table */
for
(
i
=
0
;
(
sublist
=
getitem
(
list
,
i
))
!=
NULL
;
i
++
)
{
if
(
PyTuple_Check
(
sublist
))
getsubitem
=
PyTuple_GetItem
;
else
getsubitem
=
PyList_GetItem
;
/* builds insert line */
buffer
[
0
]
=
0
;
for
(
j
=
0
;
(
item
=
getsubitem
(
sublist
,
j
))
!=
NULL
;
j
++
)
{
/* converts item to string */
if
(
PyString_Check
(
item
))
PyArg_ParseTuple
(
item
,
"s"
,
&
temp
);
else
if
(
PyInt_Check
(
item
))
{
int
k
;
PyArg_ParseTuple
(
item
,
"i"
,
&
k
);
sprintf
(
temp_buffer
,
"%d"
,
k
);
temp
=
temp_buffer
;
}
else
if
(
PyLong_Check
(
item
))
{
long
k
;
PyArg_ParseTuple
(
item
,
"l"
,
&
k
);
sprintf
(
temp_buffer
,
"%ld"
,
k
);
temp
=
temp_buffer
;
}
else
if
(
PyFloat_Check
(
item
))
{
double
k
;
PyArg_ParseTuple
(
item
,
"d"
,
&
k
);
sprintf
(
temp_buffer
,
"%g"
,
k
);
temp
=
temp_buffer
;
}
else
{
free
(
buffer
);
PyErr_SetString
(
PyExc_ValueError
,
"items must be strings, integers, "
"longs or double (real)."
);
return
NULL
;
}
/* concats buffer */
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
));
}
strncat
(
buffer
,
"
\n
"
,
MAX_BUFFER_SIZE
-
strlen
(
buffer
));
/* sends data */
PQputline
(
self
->
cnx
,
buffer
);
}
/* ends query */
PQputline
(
self
->
cnx
,
".
\n
"
);
PQendcopy
(
self
->
cnx
);
free
(
buffer
);
/* no error : returns nothing */
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* connection object methods */
static
struct
PyMethodDef
pgobj_methods
[]
=
{
{
"query"
,
(
PyCFunction
)
pg_query
,
1
},
/* query method */
{
"reset"
,
(
PyCFunction
)
pg_reset
,
1
},
/* connection reset */
{
"close"
,
(
PyCFunction
)
pg_close
,
1
},
/* connection close */
{
"fileno"
,
(
PyCFunction
)
pg_fileno
,
1
},
/* connection socket */
{
"getnotify"
,
(
PyCFunction
)
pg_getnotify
,
1
},
/* checks for notify */
{
"inserttable"
,
(
PyCFunction
)
pg_inserttable
,
1
},
/* table insert */
#ifdef DIRECT_ACCESS
{
"putline"
,
(
PyCFunction
)
pg_putline
,
1
},
/* direct access: putline */
{
"getline"
,
(
PyCFunction
)
pg_getline
,
1
},
/* direct access: getline */
{
"endcopy"
,
(
PyCFunction
)
pg_endcopy
,
1
},
/* direct access: endcopy */
#endif
/* DIRECT_ACCESS */
#ifdef LARGE_OBJECTS
{
"locreate"
,
(
PyCFunction
)
pg_locreate
,
1
},
/* creates large object */
{
"getlo"
,
(
PyCFunction
)
pg_getlo
,
1
},
/* get lo from oid */
{
"loimport"
,
(
PyCFunction
)
pg_loimport
,
1
},
/* imports lo from file */
#endif
/* LARGE_OBJECTS */
{
NULL
,
NULL
}
/* sentinel */
};
/* get attribute */
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 */
if
(
!
self
->
cnx
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Connection is not valid"
);
return
NULL
;
}
/* list postgreSQL connection fields */
/* postmaster host */
if
(
!
strcmp
(
name
,
"host"
))
{
char
*
r
=
PQhost
(
self
->
cnx
);
return
r
?
PyString_FromString
(
r
)
:
PyString_FromString
(
"localhost"
);
}
/* postmaster port */
if
(
!
strcmp
(
name
,
"port"
))
return
PyInt_FromLong
(
atol
(
PQport
(
self
->
cnx
)));
/* selected database */
if
(
!
strcmp
(
name
,
"db"
))
return
PyString_FromString
(
PQdb
(
self
->
cnx
));
/* selected options */
if
(
!
strcmp
(
name
,
"options"
))
return
PyString_FromString
(
PQoptions
(
self
->
cnx
));
/* selected postgres tty */
if
(
!
strcmp
(
name
,
"tty"
))
return
PyString_FromString
(
PQtty
(
self
->
cnx
));
/* error (status) message */
if
(
!
strcmp
(
name
,
"error"
))
return
PyString_FromString
(
PQerrorMessage
(
self
->
cnx
));
/* connection status : 1 - OK, 0 - BAD */
if
(
!
strcmp
(
name
,
"status"
))
return
PyInt_FromLong
(
PQstatus
(
self
->
cnx
)
==
CONNECTION_OK
?
1
:
0
);
/* provided user name */
if
(
!
strcmp
(
name
,
"user"
))
return
PyString_FromString
(
"Deprecated facility"
);
/* return PyString_FromString(fe_getauthname("<unknown user>")); */
/* attributes list */
if
(
!
strcmp
(
name
,
"__members__"
))
{
PyObject
*
list
=
PyList_New
(
8
);
if
(
list
)
{
PyList_SetItem
(
list
,
0
,
PyString_FromString
(
"host"
));
PyList_SetItem
(
list
,
1
,
PyString_FromString
(
"port"
));
PyList_SetItem
(
list
,
2
,
PyString_FromString
(
"db"
));
PyList_SetItem
(
list
,
3
,
PyString_FromString
(
"options"
));
PyList_SetItem
(
list
,
4
,
PyString_FromString
(
"tty"
));
PyList_SetItem
(
list
,
5
,
PyString_FromString
(
"error"
));
PyList_SetItem
(
list
,
6
,
PyString_FromString
(
"status"
));
PyList_SetItem
(
list
,
7
,
PyString_FromString
(
"user"
));
}
return
list
;
}
return
Py_FindMethod
(
pgobj_methods
,
(
PyObject
*
)
self
,
name
);
}
/* object type definition */
staticforward
PyTypeObject
PgType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/* ob_size */
"pgobject"
,
/* tp_name */
sizeof
(
pgobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
(
destructor
)
pg_dealloc
,
/* tp_dealloc */
0
,
/* tp_print */
(
getattrfunc
)
pg_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 */
};
/* query object methods */
static
struct
PyMethodDef
pgquery_methods
[]
=
{
{
"getresult"
,
(
PyCFunction
)
pg_getresult
,
1
},
/* get last result */
{
"dictresult"
,
(
PyCFunction
)
pg_dictresult
,
1
},
/* get result as dict*/
{
"fieldname"
,
(
PyCFunction
)
pg_fieldname
,
1
},
/* get field name */
{
"fieldnum"
,
(
PyCFunction
)
pg_fieldnum
,
1
},
/* get field number */
{
"listfields"
,
(
PyCFunction
)
pg_listfields
,
1
},
/* list fields names */
{
NULL
,
NULL
}
/* sentinel */
};
static
PyObject
*
pg_querygetattr
(
pgqueryobject
*
self
,
char
*
name
)
{
/* list postgreSQL connection fields */
return
Py_FindMethod
(
pgquery_methods
,
(
PyObject
*
)
self
,
name
);
}
/* query type definition */
staticforward
PyTypeObject
PgQueryType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/* ob_size */
"pgqueryobject"
,
/* tp_name */
sizeof
(
pgqueryobject
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
(
destructor
)
pg_querydealloc
,
/* tp_dealloc */
(
printfunc
)
pg_print
,
/* tp_print */
(
getattrfunc
)
pg_querygetattr
,
/* 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 */
};
/* --------------------------------------------------------------------- */
/* MODULE FUNCTIONS */
#ifdef DEFAULT_VARS
/* gets default host */
static
PyObject
*
pggetdefhost
(
PyObject
*
self
,
PyObject
*
args
)
{
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method get_defhost() takes no parameter."
);
return
NULL
;
}
Py_XINCREF
(
pg_default_host
);
return
pg_default_host
;
}
/* sets default host */
static
PyObject
*
pgsetdefhost
(
PyObject
*
self
,
PyObject
*
args
)
{
char
*
temp
=
NULL
;
PyObject
*
old
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"z"
,
&
temp
))
{
PyErr_SetString
(
PyExc_TypeError
,
"set_defhost(name), with name (string/None)."
);
return
NULL
;
}
/* adjusts value */
old
=
pg_default_host
;
if
(
temp
)
pg_default_host
=
PyString_FromString
(
temp
);
else
{
Py_INCREF
(
Py_None
);
pg_default_host
=
Py_None
;
}
return
old
;
}
/* gets default base */
static
PyObject
*
pggetdefbase
(
PyObject
*
self
,
PyObject
*
args
)
{
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method get_defbase() takes no parameter."
);
return
NULL
;
}
Py_XINCREF
(
pg_default_base
);
return
pg_default_base
;
}
/* sets default base */
static
PyObject
*
pgsetdefbase
(
PyObject
*
self
,
PyObject
*
args
)
{
char
*
temp
=
NULL
;
PyObject
*
old
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"z"
,
&
temp
))
{
PyErr_SetString
(
PyExc_TypeError
,
"set_defbase(name), with name (string/None)."
);
return
NULL
;
}
/* adjusts value */
old
=
pg_default_base
;
if
(
temp
)
pg_default_base
=
PyString_FromString
(
temp
);
else
{
Py_INCREF
(
Py_None
);
pg_default_base
=
Py_None
;
}
return
old
;
}
/* gets default options */
static
PyObject
*
pggetdefopt
(
PyObject
*
self
,
PyObject
*
args
)
{
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method get_defopt() takes no parameter."
);
return
NULL
;
}
Py_XINCREF
(
pg_default_opt
);
return
pg_default_opt
;
}
/* sets default opt */
static
PyObject
*
pgsetdefopt
(
PyObject
*
self
,
PyObject
*
args
)
{
char
*
temp
=
NULL
;
PyObject
*
old
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"z"
,
&
temp
))
{
PyErr_SetString
(
PyExc_TypeError
,
"set_defopt(name), with name (string/None)."
);
return
NULL
;
}
/* adjusts value */
old
=
pg_default_opt
;
if
(
temp
)
pg_default_opt
=
PyString_FromString
(
temp
);
else
{
Py_INCREF
(
Py_None
);
pg_default_opt
=
Py_None
;
}
return
old
;
}
/* gets default tty */
static
PyObject
*
pggetdeftty
(
PyObject
*
self
,
PyObject
*
args
)
{
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method get_deftty() takes no parameter."
);
return
NULL
;
}
Py_XINCREF
(
pg_default_tty
);
return
pg_default_tty
;
}
/* sets default tty */
static
PyObject
*
pgsetdeftty
(
PyObject
*
self
,
PyObject
*
args
)
{
char
*
temp
=
NULL
;
PyObject
*
old
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"z"
,
&
temp
))
{
PyErr_SetString
(
PyExc_TypeError
,
"set_deftty(name), with name (string/None)."
);
return
NULL
;
}
/* adjusts value */
old
=
pg_default_tty
;
if
(
temp
)
pg_default_tty
=
PyString_FromString
(
temp
);
else
{
Py_INCREF
(
Py_None
);
pg_default_tty
=
Py_None
;
}
return
old
;
}
/* gets default username */
static
PyObject
*
pggetdefuser
(
PyObject
*
self
,
PyObject
*
args
)
{
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method get_defuser() takes no parameter."
);
return
NULL
;
}
Py_XINCREF
(
pg_default_user
);
return
pg_default_user
;
}
/* sets default username */
static
PyObject
*
pgsetdefuser
(
PyObject
*
self
,
PyObject
*
args
)
{
char
*
temp
=
NULL
;
PyObject
*
old
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"z"
,
&
temp
))
{
PyErr_SetString
(
PyExc_TypeError
,
"set_defuser(name), with name (string/None)."
);
return
NULL
;
}
/* adjusts value */
old
=
pg_default_user
;
if
(
temp
)
pg_default_user
=
PyString_FromString
(
temp
);
else
{
Py_INCREF
(
Py_None
);
pg_default_user
=
Py_None
;
}
return
old
;
}
/* sets default password */
static
PyObject
*
pgsetdefpasswd
(
PyObject
*
self
,
PyObject
*
args
)
{
char
*
temp
=
NULL
;
PyObject
*
old
;
/* gets arguments */
if
(
!
PyArg_ParseTuple
(
args
,
"z"
,
&
temp
))
{
PyErr_SetString
(
PyExc_TypeError
,
"set_defpasswd(password), with password (string/
None)."
);
return
NULL
;
}
/* adjusts value */
old
=
pg_default_passwd
;
if
(
temp
)
pg_default_passwd
=
PyString_FromString
(
temp
);
else
{
Py_INCREF
(
Py_None
);
pg_default_passwd
=
Py_None
;
}
return
old
;
}
/* gets default port */
static
PyObject
*
pggetdefport
(
PyObject
*
self
,
PyObject
*
args
)
{
/* checks args */
if
(
!
PyArg_ParseTuple
(
args
,
""
))
{
PyErr_SetString
(
PyExc_SyntaxError
,
"method get_defport() takes no parameter."
);
return
NULL
;
}
Py_XINCREF
(
pg_default_port
);
return
pg_default_port
;
}
/* sets default port */
static
PyObject
*
pgsetdefport
(
PyObject
*
self
,
PyObject
*
args
)
{
long
int
port
=
-
2
;
PyObject
*
old
;
/* gets arguments */
if
((
!
PyArg_ParseTuple
(
args
,
"l"
,
&
port
))
||
(
port
<
-
1
))
{
PyErr_SetString
(
PyExc_TypeError
,
"set_defport(port), with port "
"(positive integer/-1)."
);
return
NULL
;
}
/* adjusts value */
old
=
pg_default_port
;
if
(
port
!=
-
1
)
pg_default_port
=
PyLong_FromLong
(
port
);
else
{
Py_INCREF
(
Py_None
);
pg_default_port
=
Py_None
;
}
return
old
;
}
#endif
/* DEFAULT_VARS */
/* List of functions defined in the module */
static
struct
PyMethodDef
pg_methods
[]
=
{
{
"connect"
,
(
PyCFunction
)
pgconnect
,
3
},
/* connect to a database */
#ifdef DEFAULT_VARS
{
"get_defhost"
,
pggetdefhost
,
1
},
/* gets default host */
{
"set_defhost"
,
pgsetdefhost
,
1
},
/* sets default host */
{
"get_defbase"
,
pggetdefbase
,
1
},
/* gets default base */
{
"set_defbase"
,
pgsetdefbase
,
1
},
/* sets default base */
{
"get_defopt"
,
pggetdefopt
,
1
},
/* gets default options */
{
"set_defopt"
,
pgsetdefopt
,
1
},
/* sets default options */
{
"get_deftty"
,
pggetdeftty
,
1
},
/* gets default debug tty */
{
"set_deftty"
,
pgsetdeftty
,
1
},
/* sets default debug tty */
{
"get_defport"
,
pggetdefport
,
1
},
/* gets default port */
{
"set_defport"
,
pgsetdefport
,
1
},
/* sets default port */
{
"get_defuser"
,
pggetdefuser
,
1
},
/* gets default user */
{
"set_defuser"
,
pgsetdefuser
,
1
},
/* sets default user */
{
"set_defpasswd"
,
pgsetdefpasswd
,
1
},
/* sets default passwd */
#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
)
{
PyObject
*
mod
,
*
dict
,
*
v
;
/* Initialize here because some WIN platforms get confused otherwise */
PglargeType
.
ob_type
=
PgType
.
ob_type
=
PgQueryType
.
ob_type
=
&
PyType_Type
;
/* Create the module and add the functions */
mod
=
Py_InitModule4
(
"_pg"
,
pg_methods
,
pg__doc__
,
NULL
,
PYTHON_API_VERSION
);
dict
=
PyModule_GetDict
(
mod
);
/* Add some symbolic constants to the module */
PGError
=
PyString_FromString
(
"pg.error"
);
PyDict_SetItemString
(
dict
,
"error"
,
PGError
);
/* Make the version available */
v
=
PyString_FromString
(
PyPgVersion
);
PyDict_SetItemString
(
dict
,
"version"
,
v
);
PyDict_SetItemString
(
dict
,
"__version__"
,
v
);
Py_DECREF
(
v
);
#ifdef LARGE_OBJECTS
/* create mode for large objects */
PyDict_SetItemString
(
dict
,
"INV_READ"
,
PyInt_FromLong
(
INV_READ
));
PyDict_SetItemString
(
dict
,
"INV_WRITE"
,
PyInt_FromLong
(
INV_WRITE
));
/* position flags for lo_lseek */
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 */
#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 */
/* Check for errors */
if
(
PyErr_Occurred
())
Py_FatalError
(
"can't initialize module _pg"
);
}
src/interfaces/python/pgsqldb.py
0 → 100644
View file @
e55213a5
# 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
)
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