Replacing/Augmenting dtml-sqltest from a Product?
Please forgive the somewhat naive question. I'm a seasoned C/C++, Java, Perl programmer new to Python and Zope. Hopefully someone can save me a little time. I've modified Shared/DC/ZRDB/sqltest.py and sqlgroup.py to provide some additional semantics that I find very useful. Specifically, I've added range and keyword operations, and comparisons other than equality to sqltest, and I've made a parameterized version of sqlgroup that allows selection of 'and' or 'or' linkages from a variable, making it easier to provide sophisticated search options on a Zope page. I'd like to make these modifications available for public review and comment. The best way I can think of to do this is to make a new Product that provides the new versions and replaces them in DC/ZRDB/DA/SQL. Can anyone give me a brief shortcut on how to do that? I can figure out how to make a Product, but figuring out how to either replace these classes, or to create a duplicate of SQL Method which uses them is not entirely obvious. TIA, -Brad
Bradley McLean wrote:
Please forgive the somewhat naive question. I'm a seasoned C/C++, Java, Perl programmer new to Python and Zope.
GLad to hear it, Perl programmers go much better with seasoning ;^)
Hopefully someone can save me a little time.
I'll try ...
I've modified Shared/DC/ZRDB/sqltest.py and sqlgroup.py to provide some additional semantics that I find very useful. Specifically, I've added range and keyword operations, and comparisons other than equality to sqltest, and I've made a parameterized version of sqlgroup that allows selection of 'and' or 'or' linkages from a variable, making it easier to provide sophisticated search options on a Zope page.
I'd like to make these modifications available for public review and comment.
The best way I can think of to do this is to make a new Product that provides the new versions and replaces them in DC/ZRDB/DA/SQL.
Can anyone give me a brief shortcut on how to do that? I can figure out how to make a Product, but figuring out how to either replace these classes, or to create a duplicate of SQL Method which uses them is not entirely obvious.
TIA,
Personally, I would post a patch to the collector, and to this list (or if patch == large_file: procide URL for download), that way you get DC looking over it, as well as anyone of the rest of us that might like to try it out. Bill Anderson -- "They laughed at Columbus, they laughed at Fulton, they laughed at the Wright brothers. But they also laughed at Bozo the Clown." -- Carl Sagan
Hi, I am creating an object in Zope. I have defined various different values for the object such as url (string) title (string) description (text) But now I want to create a drop down object that has predefined values so the users can select one of the options. There is a property called selection list, and I was unable to find any documentation in how to use it. I tried adding a space seperated values, but it did not work. In the Zope content manager guide on page 42 (pdf version) figure 40 it does not talk about the selection lists. Any help will be appretitated.. Adonis
technews@egsx.com wrote There is a property called selection list, and I was unable to find any documentation in how to use it. I tried adding a space seperated values, but it did not work. In the Zope content manager guide on page 42 (pdf version) figure 40 it does not talk about the selection lists.
easy way: create a property of type 'tokens', specify a bunch of strings, seperated by spaces (e.g. "abc def ghi jkl"). Say you call this token property 'option_choices'. Now define a property, type selection, with a value of 'option_choices'. Voila. the slightly trickier way: make an object that returns a list of strings. Set the value of the new selection property to the name of this object. Done. Anthony
* Bill Anderson (bill.anderson@libc.org) [991118 00:38]:
Personally, I would post a patch to the collector, and to this list (or if patch == large_file: procide URL for download), that way you get DC looking over it, as well as anyone of the rest of us that might like to try it out.
Thanks for the suggestion, Bill. Here it is: --- sqlgroup.py.orig Tue Mar 9 19:15:44 1999 +++ sqlgroup.py Thu Nov 18 17:52:25 1999 @@ -150,7 +150,8 @@ import sys class SQLGroup: - blockContinuations='and','or' + # Brad McLean 11/17/99: Allow a new operator "andor" + blockContinuations='and','or','andor' name='sqlgroup' required=None where=None @@ -172,7 +173,12 @@ __traceback_info__=tname s=strip(section(None, md)) if s: - if r: r.append(tname) + if r: + # Brad McLean 11/17/99: If it's andor tag, use the + # Value of the arguments as the sqljoiner + if tname == 'andor': + r.append(md[args]) + else: r.append(tname) r.append("%s\n" % s) if r: --- sqltest.py.orig Thu Aug 26 13:59:36 1999 +++ sqltest.py Thu Nov 18 17:52:25 1999 @@ -126,6 +126,41 @@ with the appropriate boolean operator, as indicated by use of an 'and' or 'or' tag, otherwise, no text is inserted. + Extensions made 11/17/99 by Brad McLean: + + There is an 'andor' tag which takes a parameter: + <!--#andor operator_variable--> or <dtml-andor operator_variable> + This permits having the user interface present something like: + <select name="operator_variable" size=1> + <option value="or" SELECTED>Or</option> + <option value="and">And</option> + <option value="and not">And Not</option> + </select> + + + Further, sqltest has been extended with 'expr' options: + 'expr' defaults to 'eq' + other values are 'ge','le','lt','gt','rng','kw' + + For 'rng' (range), if a single parameter is given, it devolves to 'eq'. + If two values are provided, then a field test ensuring that the value + lies between the two values (inclusive) is generated. Simply repeat + the same 'name' attribute on two input elements on the calling form; + the first will be taken to be the lower element + + For 'kw' (Keyword), each word provided is searched for. This could + use some further work to allow 'and' semantics as well as 'or', and + phrases would be cool too, but that's future. + + This code works well with MySQL. I think it should work with most + other SQL databases, but I'm not sure. + + Examples: + <dtml-sqltest C.TimeID column=TimeID type=nb expr=eq optional> + <dtml-sqltest C.SizeID column=SizeID type=nb multiple expr=rng optional> + <dtml-sqltest C.Notes column=Notes type=nb multiple expr=kw optional> + + ''' __rcs_id__='$Id: sqltest.py,v 1.10 1999/08/26 17:59:36 jim Exp $' @@ -151,8 +186,9 @@ optional=multiple=None def __init__(self, args): + # Brad McLean 11/17/99: args = parse_params(args, name='', type=None, column=None, - multiple=1, optional=1) + multiple=1, optional=1, expr='') self.__name__ = name_param(args,'sqlvar') has_key=args.has_key if not has_key('type'): @@ -164,6 +200,9 @@ if has_key('multiple'): self.multiple=args['multiple'] if has_key('column'): self.column=args['column'] else: self.column=self.__name__ + # Brad McLean 11/17/99: + if has_key('expr'): self.expr=args['expr'] + else: self.expr = "eq" def render(self, md): name=self.__name__ @@ -201,7 +240,9 @@ 'Invalid floating-point value for <em>%s</em>' % name) else: v=str(v) - v=md.getitem('sql_quote__',0)(v) + # Brad McLean 11/17/99: + if self.expr != 'kw': + v=md.getitem('sql_quote__',0)(v) #if find(v,"\'") >= 0: v=join(split(v,"\'"),"''") #v="'%s'" % v @@ -212,11 +253,55 @@ raise 'Missing Input', ( 'No input was provided for <em>%s</em>' % name) - if len(vs) > 1: - vs=join(map(str,vs),', ') - return "%s in (%s)" % (self.column,vs) - return "%s=%s" % (self.column,vs[0]) + # Brad McLean 11/17/99: Major semantics changes below: + if len(vs) > 1 or self.expr == 'kw': + if self.expr == 'eq': + vs=join(map(str,vs),', ') + return "%s in (%s)" % (self.column,vs) + # Range processing: Must have just two values. Future: + # might want a both inclusive and exclusive options. + elif self.expr == 'rng' and len(vs) == 2: + return "(%s >= %s and %s <= %s)" % (self.column,vs[0],self.column,vs[1]) + # Keyword processing: Split each word into a separate SQL + # clause. This might be rather database specific; perhaps it + # can be parameterized or factored into a helper method somehow. + # Future options might include other operators than 'or', and + # possibly a parser smart enough to handle phrases, etc. + elif self.expr == 'kw': + result = ["("] + for i in vs: + for w in split(i): + result.append("locate(lower(%s),lower(%s))>0" + % (md.getitem('sql_quote__',0)(w),self.column)) + result.append(" or ") + result[-1] = ")" + return join(result) + else: + raise ValueError, ( + 'Wrong Value count for type for <em>%s</em>' % name) + # Single value to a range devolves to a simple eq + # Should there be a table of these per database in case of differing + # operators? + if self.expr == 'eq' or self.expr == 'rng': + return "%s=%s" % (self.column,vs[0]) + elif self.expr == 'lt': + return "%s<%s" % (self.column,vs[0]) + elif self.expr == 'gt': + return "%s>%s" % (self.column,vs[0]) + elif self.expr == 'le': + return "%s<=%s" % (self.column,vs[0]) + elif self.expr == 'ge': + return "%s>=%s" % (self.column,vs[0]) + elif self.expr == 'ne': + return "%s!=%s" % (self.column,vs[0]) + raise ValueError, ( + 'Unknown expr type for <em>%s</em>' % name) __call__=render valid_type={'int':1, 'float':1, 'string':1, 'nb': 1}.has_key + + + + +
At 00:20 19/11/99 , Bradley McLean wrote:
* Bill Anderson (bill.anderson@libc.org) [991118 00:38]:
Personally, I would post a patch to the collector, and to this list (or if patch == large_file: procide URL for download), that way you get DC looking over it, as well as anyone of the rest of us that might like to try it out.
Thanks for the suggestion, Bill. Here it is:
From 2.1.0 beta 1 on, the sqltest tag supports an optional 'op' attribute, which let's you specify what comperisn operator should be used. You can fill in any operator you like, it will use that operator in stead of the '=' sign, or you could specify a keyword from the list 'eq', 'ne', 'lt', 'le', 'lte', 'gt', 'ge' or 'gte', and it will use the appropriate operator that goes with that keyword. Maybe you should try and integrate your changes to the sqltest tag with this operator. Also, did you also file this addition in the Collector (http://classic.zope.org:8080/Collector)? -- Martijn Pieters, Web Developer | Antraciet http://www.antraciet.nl | Tel: +31-35-7502100 Fax: +31-35-7502111 | mailto:mj@antraciet.nl http://www.antraciet.nl/~mj | PGP: http://wwwkeys.nl.pgp.net:11371/pks/lookup?op=get&search=0xA8A32149 ------------------------------------------
participants (5)
-
Anthony Baxter -
Bill Anderson -
Bradley McLean -
Martijn Pieters -
technews@egsx.com