[Zope3-checkins] CVS: Zope3/src/zope/app/sqlexpr -
MAINTAINER.txt:1.1 README.txt:1.1 TODO.txt:1.1
VERSION.txt:1.1 __init__.py:1.1 configure.zcml:1.1 sqlexpr.py:1.1
Philipp von Weitershausen
philikon at philikon.de
Fri Feb 27 09:39:42 EST 2004
Update of /cvs-repository/Zope3/src/zope/app/sqlexpr
In directory cvs.zope.org:/tmp/cvs-serv31077/app/sqlexpr
Added Files:
MAINTAINER.txt README.txt TODO.txt VERSION.txt __init__.py
configure.zcml sqlexpr.py
Log Message:
Moved the sqlexpr package to zope.app.
=== Added File Zope3/src/zope/app/sqlexpr/MAINTAINER.txt ===
Stephan Richter
Email: stephan.richter at tufts.edu
IRC nick: srichter
=== Added File Zope3/src/zope/app/sqlexpr/README.txt ===
SQL TALES Expression
The goal of the SQL TALES expression is to allow quick SQL queries
right out of TALES expressions and Zope Page Templates. While this
is certainly not the Zopeish way of doing things, it allows the
newbie Web scripter an easier entrance to the world of Zope 3.
SQL Expressions behave very similar to String Expressions, but
before they return, they are making an SQL call to the database and
return a ResultSet.
Example 1 - Once you have setup a SQL Connection, you can just use
this connection by setting the variable 'sql_conn'. From then on
this connection is used to execute the SQL statements::
<html tal:define="sql_conn string:psycopg_test">
<body>
<ul>
<li tal:repeat="contact sql: SELECT * FROM contact">
<b tal:content="contact/name" />
</li>
</ul>
</body>
</html>
Example 2 - In case you do not want to deal with any Component
Architecture details at all, then you can simply specify the
connection type and the DSN and the connection is created for you at
runtime::
<html tal:define="rdb string:PsycopgDA; dsn string:dbi://test">
<body>
<ul>
<li tal:repeat="contact sql: SELECT * FROM contact">
<b tal:content="contact/name" />
</li>
</ul>
</body>
</html>
Example 3 - throwing in some variables to make it interesting::
<html tal:define="rdb string:PsycopgDA; dsn string:dbi://test">
<body>
<ul tal:define="name string:Stephan; table string:contact">
<li tal:repeat="
contact sql: SELECT * FROM ${table} WHERE name = '${name}'">
<b tal:content="contact/name" />
</li>
</ul>
</body>
</html>
Installation
Add the following line to products.zcml file::
<include package="zope.app.sqlexpr" />
However, the product is useless unless you install a relational
database adapter or get a Gadfly database setup (the DA for Gadfly
comes with Zope 3).
=== Added File Zope3/src/zope/app/sqlexpr/TODO.txt ===
To Do List
- Implement more advanced tests; boy it took me more time to write the tests
than writing the code.
- Check whether there is a better way of getting the connection name or the
database information. The hard-coded variable names 'sql_conn', 'rdb', and
'dsn' disturb me a bit.
=== Added File Zope3/src/zope/app/sqlexpr/VERSION.txt ===
0.1
=== Added File Zope3/src/zope/app/sqlexpr/__init__.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""SQL Expression Package
$Id: __init__.py,v 1.1 2004/02/27 14:39:41 philikon Exp $
"""
from zope.app.pagetemplate.engine import Engine
from sqlexpr import SQLExpr
# XXX: Almost a classic monkey patch. We really should have a ZCML directive
# for this.
Engine.registerType('sql', SQLExpr)
=== Added File Zope3/src/zope/app/sqlexpr/configure.zcml ===
<configure
xmlns="http://namespaces.zope.org/zope"
i18n_domain="sqlexpr"
>
<!-- Empty configuration file -->
</configure>
=== Added File Zope3/src/zope/app/sqlexpr/sqlexpr.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""SQL Expression Type
$Id: sqlexpr.py,v 1.1 2004/02/27 14:39:41 philikon Exp $
"""
__metaclass__ = type
import re
from zope.component import getService, createObject
from zope.app.rdb import queryForResults
from zope.tales.expressions import NAME_RE
__metaclass__ = type
_interp = re.compile(r'\$(%(n)s)|\${(%(n)s(?:/[^}]*)*)}' % {'n': NAME_RE})
class NoConnectionSpecified(Exception):
pass
class SQLExpr:
"""SQL Expression Handler class
"""
def __init__(self, name, expr, engine):
# Completely taken from StringExpr
self._s = expr
if '%' in expr:
expr = expr.replace('%', '%%')
self._vars = vars = []
if '$' in expr:
# Use whatever expr type is registered as "path".
path_type = engine.getTypes()['path']
parts = []
for exp in expr.split('$$'):
if parts: parts.append('$')
m = _interp.search(exp)
while m is not None:
parts.append(exp[:m.start()])
parts.append('%s')
vars.append(path_type(
'path', m.group(1) or m.group(2), engine))
exp = exp[m.end():]
m = _interp.search(exp)
if '$' in exp:
raise CompilerError, (
'$ must be doubled or followed by a simple path')
parts.append(exp)
expr = ''.join(parts)
self._expr = expr
def __call__(self, econtext):
vvals = []
for var in self._vars:
v = var(econtext)
if isinstance(v, (str, unicode)):
v = sql_quote(v)
vvals.append(v)
if econtext.vars.has_key('sql_conn'):
# XXX: It is hard set that the connection name variable is called
# 'sql_conn'
conn_name = econtext.vars['sql_conn']
connection_service = getService(econtext.context,
"SQLDatabaseConnections")
connection = connection_service.getConnection(conn_name)
elif econtext.vars.has_key('rdb') and econtext.vars.has_key('dsn'):
rdb = econtext.vars['rdb']
dsn = econtext.vars['dsn']
connection = createObject(None, rdb, dsn)()
else:
raise NoConnectionSpecified
query = self._expr % tuple(vvals)
return queryForResults(connection, query)
def __str__(self):
return 'sql expression (%s)' % `self._s`
def __repr__(self):
return '<SQLExpr %s>' % `self._s`
def sql_quote(value):
if value.find("\'") >= 0:
value = "''".join(value.split("\'"))
return "%s" %value
More information about the Zope3-Checkins
mailing list