mirror of https://github.com/postgres/postgres
parent
0bd84442f5
commit
f36e7ff092
@ -0,0 +1,57 @@ |
||||
%define version 3.0 |
||||
%define release pre20000310 |
||||
%define name PyGreSQL |
||||
%define pythonversion 1.5 |
||||
Source: %{name}-%{version}-%{release}.tgz |
||||
Summary: A Python interface for PostgreSQL database. |
||||
Name: %{name} |
||||
Version: %{version} |
||||
Release: %{release} |
||||
#Patch: |
||||
Group: Applications/Databases |
||||
BuildRoot: /tmp/rpmbuild_%{name} |
||||
Copyright: GPL-like |
||||
Requires: python >= %{pythonversion}, postgresql |
||||
Packager: Hartmut Goebel <hartmut@goebel.noris.de> |
||||
Vendor: D'Arcy J.M. Cain <darcy@druid.net> |
||||
URL: http://www.druid.net/pygresql/ |
||||
|
||||
%changelog |
||||
#* Tue Oct 06 1998 Fabio Coatti <cova@felix.unife.it> |
||||
#- fixed installation directory files list |
||||
|
||||
%description |
||||
PyGreSQL is a python module that interfaces to a PostgreSQL database. It |
||||
embeds the PostgreSQL query library to allow easy use of the powerful |
||||
PostgreSQL features from a Python script. |
||||
|
||||
Version 3.0 includes DB-API 2.0 support. |
||||
|
||||
%prep |
||||
rm -rf $RPM_BUILD_ROOT |
||||
|
||||
%setup -n %{name}-%{version}-%{release} |
||||
#%patch |
||||
|
||||
%build |
||||
mkdir -p $RPM_BUILD_ROOT/usr/lib/python%{pythonversion}/lib-dynload |
||||
cc -fpic -shared -o $RPM_BUILD_ROOT/usr/lib/python%{pythonversion}/lib-dynload/_pg.so -I/usr/include/pgsql/ -I/usr/include/python1.5 pgmodule.c -lpq |
||||
## import fails, since _pg is not yet installed |
||||
python -c 'import pg' || true |
||||
python -c 'import pgdb' || true |
||||
|
||||
%install |
||||
cp *.py *.pyc $RPM_BUILD_ROOT/usr/lib/python%{pythonversion}/ |
||||
|
||||
cd $RPM_BUILD_ROOT |
||||
find . -type f | sed 's,^\.,\%attr(-\,root\,root) ,' > $RPM_BUILD_DIR/file.list.%{name} |
||||
find . -type l | sed 's,^\.,\%attr(-\,root\,root) ,' >> $RPM_BUILD_DIR/file.list.%{name} |
||||
|
||||
%files -f ../file.list.%{name} |
||||
%doc %attr(-,root,root) Announce ChangeLog README tutorial |
||||
|
||||
|
||||
%clean |
||||
rm -rf $RPM_BUILD_ROOT |
||||
cd $RPM_BUILD_DIR |
||||
rm -rf %{name}-%{version}-%{release} file.list.%{name} |
@ -0,0 +1,401 @@ |
||||
""" pgdb - DB-SIG compliant module for PygreSQL. |
||||
|
||||
(c) 1999, Pascal Andre <andre@via.ecp.fr>. |
||||
See package documentation for further information on copyright. |
||||
|
||||
Even though this file is distributed with a release version of |
||||
PyGreSQL, this is beta software. Inline documentation is sparse. |
||||
See DB-SIG 2.0 specification for usage information. |
||||
|
||||
basic usage: |
||||
|
||||
pgdb.connect(connect_string) -> connection |
||||
connect_string = 'host:database:user:password:opt:tty' |
||||
All parts are optional. You may also pass host through |
||||
password as keyword arguments. To pass a port, pass it in |
||||
the host keyword parameter: |
||||
pgdb.connect(host='localhost:5432') |
||||
|
||||
connection.cursor() -> cursor |
||||
|
||||
connection.commit() |
||||
|
||||
connection.close() |
||||
|
||||
connection.rollback() |
||||
|
||||
cursor.execute(query[, params]) |
||||
execute a query, binding params (a dictionary) if it is |
||||
passed. The binding syntax is the same as the % operator |
||||
for dictionaries, and no quoting is done. |
||||
|
||||
cursor.executemany(query, list of params) |
||||
execute a query many times, binding each param dictionary |
||||
from the list. |
||||
|
||||
cursor.fetchone() -> [value, value, ...] |
||||
|
||||
cursor.fetchall() -> [[value, value, ...], ...] |
||||
|
||||
cursor.fetchmany([size]) -> [[value, value, ...], ...] |
||||
returns size or cursor.arraysize number of rows from result |
||||
set. Default cursor.arraysize is 1. |
||||
|
||||
cursor.description -> [(column_name, type_name, display_size, |
||||
internal_size, precision, scale, null_ok), ...] |
||||
|
||||
Note that precision, scale and null_ok are not implemented. |
||||
|
||||
cursor.rowcount |
||||
number of rows available in the result set. Available after |
||||
a call to execute. |
||||
|
||||
cursor.close() |
||||
|
||||
""" |
||||
|
||||
import _pg |
||||
import string |
||||
import exceptions |
||||
import types |
||||
import DateTime |
||||
import time |
||||
|
||||
### module constants |
||||
|
||||
# compliant with DB SIG 2.0 |
||||
apilevel = '2.0' |
||||
|
||||
# module may be shared, but not connections |
||||
threadsafety = 1 |
||||
|
||||
# this module use extended python format codes |
||||
paramstyle = 'pyformat' |
||||
|
||||
### exception hierarchy |
||||
|
||||
class Warning(StandardError): |
||||
pass |
||||
|
||||
class Error(StandardError): |
||||
pass |
||||
|
||||
class InterfaceError(Error): |
||||
pass |
||||
|
||||
class DatabaseError(Error): |
||||
pass |
||||
|
||||
class DataError(DatabaseError): |
||||
pass |
||||
|
||||
class OperationalError(DatabaseError): |
||||
pass |
||||
|
||||
class IntegrityError(DatabaseError): |
||||
pass |
||||
|
||||
class InternalError(DatabaseError): |
||||
pass |
||||
|
||||
class ProgrammingError(DatabaseError): |
||||
pass |
||||
|
||||
class NotSupportedError(DatabaseError): |
||||
pass |
||||
|
||||
### internal type handling class |
||||
class pgdbTypeCache: |
||||
|
||||
def __init__(self, cnx): |
||||
self.__source = cnx.source() |
||||
self.__type_cache = {} |
||||
|
||||
def typecast(self, typ, value): |
||||
# for NULL values, no typecast is necessary |
||||
if value == None: |
||||
return value |
||||
|
||||
if typ == STRING: |
||||
pass |
||||
elif typ == BINARY: |
||||
pass |
||||
elif typ == INTEGER: |
||||
value = int(value) |
||||
elif typ == LONG: |
||||
value = long(value) |
||||
elif typ == FLOAT: |
||||
value = float(value) |
||||
elif typ == MONEY: |
||||
value = string.replace(value, "$", "") |
||||
value = string.replace(value, ",", "") |
||||
value = float(value) |
||||
elif typ == DATETIME: |
||||
# format may differ ... we'll give string |
||||
pass |
||||
elif typ == ROWID: |
||||
value = long(value) |
||||
return value |
||||
|
||||
def getdescr(self, oid): |
||||
try: |
||||
return self.__type_cache[oid] |
||||
except: |
||||
self.__source.execute( |
||||
"SELECT typname, typprtlen, typlen " |
||||
"FROM pg_type WHERE oid = %s" % oid |
||||
) |
||||
res = self.__source.fetch(1)[0] |
||||
# column name is omitted from the return value. It will |
||||
# have to be prepended by the caller. |
||||
res = ( |
||||
res[0], |
||||
string.atoi(res[1]), string.atoi(res[2]), |
||||
None, None, None |
||||
) |
||||
self.__type_cache[oid] = res |
||||
return res |
||||
|
||||
### cursor object |
||||
|
||||
class pgdbCursor: |
||||
|
||||
def __init__(self, src, cache): |
||||
self.__cache = cache |
||||
self.__source = src |
||||
self.description = None |
||||
self.rowcount = -1 |
||||
self.arraysize = 5 |
||||
|
||||
def close(self): |
||||
self.__source.close() |
||||
self.description = None |
||||
self.rowcount = -1 |
||||
|
||||
def execute(self, operation, params = None): |
||||
if type(params) == types.TupleType or type(params) == types.ListType: |
||||
self.executemany(operation, params) |
||||
else: |
||||
self.executemany(operation, (params,)) |
||||
|
||||
def executemany(self, operation, param_seq): |
||||
self.description = None |
||||
self.rowcount = -1 |
||||
|
||||
# first try to execute all queries |
||||
totrows = 0 |
||||
sql = "INIT" |
||||
try: |
||||
for params in param_seq: |
||||
if params != None: |
||||
sql = operation % params |
||||
else: |
||||
sql = operation |
||||
rows = self.__source.execute(sql) |
||||
if rows != None: # true is __source is NOT a DQL |
||||
totrows = totrows + rows |
||||
except _pg.error, msg: |
||||
raise DatabaseError, "error '%s' in '%s'" % ( msg, sql ) |
||||
except: |
||||
raise OperationalError, "internal error in '%s'" % sql |
||||
|
||||
# then initialize result raw count and description |
||||
if self.__source.resulttype == _pg.RESULT_DQL: |
||||
self.rowcount = self.__source.ntuples |
||||
d = [] |
||||
for typ in self.__source.listinfo(): |
||||
# listinfo is a sequence of |
||||
# (index, column_name, type_oid) |
||||
# getdescr returns all items needed for a |
||||
# description tuple except the column_name. |
||||
desc = typ[1:2]+self.__cache.getdescr(typ[2]) |
||||
d.append(desc) |
||||
self.description = d |
||||
else: |
||||
self.rowcount = totrows |
||||
self.description = None |
||||
|
||||
def fetchone(self): |
||||
res = self.fetchmany(1, 0) |
||||
try: |
||||
return res[0] |
||||
except: |
||||
return None |
||||
|
||||
def fetchall(self): |
||||
return self.fetchmany(-1, 0) |
||||
|
||||
def fetchmany(self, size = None, keep = 1): |
||||
if size == None: |
||||
size = self.arraysize |
||||
if keep == 1: |
||||
self.arraysize = size |
||||
res = self.__source.fetch(size) |
||||
result = [] |
||||
for r in res: |
||||
row = [] |
||||
for i in range(len(r)): |
||||
row.append(self.__cache.typecast( |
||||
self.description[i][1], |
||||
r[i] |
||||
) |
||||
) |
||||
result.append(row) |
||||
return result |
||||
|
||||
def setinputsizes(self, sizes): |
||||
pass |
||||
|
||||
def setoutputsize(self, size, col = 0): |
||||
pass |
||||
|
||||
### connection object |
||||
|
||||
class pgdbCnx: |
||||
|
||||
def __init__(self, cnx): |
||||
self.__cnx = cnx |
||||
self.__cache = pgdbTypeCache(cnx) |
||||
try: |
||||
src = self.__cnx.source() |
||||
src.execute("BEGIN") |
||||
except: |
||||
raise OperationalError, "invalid connection." |
||||
|
||||
def close(self): |
||||
self.__cnx.close() |
||||
|
||||
def commit(self): |
||||
try: |
||||
src = self.__cnx.source() |
||||
src.execute("COMMIT") |
||||
src.execute("BEGIN") |
||||
except: |
||||
raise OperationalError, "can't commit." |
||||
|
||||
def rollback(self): |
||||
try: |
||||
src = self.__cnx.source() |
||||
src.execute("ROLLBACK") |
||||
src.execute("BEGIN") |
||||
except: |
||||
raise OperationalError, "can't rollback." |
||||
|
||||
def cursor(self): |
||||
try: |
||||
src = self.__cnx.source() |
||||
return pgdbCursor(src, self.__cache) |
||||
except: |
||||
raise pgOperationalError, "invalid connection." |
||||
|
||||
### module interface |
||||
|
||||
# connects to a database |
||||
def connect(dsn = None, user = None, password = None, host = None, database = None): |
||||
# first get params from DSN |
||||
dbport = -1 |
||||
dbhost = "" |
||||
dbbase = "" |
||||
dbuser = "" |
||||
dbpasswd = "" |
||||
dbopt = "" |
||||
dbtty = "" |
||||
try: |
||||
params = string.split(dsn, ":") |
||||
dbhost = params[0] |
||||
dbbase = params[1] |
||||
dbuser = params[2] |
||||
dbpasswd = params[3] |
||||
dbopt = params[4] |
||||
dbtty = params[5] |
||||
except: |
||||
pass |
||||
|
||||
# override if necessary |
||||
if user != None: |
||||
dbuser = user |
||||
if password != None: |
||||
dbpasswd = password |
||||
if database != None: |
||||
dbbase = database |
||||
if host != None: |
||||
try: |
||||
params = string.split(host, ":") |
||||
dbhost = params[0] |
||||
dbport = params[1] |
||||
except: |
||||
pass |
||||
|
||||
# empty host is localhost |
||||
if dbhost == "": |
||||
dbhost = None |
||||
if dbuser == "": |
||||
dbuser = None |
||||
|
||||
# open the connection |
||||
cnx = _pg.connect(host = dbhost, dbname = dbbase, port = dbport, |
||||
opt = dbopt, tty = dbtty, |
||||
user = dbuser, passwd = dbpasswd) |
||||
return pgdbCnx(cnx) |
||||
|
||||
### types handling |
||||
|
||||
# PostgreSQL is object-oriented: types are dynamic. We must thus use type names |
||||
# as internal type codes. |
||||
|
||||
class pgdbType: |
||||
|
||||
def __init__(self, *values): |
||||
self.values= values |
||||
|
||||
def __cmp__(self, other): |
||||
if other in self.values: |
||||
return 0 |
||||
if other < self.values: |
||||
return 1 |
||||
else: |
||||
return -1 |
||||
|
||||
STRING = pgdbType( |
||||
'char', 'name', 'text', 'varchar' |
||||
) |
||||
|
||||
# BLOB support is pg specific |
||||
BINARY = pgdbType() |
||||
INTEGER = pgdbType('int2', 'int4', 'serial') |
||||
LONG = pgdbType('int8') |
||||
FLOAT = pgdbType('float4', 'float8', 'numeric') |
||||
BOOL = pgdbType('bool') |
||||
MONEY = pgdbType('money') |
||||
|
||||
# this may be problematic as type are quite different ... I hope it won't hurt |
||||
DATETIME = pgdbType( |
||||
'abstime', 'reltime', 'tinterval', 'date', 'time', 'timespan', 'timestamp' |
||||
) |
||||
|
||||
# OIDs are used for everything (types, tables, BLOBs, rows, ...). This may cause |
||||
# confusion, but we are unable to find out what exactly is behind the OID (at |
||||
# least not easily enough). Should this be undefined as BLOBs ? |
||||
ROWID = pgdbType( |
||||
'oid', 'oid8' |
||||
) |
||||
|
||||
# mandatory type helpers |
||||
def Date(year, month, day): |
||||
return DateTime.DateTime(year, month, day) |
||||
|
||||
def Time(hour, minute, second): |
||||
return DateTime.TimeDelta(hour, minute, second) |
||||
|
||||
def Timestamp(year, month, day, hour, minute, second): |
||||
return DateTime.DateTime(year, month, day, hour, minute, second) |
||||
|
||||
def DateFromTicks(ticks): |
||||
return apply(Date, time.localtime(ticks)[:3]) |
||||
|
||||
def TimeFromTicks(ticks): |
||||
return apply(Time, time.localtime(ticks)[3:6]) |
||||
|
||||
def TimestampFromTicks(ticks): |
||||
return apply(Timestamp, time.localtime(ticks)[:6]) |
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,46 +0,0 @@ |
||||
# 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 ) |
||||
|
@ -0,0 +1,43 @@ |
||||
#!/usr/bin/env python |
||||
|
||||
include_dirs=['/usr/include/pgsql'] |
||||
library_dirs=['usr/lib/pgsql'] |
||||
optional_libs=['pq'] |
||||
|
||||
# Setup script for the PyGreSQL version 3 |
||||
# created 2000/04 Mark Alexander <mwa@gate.net> |
||||
# tweaked 2000/05 Jeremy Hylton <jeremy@cnri.reston.va.us> |
||||
|
||||
# requires distutils; standard in Python 1.6, otherwise download from |
||||
# http://www.python.org/sigs/distutils-sig/download.html |
||||
|
||||
# You may have to change the first 3 variables (include_dirs, |
||||
# library_dirs, optional_libs) to match your postgres distribution. |
||||
|
||||
# Now, you can: |
||||
# python setup.py build # to build the module |
||||
# python setup.py install # to install it |
||||
|
||||
# See http://www.python.org/sigs/distutils-sig/doc/ for more information |
||||
# on using distutils to install Python programs. |
||||
|
||||
from distutils.core import setup |
||||
|
||||
setup (name = "PyGreSQL", |
||||
version = "3.0", |
||||
description = "Python PostgreSQL Interfaces", |
||||
author = "D'Arcy J. M. Cain", |
||||
author_email = "darcy@druid.net", |
||||
url = "http://www.druid.net/pygresql/", |
||||
licence = "Python", |
||||
|
||||
py_modules = ['pg', 'pgdb'], |
||||
ext_modules = [ ('_pgmodule', { |
||||
'sources': ['pgmodule.c'], |
||||
'include_dirs': include_dirs, |
||||
'library_dirs': library_dirs, |
||||
'libraries': optional_libs |
||||
} |
||||
)] |
||||
) |
||||
|
@ -1,171 +0,0 @@ |
||||
#! /usr/local/bin/python |
||||
# advanced.py - demo of advanced features of PostGres. Some may not be ANSI. |
||||
# inspired from the Postgres tutorial |
||||
# adapted to Python 1995 by Pascal Andre |
||||
|
||||
print "__________________________________________________________________" |
||||
print "MODULE ADVANCED.PY : ADVANCED POSTGRES SQL COMMANDS TUTORIAL" |
||||
print |
||||
print "This module is designed for being imported from python prompt" |
||||
print |
||||
print "In order to run the samples included here, first create a connection" |
||||
print "using : cnx = advanced.DB(...)" |
||||
print "then start the demo with: advanced.demo(cnx)" |
||||
print "__________________________________________________________________" |
||||
|
||||
from pgtools import * |
||||
from pg import DB |
||||
|
||||
# inheritance features |
||||
def inherit_demo(pgcnx): |
||||
print "-----------------------------" |
||||
print "-- Inheritance:" |
||||
print "-- a table can inherit from zero or more tables. A query" |
||||
print "-- can reference either all rows of a table or all rows " |
||||
print "-- of a table plus all of its descendants." |
||||
print "-----------------------------" |
||||
print |
||||
print "-- For example, the capitals table inherits from cities table." |
||||
print "-- (It inherits all data fields from cities.)" |
||||
print |
||||
print "CREATE TABLE cities (" |
||||
print " name text," |
||||
print " population float8," |
||||
print " altitude int" |
||||
print ")" |
||||
print |
||||
print "CREATE TABLE capitals (" |
||||
print " state varchar(2)" |
||||
print ") INHERITS (cities)" |
||||
pgcnx.query("CREATE TABLE cities (" \ |
||||
"name text," \ |
||||
"population float8," \ |
||||
"altitude int)") |
||||
pgcnx.query("CREATE TABLE capitals (" \ |
||||
"state varchar(2)) INHERITS (cities)") |
||||
wait_key() |
||||
print |
||||
print "-- now, let's populate the tables" |
||||
print |
||||
print "INSERT INTO cities VALUES ('San Francisco', 7.24E+5, 63)" |
||||
print "INSERT INTO cities VALUES ('Las Vegas', 2.583E+5, 2174)" |
||||
print "INSERT INTO cities VALUES ('Mariposa', 1200, 1953)" |
||||
print |
||||
print "INSERT INTO capitals VALUES ('Sacramento', 3.694E+5, 30, 'CA')" |
||||
print "INSERT INTO capitals VALUES ('Madison', 1.913E+5, 845, 'WI')" |
||||
print |
||||
pgcnx.query( |
||||
"INSERT INTO cities VALUES ('San Francisco', 7.24E+5, 63)") |
||||
pgcnx.query( |
||||
"INSERT INTO cities VALUES ('Las Vegas', 2.583E+5, 2174)") |
||||
pgcnx.query( |
||||
"INSERT INTO cities VALUES ('Mariposa', 1200, 1953)") |
||||
pgcnx.query("INSERT INTO capitals" \ |
||||
" VALUES ('Sacramento', 3.694E+5, 30, 'CA')") |
||||
pgcnx.query("INSERT INTO capitals" \ |
||||
" VALUES ('Madison', 1.913E+5, 845, 'WI')") |
||||
print |
||||
print "SELECT * FROM cities" |
||||
print pgcnx.query("SELECT * FROM cities") |
||||
print "SELECT * FROM capitals" |
||||
print pgcnx.query("SELECT * FROM capitals") |
||||
print |
||||
print "-- like before, a regular query references rows of the base" |
||||
print "-- table only" |
||||
print |
||||
print "SELECT name, altitude" |
||||
print "FROM cities" |
||||
print "WHERE altitude > 500;" |
||||
print pgcnx.query("SELECT name, altitude " \ |
||||
"FROM cities " \ |
||||
"WHERE altitude > 500") |
||||
print |
||||
print "-- on the other hand, you can find all cities, including " |
||||
print "-- capitals, that are located at an altitude of 500 'ft " |
||||
print "-- or higher by:" |
||||
print |
||||
print "SELECT c.name, c.altitude" |
||||
print "FROM cities* c" |
||||
print "WHERE c.altitude > 500" |
||||
print pgcnx.query("SELECT c.name, c.altitude " \ |
||||
"FROM cities* c " \ |
||||
"WHERE c.altitude > 500") |
||||
|
||||
# arrays attributes |
||||
def array_demo(pgcnx): |
||||
print "----------------------" |
||||
print "-- Arrays:" |
||||
print "-- attributes can be arrays of base types or user-defined " |
||||
print "-- types" |
||||
print "----------------------" |
||||
print |
||||
print "CREATE TABLE sal_emp (" |
||||
print " name text," |
||||
print " pay_by_quarter int4[]," |
||||
print " schedule text[][]" |
||||
print ")" |
||||
pgcnx.query("CREATE TABLE sal_emp (" \ |
||||
"name text," \ |
||||
"pay_by_quarter int4[]," \ |
||||
"schedule text[][])") |
||||
wait_key() |
||||
print |
||||
print "-- insert instances with array attributes. " |
||||
print " Note the use of braces" |
||||
print |
||||
print "INSERT INTO sal_emp VALUES (" |
||||
print " 'Bill'," |
||||
print " '{10000,10000,10000,10000}'," |
||||
print " '{{\"meeting\", \"lunch\"}, {}}')" |
||||
print |
||||
print "INSERT INTO sal_emp VALUES (" |
||||
print " 'Carol'," |
||||
print " '{20000,25000,25000,25000}'," |
||||
print " '{{\"talk\", \"consult\"}, {\"meeting\"}}')" |
||||
print |
||||
pgcnx.query("INSERT INTO sal_emp VALUES (" \ |
||||
"'Bill', '{10000,10000,10000,10000}'," \ |
||||
"'{{\"meeting\", \"lunch\"}, {}}')") |
||||
pgcnx.query("INSERT INTO sal_emp VALUES (" \ |
||||
"'Carol', '{20000,25000,25000,25000}'," \ |
||||
"'{{\"talk\", \"consult\"}, {\"meeting\"}}')") |
||||
wait_key() |
||||
print |
||||
print "----------------------" |
||||
print "-- queries on array attributes" |
||||
print "----------------------" |
||||
print |
||||
print "SELECT name FROM sal_emp WHERE" |
||||
print " sal_emp.pay_by_quarter[1] <> sal_emp.pay_by_quarter[2]" |
||||
print |
||||
print pgcnx.query("SELECT name FROM sal_emp WHERE " \ |
||||
"sal_emp.pay_by_quarter[1] <> sal_emp.pay_by_quarter[2]") |
||||
print |
||||
print "-- retrieve third quarter pay of all employees" |
||||
print |
||||
print "SELECT sal_emp.pay_by_quarter[3] FROM sal_emp" |
||||
print |
||||
print pgcnx.query("SELECT sal_emp.pay_by_quarter[3] FROM sal_emp") |
||||
print |
||||
print "-- select subarrays" |
||||
print |
||||
print "SELECT sal_emp.schedule[1:2][1:1] FROM sal_emp WHERE " |
||||
print " sal_emp.name = 'Bill'" |
||||
print pgcnx.query("SELECT sal_emp.schedule[1:2][1:1] FROM sal_emp WHERE " \ |
||||
"sal_emp.name = 'Bill'") |
||||
|
||||
# base cleanup |
||||
def demo_cleanup(pgcnx): |
||||
print "-- clean up (you must remove the children first)" |
||||
print "DROP TABLE sal_emp" |
||||
print "DROP TABLE capitals" |
||||
print "DROP TABLE cities;" |
||||
pgcnx.query("DROP TABLE sal_emp") |
||||
pgcnx.query("DROP TABLE capitals") |
||||
pgcnx.query("DROP TABLE cities") |
||||
|
||||
# main demo function |
||||
def demo(pgcnx): |
||||
inherit_demo(pgcnx) |
||||
array_demo(pgcnx) |
||||
demo_cleanup(pgcnx) |
@ -1,284 +0,0 @@ |
||||
#! /usr/local/bin/python |
||||
# basics.py - basic SQL commands tutorial |
||||
# inspired from the Postgres95 tutorial |
||||
# adapted to Python 1995 by Pascal ANDRE |
||||
|
||||
print "__________________________________________________________________" |
||||
print "MODULE BASICS.PY : BASIC SQL COMMANDS TUTORIAL" |
||||
print |
||||
print "This module is designed for being imported from python prompt" |
||||
print |
||||
print "In order to run the samples included here, first create a connection" |
||||
print "using : cnx = basics.DB(...)" |
||||
print "then start the demo with: basics.demo(cnx)" |
||||
print "__________________________________________________________________" |
||||
|
||||
from pg import DB |
||||
from pgtools import * |
||||
|
||||
# table creation commands |
||||
def create_table(pgcnx): |
||||
print "-----------------------------" |
||||
print "-- Creating a table:" |
||||
print "-- a CREATE TABLE is used to create base tables. POSTGRES" |
||||
print "-- SQL has its own set of built-in types. (Note that" |
||||
print "-- keywords are case-insensitive but identifiers are " |
||||
print "-- case-sensitive.)" |
||||
print "-----------------------------" |
||||
print |
||||
print "Sending query :" |
||||
print "CREATE TABLE weather (" |
||||
print " city varchar(80)," |
||||
print " temp_lo int," |
||||
print " temp_hi int," |
||||
print " prcp float8," |
||||
print " date date" |
||||
print ")" |
||||
pgcnx.query("CREATE TABLE weather (city varchar(80), temp_lo int," \ |
||||
"temp_hi int, prcp float8, date date)") |
||||
print |
||||
print "Sending query :" |
||||
print "CREATE TABLE cities (" |
||||
print " name varchar(80)," |
||||
print " location point" |
||||
print ")" |
||||
pgcnx.query("CREATE TABLE cities (" \ |
||||
"name varchar(80)," \ |
||||
"location point)") |
||||
|
||||
# data insertion commands |
||||
def insert_data(pgcnx): |
||||
print "-----------------------------" |
||||
print "-- Inserting data:" |
||||
print "-- an INSERT statement is used to insert a new row into" |
||||
print "-- a table. There are several ways you can specify what" |
||||
print "-- columns the data should go to." |
||||
print "-----------------------------" |
||||
print |
||||
print "-- 1. the simplest case is when the list of value correspond to" |
||||
print "-- the order of the columns specified in CREATE TABLE." |
||||
print |
||||
print "Sending query :" |
||||
print "INSERT INTO weather " |
||||
print " VALUES ('San Francisco', 46, 50, 0.25, '11/27/1994')" |
||||
pgcnx.query("INSERT INTO weather " \ |
||||
"VALUES ('San Francisco', 46, 50, 0.25, '11/27/1994')") |
||||
print |
||||
print "Sending query :" |
||||
print "INSERT INTO cities " |
||||
print " VALUES ('San Francisco', '(-194.0, 53.0)')" |
||||
pgcnx.query("INSERT INTO cities " \ |
||||
"VALUES ('San Francisco', '(-194.0, 53.0)')") |
||||
print |
||||
wait_key() |
||||
print "-- 2. you can also specify what column the values correspond " |
||||
print " to. (The columns can be specified in any order. You may " |
||||
print " also omit any number of columns. eg. unknown precipitation" |
||||
print " below)" |
||||
print "Sending query :" |
||||
print "INSERT INTO weather (city, temp_lo, temp_hi, prcp, date)" |
||||
print " VALUES ('San Francisco', 43, 57, 0.0, '11/29/1994')" |
||||
pgcnx.query("INSERT INTO weather (date, city, temp_hi, temp_lo)" \ |
||||
"VALUES ('11/29/1994', 'Hayward', 54, 37)") |
||||
|
||||
# direct selection commands |
||||
def select_data1(pgcnx): |
||||
print "-----------------------------" |
||||
print "-- Retrieving data:" |
||||
print "-- a SELECT statement is used for retrieving data. The " |
||||
print "-- basic syntax is:" |
||||
print "-- SELECT columns FROM tables WHERE predicates" |
||||
print "-----------------------------" |
||||
print |
||||
print "-- a simple one would be the query:" |
||||
print "SELECT * FROM weather" |
||||
print |
||||
print "The result is :" |
||||
q = pgcnx.query("SELECT * FROM weather") |
||||
print q |
||||
print |
||||
print "-- you may also specify expressions in the target list (the " |
||||
print "-- 'AS column' specifies the column name of the result. It is " |
||||
print "-- optional.)" |
||||
print "The query :" |
||||
print " SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date " |
||||
print " FROM weather" |
||||
print "Gives :" |
||||
print pgcnx.query("SELECT city, (temp_hi+temp_lo)/2 " \ |
||||
"AS temp_avg, date FROM weather") |
||||
print |
||||
print "-- if you want to retrieve rows that satisfy certain condition" |
||||
print "-- (ie. a restriction), specify the condition in WHERE. The " |
||||
print "-- following retrieves the weather of San Francisco on rainy " |
||||
print "-- days." |
||||
print "SELECT *" |
||||
print "FROM weather" |
||||
print "WHERE city = 'San Francisco' " |
||||
print " and prcp > 0.0" |
||||
print pgcnx.query("SELECT * FROM weather WHERE city = 'San Francisco'" \ |
||||
" AND prcp > 0.0") |
||||
print |
||||
print "-- here is a more complicated one. Duplicates are removed when " |
||||
print "-- DISTINCT is specified. ORDER BY specifies the column to sort" |
||||
print "-- on. (Just to make sure the following won't confuse you, " |
||||
print "-- DISTINCT and ORDER BY can be used separately.)" |
||||
print "SELECT DISTINCT city" |
||||
print "FROM weather" |
||||
print "ORDER BY city;" |
||||
print pgcnx.query("SELECT DISTINCT city FROM weather ORDER BY city") |
||||
|
||||
# selection to a temporary table |
||||
def select_data2(pgcnx): |
||||
print "-----------------------------" |
||||
print "-- Retrieving data into other classes:" |
||||
print "-- a SELECT ... INTO statement can be used to retrieve " |
||||
print "-- data into another class." |
||||
print "-----------------------------" |
||||
print |
||||
print "The query :" |
||||
print "SELECT * INTO TABLE temp " |
||||
print "FROM weather" |
||||
print "WHERE city = 'San Francisco' " |
||||
print " and prcp > 0.0" |
||||
pgcnx.query("SELECT * INTO TABLE temp FROM weather " \ |
||||
"WHERE city = 'San Francisco' and prcp > 0.0") |
||||
print "Fills the table temp, that can be listed with :" |
||||
print "SELECT * from temp" |
||||
print pgcnx.query("SELECT * from temp") |
||||
|
||||
# aggregate creation commands |
||||
def create_aggregate(pgcnx): |
||||
print "-----------------------------" |
||||
print "-- Aggregates" |
||||
print "-----------------------------" |
||||
print |
||||
print "Let's consider the query :" |
||||
print "SELECT max(temp_lo)" |
||||
print "FROM weather;" |
||||
print pgcnx.query("SELECT max(temp_lo) FROM weather") |
||||
print |
||||
print "-- Aggregate with GROUP BY" |
||||
print "SELECT city, max(temp_lo)" |
||||
print "FROM weather " |
||||
print "GROUP BY city;" |
||||
print pgcnx.query( "SELECT city, max(temp_lo)" \ |
||||
"FROM weather GROUP BY city") |
||||
|
||||
# table join commands |
||||
def join_table(pgcnx): |
||||
print "-----------------------------" |
||||
print "-- Joining tables:" |
||||
print "-- queries can access multiple tables at once or access" |
||||
print "-- the same table in such a way that multiple instances" |
||||
print "-- of the table are being processed at the same time." |
||||
print "-----------------------------" |
||||
print |
||||
print "-- suppose we want to find all the records that are in the " |
||||
print "-- temperature range of other records. W1 and W2 are aliases " |
||||
print "--for weather." |
||||
print |
||||
print "SELECT W1.city, W1.temp_lo, W1.temp_hi, " |
||||
print " W2.city, W2.temp_lo, W2.temp_hi" |
||||
print "FROM weather W1, weather W2" |
||||
print "WHERE W1.temp_lo < W2.temp_lo " |
||||
print " and W1.temp_hi > W2.temp_hi" |
||||
print |
||||
print pgcnx.query("SELECT W1.city, W1.temp_lo, W1.temp_hi, " \ |
||||
"W2.city, W2.temp_lo, W2.temp_hi FROM weather W1, weather W2 "\ |
||||
"WHERE W1.temp_lo < W2.temp_lo and W1.temp_hi > W2.temp_hi") |
||||
print |
||||
print "-- let's join two tables. The following joins the weather table" |
||||
print "-- and the cities table." |
||||
print |
||||
print "SELECT city, location, prcp, date" |
||||
print "FROM weather, cities" |
||||
print "WHERE name = city" |
||||
print |
||||
print pgcnx.query("SELECT city, location, prcp, date FROM weather, cities"\ |
||||
" WHERE name = city") |
||||
print |
||||
print "-- since the column names are all different, we don't have to " |
||||
print "-- specify the table name. If you want to be clear, you can do " |
||||
print "-- the following. They give identical results, of course." |
||||
print |
||||
print "SELECT w.city, c.location, w.prcp, w.date" |
||||
print "FROM weather w, cities c" |
||||
print "WHERE c.name = w.city;" |
||||
print |
||||
print pgcnx.query("SELECT w.city, c.location, w.prcp, w.date " \ |
||||
"FROM weather w, cities c WHERE c.name = w.city") |
||||
|
||||
# data updating commands |
||||
def update_data(pgcnx): |
||||
print "-----------------------------" |
||||
print "-- Updating data:" |
||||
print "-- an UPDATE statement is used for updating data. " |
||||
print "-----------------------------" |
||||
print |
||||
print "-- suppose you discover the temperature readings are all off by" |
||||
print "-- 2 degrees as of Nov 28, you may update the data as follow:" |
||||
print |
||||
print "UPDATE weather" |
||||
print " SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2" |
||||
print " WHERE date > '11/28/1994'" |
||||
print |
||||
pgcnx.query("UPDATE weather " \ |
||||
"SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2" \ |
||||
"WHERE date > '11/28/1994'") |
||||
print |
||||
print "SELECT * from weather" |
||||
print pgcnx.query("SELECT * from weather") |
||||
|
||||
# data deletion commands |
||||
def delete_data(pgcnx): |
||||
print "-----------------------------" |
||||
print "-- Deleting data:" |
||||
print "-- a DELETE statement is used for deleting rows from a " |
||||
print "-- table." |
||||
print "-----------------------------" |
||||
print |
||||
print "-- suppose you are no longer interested in the weather of " |
||||
print "-- Hayward, you can do the following to delete those rows from" |
||||
print "-- the table" |
||||
print |
||||
print "DELETE FROM weather WHERE city = 'Hayward'" |
||||
pgcnx.query("DELETE FROM weather WHERE city = 'Hayward'") |
||||
print |
||||
print "SELECT * from weather" |
||||
print |
||||
print pgcnx.query("SELECT * from weather") |
||||
print |
||||
print "-- you can also delete all the rows in a table by doing the " |
||||
print "-- following. (This is different from DROP TABLE which removes " |
||||
print "-- the table in addition to the removing the rows.)" |
||||
print |
||||
print "DELETE FROM weather" |
||||
pgcnx.query("DELETE FROM weather") |
||||
print |
||||
print "SELECT * from weather" |
||||
print pgcnx.query("SELECT * from weather") |
||||
|
||||
# table removal commands |
||||
def remove_table(pgcnx): |
||||
print "-----------------------------" |
||||
print "-- Removing the tables:" |
||||
print "-- DROP TABLE is used to remove tables. After you have" |
||||
print "-- done this, you can no longer use those tables." |
||||
print "-----------------------------" |
||||
print |
||||
print "DROP TABLE weather, cities, temp" |
||||
pgcnx.query("DROP TABLE weather, cities, temp") |
||||
|
||||
# main demo function |
||||
def demo(pgcnx): |
||||
create_table(pgcnx) |
||||
wait_key() |
||||
insert_data(pgcnx) |
||||
wait_key() |
||||
select_data1(pgcnx) |
||||
select_data2(pgcnx) |
||||
create_aggregate(pgcnx) |
||||
join_table(pgcnx) |
||||
update_data(pgcnx) |
||||
delete_data(pgcnx) |
||||
remove_table(pgcnx) |
@ -1,193 +0,0 @@ |
||||
# func.py - demonstrate the use of SQL functions |
||||
# inspired from the PostgreSQL tutorial |
||||
# adapted to Python 1995 by Pascal ANDRE |
||||
|
||||
print "__________________________________________________________________" |
||||
print "MODULE FUNC.PY : SQL FUNCTION DEFINITION TUTORIAL" |
||||
print |
||||
print "This module is designed for being imported from python prompt" |
||||
print |
||||
print "In order to run the samples included here, first create a connection" |
||||
print "using : cnx = func.DB(...)" |
||||
print "then start the demo with: func.demo(cnx)" |
||||
print "__________________________________________________________________" |
||||
|
||||
from pgtools import * |
||||
from pg import DB |
||||
|
||||
# basic functions declaration |
||||
def base_func(pgcnx): |
||||
print "-----------------------------" |
||||
print "-- Creating SQL Functions on Base Types" |
||||
print "-- a CREATE FUNCTION statement lets you create a new " |
||||
print "-- function that can be used in expressions (in SELECT, " |
||||
print "-- INSERT, etc.). We will start with functions that " |
||||
print "-- return values of base types." |
||||
print "-----------------------------" |
||||
print |
||||
print "--" |
||||
print "-- let's create a simple SQL function that takes no arguments" |
||||
print "-- and returns 1" |
||||
print |
||||
print "CREATE FUNCTION one() RETURNS int4" |
||||
print " AS 'SELECT 1 as ONE' LANGUAGE 'sql'" |
||||
pgcnx.query("CREATE FUNCTION one() RETURNS int4 " \ |
||||
"AS 'SELECT 1 as ONE' LANGUAGE 'sql'") |
||||
wait_key() |
||||
print |
||||
print "--" |
||||
print "-- functions can be used in any expressions (eg. in the target" |
||||
print "-- list or qualifications)" |
||||
print |
||||
print "SELECT one() AS answer" |
||||
print pgcnx.query("SELECT one() AS answer") |
||||
print |
||||
print "--" |
||||
print "-- here's how you create a function that takes arguments. The" |
||||
print "-- following function returns the sum of its two arguments:" |
||||
print |
||||
print "CREATE FUNCTION add_em(int4, int4) RETURNS int4" |
||||
print " AS 'SELECT $1 + $2' LANGUAGE 'sql'" |
||||
pgcnx.query("CREATE FUNCTION add_em(int4, int4) RETURNS int4 " \ |
||||
"AS 'SELECT $1 + $2' LANGUAGE 'sql'") |
||||
print |
||||
print "SELECT add_em(1, 2) AS answer" |
||||
print pgcnx.query("SELECT add_em(1, 2) AS answer") |
||||
|
||||
# functions on composite types |
||||
def comp_func(pgcnx): |
||||
print "-----------------------------" |
||||
print "-- Creating SQL Functions on Composite Types" |
||||
print "-- it is also possible to create functions that return" |
||||
print "-- values of composite types." |
||||
print "-----------------------------" |
||||
print |
||||
print "-- before we create more sophisticated functions, let's " |
||||
print "-- populate an EMP table" |
||||
print |
||||
print "CREATE TABLE EMP (" |
||||
print " name text," |
||||
print " salary int4," |
||||
print " age int4," |
||||
print " dept varchar(16)" |
||||
print ")" |
||||
pgcnx.query("CREATE TABLE EMP (" \ |
||||
"name text," \ |
||||
"salary int4," \ |
||||
"age int4," \ |
||||
"dept varchar(16))") |
||||
print |
||||
print "INSERT INTO EMP VALUES ('Sam', 1200, 16, 'toy')" |
||||
print "INSERT INTO EMP VALUES ('Claire', 5000, 32, 'shoe')" |
||||
print "INSERT INTO EMP VALUES ('Andy', -1000, 2, 'candy')" |
||||
print "INSERT INTO EMP VALUES ('Bill', 4200, 36, 'shoe')" |
||||
print "INSERT INTO EMP VALUES ('Ginger', 4800, 30, 'candy')" |
||||
pgcnx.query("INSERT INTO EMP VALUES ('Sam', 1200, 16, 'toy')") |
||||
pgcnx.query("INSERT INTO EMP VALUES ('Claire', 5000, 32, 'shoe')") |
||||
pgcnx.query("INSERT INTO EMP VALUES ('Andy', -1000, 2, 'candy')") |
||||
pgcnx.query("INSERT INTO EMP VALUES ('Bill', 4200, 36, 'shoe')") |
||||
pgcnx.query("INSERT INTO EMP VALUES ('Ginger', 4800, 30, 'candy')") |
||||
wait_key() |
||||
print |
||||
print "-- the argument of a function can also be a tuple. For " |
||||
print "-- instance, double_salary takes a tuple of the EMP table" |
||||
print |
||||
print "CREATE FUNCTION double_salary(EMP) RETURNS int4" |
||||
print " AS 'SELECT $1.salary * 2 AS salary' LANGUAGE 'sql'" |
||||
pgcnx.query("CREATE FUNCTION double_salary(EMP) RETURNS int4 " \ |
||||
"AS 'SELECT $1.salary * 2 AS salary' LANGUAGE 'sql'") |
||||
print |
||||
print "SELECT name, double_salary(EMP) AS dream" |
||||
print "FROM EMP" |
||||
print "WHERE EMP.dept = 'toy'" |
||||
print pgcnx.query("SELECT name, double_salary(EMP) AS dream " \ |
||||
"FROM EMP WHERE EMP.dept = 'toy'") |
||||
print |
||||
print "-- the return value of a function can also be a tuple. However," |
||||
print "-- make sure that the expressions in the target list is in the " |
||||
print "-- same order as the columns of EMP." |
||||
print |
||||
print "CREATE FUNCTION new_emp() RETURNS EMP" |
||||
print " AS 'SELECT \'None\'::text AS name," |
||||
print " 1000 AS salary," |
||||
print " 25 AS age," |
||||
print " \'none\'::varchar(16) AS dept'" |
||||
print " LANGUAGE 'sql'" |
||||
pgcnx.query("CREATE FUNCTION new_emp() RETURNS EMP " \ |
||||
"AS 'SELECT \\\'None\\\'::text AS name, " \ |
||||
"1000 AS salary, " \ |
||||
"25 AS age, " \ |
||||
"\\\'none\\\'::varchar(16) AS dept' " \ |
||||
"LANGUAGE 'sql'") |
||||
wait_key() |
||||
print |
||||
print "-- you can then project a column out of resulting the tuple by" |
||||
print "-- using the \"function notation\" for projection columns. " |
||||
print "-- (ie. bar(foo) is equivalent to foo.bar) Note that we don't" |
||||
print "-- support new_emp().name at this moment." |
||||
print |
||||
print "SELECT name(new_emp()) AS nobody" |
||||
print pgcnx.query("SELECT name(new_emp()) AS nobody") |
||||
print |
||||
print "-- let's try one more function that returns tuples" |
||||
print "CREATE FUNCTION high_pay() RETURNS setof EMP" |
||||
print " AS 'SELECT * FROM EMP where salary > 1500'" |
||||
print " LANGUAGE 'sql'" |
||||
pgcnx.query("CREATE FUNCTION high_pay() RETURNS setof EMP " \ |
||||
"AS 'SELECT * FROM EMP where salary > 1500' " \ |
||||
"LANGUAGE 'sql'") |
||||
print |
||||
print "SELECT name(high_pay()) AS overpaid" |
||||
print pgcnx.query("SELECT name(high_pay()) AS overpaid") |
||||
|
||||
# function with multiple SQL commands |
||||
def mult_func(pgcnx): |
||||
print "-----------------------------" |
||||
print "-- Creating SQL Functions with multiple SQL statements" |
||||
print "-- you can also create functions that do more than just a" |
||||
print "-- SELECT." |
||||
print "-----------------------------" |
||||
print |
||||
print "-- you may have noticed that Andy has a negative salary. We'll" |
||||
print "-- create a function that removes employees with negative " |
||||
print "-- salaries." |
||||
print |
||||
print "SELECT * FROM EMP" |
||||
print pgcnx.query("SELECT * FROM EMP") |
||||
print |
||||
print "CREATE FUNCTION clean_EMP () RETURNS int4" |
||||
print " AS 'DELETE FROM EMP WHERE EMP.salary <= 0" |
||||
print " SELECT 1 AS ignore_this'" |
||||
print " LANGUAGE 'sql'" |
||||
pgcnx.query("CREATE FUNCTION clean_EMP () RETURNS int4 AS 'DELETE FROM EMP WHERE EMP.salary <= 0; SELECT 1 AS ignore_this' LANGUAGE 'sql'") |
||||
print |
||||
print "SELECT clean_EMP()" |
||||
print pgcnx.query("SELECT clean_EMP()") |
||||
print |
||||
print "SELECT * FROM EMP" |
||||
print pgcnx.query("SELECT * FROM EMP") |
||||
|
||||
# base cleanup |
||||
def demo_cleanup(pgcnx): |
||||
print "-- remove functions that were created in this file" |
||||
print |
||||
print "DROP FUNCTION clean_EMP()" |
||||
print "DROP FUNCTION high_pay()" |
||||
print "DROP FUNCTION new_emp()" |
||||
print "DROP FUNCTION add_em(int4, int4)" |
||||
print "DROP FUNCTION one()" |
||||
print |
||||
print "DROP TABLE EMP" |
||||
pgcnx.query("DROP FUNCTION clean_EMP()") |
||||
pgcnx.query("DROP FUNCTION high_pay()") |
||||
pgcnx.query("DROP FUNCTION new_emp()") |
||||
pgcnx.query("DROP FUNCTION add_em(int4, int4)") |
||||
pgcnx.query("DROP FUNCTION one()") |
||||
pgcnx.query("DROP TABLE EMP") |
||||
|
||||
# main demo function |
||||
def demo(pgcnx): |
||||
base_func(pgcnx) |
||||
comp_func(pgcnx) |
||||
mult_func(pgcnx) |
||||
demo_cleanup(pgcnx) |
@ -1,48 +0,0 @@ |
||||
#! /usr/local/bin/python |
||||
# pgtools.py - valuable functions for PostGreSQL tutorial |
||||
# written 1995 by Pascal ANDRE |
||||
|
||||
import sys |
||||
|
||||
# number of rows |
||||
scr_size = 24 |
||||
|
||||
# waits for a key |
||||
def wait_key(): |
||||
print "Press <enter>" |
||||
sys.stdin.read(1) |
||||
|
||||
# displays a table for a select query result |
||||
def display(fields, result): |
||||
print result |
||||
# gets cols width |
||||
fmt = [] |
||||
sep = '+' |
||||
head = '|' |
||||
for i in range(0, len(fields)): |
||||
max = len(fields[i]) |
||||
for j in range(0, len(result)): |
||||
if i < len(result[j]): |
||||
if len(result[j][i]) > max: |
||||
max = len(result[j][i]) |
||||
fmt.append(" %%%ds |" % max) |
||||
for j in range(0, max): |
||||
sep = sep + '-' |
||||
sep = sep + '--+' |
||||
for i in range(0, len(fields)): |
||||
head = head + fmt[i] % fields[i] |
||||
print sep + '\n' + head + '\n' + sep |
||||
pos = 6 |
||||
for i in range(0, len(result)): |
||||
str = '|' |
||||
for j in range(0, len(result[i])): |
||||
str = str + fmt[j] % result[i][j] |
||||
print str |
||||
pos = pos + 1 |
||||
if pos == scr_size: |
||||
print sep |
||||
wait_key() |
||||
print sep + '\n' + head + '\n' + sep |
||||
pos = 6 |
||||
print sep |
||||
wait_key() |
@ -1,133 +0,0 @@ |
||||
# syscat.py - parses some system catalogs |
||||
# inspired from the PostgreSQL tutorial |
||||
# adapted to Python 1995 by Pascal ANDRE |
||||
|
||||
print "____________________________________________________________________" |
||||
print |
||||
print "MODULE SYSCAT.PY : PARSES SOME POSTGRESQL SYSTEM CATALOGS" |
||||
print |
||||
print "This module is designed for being imported from python prompt" |
||||
print |
||||
print "In order to run the samples included here, first create a connection" |
||||
print "using : cnx = syscat.DB(...)" |
||||
print "then start the demo with: syscat.demo(cnx)" |
||||
print |
||||
print "Some results may be empty, depending on your base status." |
||||
print |
||||
print "____________________________________________________________________" |
||||
print |
||||
|
||||
from pg import DB |
||||
from pgtools import * |
||||
|
||||
# lists all simple indices |
||||
def list_simple_ind(pgcnx): |
||||
result = pgcnx.query("select bc.relname " \ |
||||
"as class_name, ic.relname as index_name, a.attname " \ |
||||
"from pg_class bc, pg_class ic, pg_index i, pg_attribute a " \ |
||||
"where i.indrelid = bc.oid and i.indexrelid = bc.oid " \ |
||||
" and i.indkey[0] = a.attnum and a.attrelid = bc.oid " \ |
||||
" and i.indproc = '0'::oid " \ |
||||
"order by class_name, index_name, attname") |
||||
return result |
||||
|
||||
# list all user defined attributes and their type in user-defined classes |
||||
def list_all_attr(pgcnx): |
||||
result = pgcnx.query("select c.relname, a.attname, t.typname " \ |
||||
"from pg_class c, pg_attribute a, pg_type t " \ |
||||
"where c.relkind = 'r' and c.relname !~ '^pg_' " \ |
||||
" and c.relname !~ '^Inv' and a.attnum > 0 " \ |
||||
" and a.attrelid = c.oid and a.atttypid = t.oid " \ |
||||
"order by relname, attname") |
||||
return result |
||||
|
||||
# list all user defined base type |
||||
def list_user_base_type(pgcnx): |
||||
result = pgcnx.query("select u.usename, t.typname " \ |
||||
"from pg_type t, pg_user u " \ |
||||
"where u.usesysid = int2in(int4out(t.typowner)) " \ |
||||
" and t.typrelid = '0'::oid and t.typelem = '0'::oid " \ |
||||
" and u.usename <> 'postgres' order by usename, typname") |
||||
return result |
||||
|
||||
# list all right-unary operators |
||||
def list_right_unary_operator(pgcnx): |
||||
result = pgcnx.query("select o.oprname as right_unary, " \ |
||||
" lt.typname as operand, result.typname as return_type " \ |
||||
"from pg_operator o, pg_type lt, pg_type result " \ |
||||
"where o.oprkind='r' and o.oprleft = lt.oid " \ |
||||
" and o.oprresult = result.oid order by operand") |
||||
return result |
||||
|
||||
# list all left-unary operators |
||||
def list_left_unary_operator(pgcnx): |
||||
result = pgcnx.query("select o.oprname as left_unary, " \ |
||||
" rt.typname as operand, result.typname as return_type " \ |
||||
"from pg_operator o, pg_type rt, pg_type result " \ |
||||
"where o.oprkind='l' and o.oprright = rt.oid " \ |
||||
" and o.oprresult = result.oid order by operand") |
||||
return result |
||||
|
||||
# list all binary operators |
||||
def list_binary_operator(pgcnx): |
||||
result = pgcnx.query("select o.oprname as binary_op, " \ |
||||
" rt.typname as right_opr, lt.typname as left_opr, " \ |
||||
" result.typname as return_type " \ |
||||
"from pg_operator o, pg_type rt, pg_type lt, pg_type result " \ |
||||
"where o.oprkind = 'b' and o.oprright = rt.oid " \ |
||||
" and o.oprleft = lt.oid and o.oprresult = result.oid") |
||||
return result |
||||
|
||||
# returns the name, args and return type from all function of lang l |
||||
def list_lang_func(pgcnx, l): |
||||
result = pgcnx.query("select p.proname, p.pronargs, t.typname " \ |
||||
"from pg_proc p, pg_language l, pg_type t " \ |
||||
"where p.prolang = l.oid and p.prorettype = t.oid " \ |
||||
" and l.lanname = '%s' order by proname" % l) |
||||
return result |
||||
|
||||
# lists all the aggregate functions and the type to which they can be applied |
||||
def list_agg_func(pgcnx): |
||||
result = pgcnx.query("select a.aggname, t.typname " \ |
||||
"from pg_aggregate a, pg_type t " \ |
||||
"where a.aggbasetype = t.oid order by aggname, typname") |
||||
return result |
||||
|
||||
# lists all the operator classes that can be used with each access method as |
||||
# well as the operators that can be used with the respective operator classes |
||||
def list_op_class(pgcnx): |
||||
result = pgcnx.query("select am.amname, opc.opcname, opr.oprname " \ |
||||
"from pg_am am, pg_amop amop, pg_opclass opc, pg_operator opr " \ |
||||
"where amop.amopid = am.oid and amop.amopclaid = opc.oid " \ |
||||
" and amop.amopopr = opr.oid order by amname, opcname, oprname") |
||||
return result |
||||
|
||||
# demo function - runs all examples |
||||
def demo(pgcnx): |
||||
#import sys, os |
||||
#save_stdout = sys.stdout |
||||
#sys.stdout = os.popen("more", "w") |
||||
print "Listing simple indices ..." |
||||
print list_simple_ind(pgcnx) |
||||
print "Listing all attributes ..." |
||||
print list_all_attr(pgcnx) |
||||
print "Listing all user-defined base types ..." |
||||
print list_user_base_type(pgcnx) |
||||
print "Listing all left-unary operators defined ..." |
||||
print list_left_unary_operator(pgcnx) |
||||
print "Listing all right-unary operators defined ..." |
||||
print list_right_unary_operator(pgcnx) |
||||
print "Listing all binary operators ..." |
||||
print list_binary_operator(pgcnx) |
||||
print "Listing C external function linked ..." |
||||
print list_lang_func(pgcnx, 'C') |
||||
print "Listing C internal functions ..." |
||||
print list_lang_func(pgcnx, 'internal') |
||||
print "Listing SQL functions defined ..." |
||||
print list_lang_func(pgcnx, 'sql') |
||||
print "Listing 'aggregate functions' ..." |
||||
print list_agg_func(pgcnx) |
||||
print "Listing 'operator classes' ..." |
||||
print list_op_class(pgcnx) |
||||
#del sys.stdout |
||||
#sys.stdout = save_stdout |
Loading…
Reference in new issue