[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