[Zope3-checkins] CVS: zopeproducts/sqlexpr - INSTALL.txt:1.1 LICENSE.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

Stephan Richter srichter@cosmos.phy.tufts.edu
Wed, 11 Jun 2003 00:14:59 -0400


Update of /cvs-repository/zopeproducts/sqlexpr
In directory cvs.zope.org:/tmp/cvs-serv7626/sqlexpr

Added Files:
	INSTALL.txt LICENSE.txt README.txt TODO.txt VERSION.txt 
	__init__.py configure.zcml sqlexpr.py 
Log Message:
This is a little product that adds another TALES expression to page 
templates. SQL expressions allow you to write SQL statements in your page
templates directly without the need for creating new SQL Scripts, 
connection services and database adapters. The used database can be either 
specified with a connection object name or by directly specifying the RDB 
DA and the DSM. See README.txt for detailed examples.

Thanks goes to Alan Runyaga, who tickled the idea out of me today. He was
looking for allowing Zope to be more similar to PHP and other inline 
scripting tools, since they are more familiar to the Web scripter and 
therefore easier to learn.

This product will serve as base for the "Developing a new TALES expression"
recipe in the Zope 3 Developer's Cookbook.


=== Added File zopeproducts/sqlexpr/INSTALL.txt ===
Installation

  This is a usual Zope 3 Product. 

  1. Create 'zopeproducts' inside your Zope 3 installation 'src' directory.

  2. Add an empty '__init__.py' to zopeproducts.

  3. Copy the 'sqlexpr' folder to 'zopeproducts'.

  4. add the following line to products.zcml file::

     <include package='zopeproducts.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 zopeproducts/sqlexpr/LICENSE.txt ===
Zope Public License (ZPL) Version 2.0
-----------------------------------------------

This software is Copyright (c) Zope Corporation (tm) and
Contributors. All rights reserved.

This license has been certified as open source. It has also
been designated as GPL compatible by the Free Software
Foundation (FSF).

Redistribution and use in source and binary forms, with or
without modification, are permitted provided that the
following conditions are met:

1. Redistributions in source code must retain the above
   copyright notice, this list of conditions, and the following
   disclaimer.

2. Redistributions in binary form must reproduce the above
   copyright notice, this list of conditions, and the following
   disclaimer in the documentation and/or other materials
   provided with the distribution.

3. The name Zope Corporation (tm) must not be used to
   endorse or promote products derived from this software
   without prior written permission from Zope Corporation.

4. The right to distribute this software or to use it for
   any purpose does not give you the right to use Servicemarks
   (sm) or Trademarks (tm) of Zope Corporation. Use of them is
   covered in a separate agreement (see
   http://www.zope.com/Marks).

5. If any files are modified, you must cause the modified
   files to carry prominent notices stating that you changed
   the files and the date of any change.

Disclaimer

  THIS SOFTWARE IS PROVIDED BY ZOPE CORPORATION ``AS IS''
  AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
  NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
  NO EVENT SHALL ZOPE CORPORATION OR ITS CONTRIBUTORS BE
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  DAMAGE.


This software consists of contributions made by Zope
Corporation and many individuals on behalf of Zope
Corporation.  Specific attributions are listed in the
accompanying credits file.


=== Added File zopeproducts/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_reg">
      <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>


=== Added File zopeproducts/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 zopeproducts/sqlexpr/VERSION.txt ===
0.1

=== Added File zopeproducts/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 2003/06/11 04:14:58 srichter 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 zopeproducts/sqlexpr/configure.zcml ===
<zopeConfigure
    xmlns="http://namespaces.zope.org/zope">

  <!-- Empty configuration file -->

</zopeConfigure>

=== Added File zopeproducts/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 2003/06/11 04:14:58 srichter Exp $
"""
__metaclass__ = type 

import re
from zope.component import getService, createObject
from zope.app.rdb import queryForResults
from zope.tales.expressions import NAME_RE

_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)
            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`