dabo Commit
Revision 1520
Date: 2005-11-05 10:34:14 -0800 (Sat, 05 Nov 2005)
Author: ed
Changed:
U trunk/dabo/db/dCursorMixin.py
Log:
Added a 'replace' function to the DataSet. It uses the syntax:
DataSet.replace(field, valOrExpr, scope)
'valOrExpr' is treated as a literal value, unless its first character is '='.
Then it is treated as an expression, allowing for more complex replace
statements.
Example:
DataSet.replace("lastname", "=lastname.title()")
=> this will replace all the last name fields with their values changed
to Title caps.
DataSet.replace("lastname", "lastname.title()")
=> this will replace all the last name fields with the literal string
'lastname.title()'. Since valOrExpr didn't begin with '=', it was treated as a
literal value.
DataSet.replace("lastname", "Smith", "phone.endswith('9952')"
=> this will replace the lastname field with "Smith" in every record
where the phone number ends in '9952'
Diff:
Modified: trunk/dabo/db/dCursorMixin.py
===================================================================
--- trunk/dabo/db/dCursorMixin.py 2005-11-05 07:06:23 UTC (rev 1519)
+++ trunk/dabo/db/dCursorMixin.py 2005-11-05 18:34:14 UTC (rev 1520)
@@ -1922,10 +1922,6 @@
def __init__(self, *args, **kwargs):
super(DataSet, self).__init__(*args, **kwargs)
if _useSQLite:
- # Create a name for temporary tables
- alphanum = "abcdefghijklmnopqrstuvwxyz0123456789"
- self._sqliteTableName = "dabo_%s" %
"".join(random.sample(alphanum, 7))
-
# Register the adapters
if _USE_DECIMAL:
sqlite.register_adapter(Decimal,
self._adapt_decimal)
@@ -1946,6 +1942,18 @@
return str(decVal)
+ def _convert_decimal(self, strval):
+ """This is a converter routine. Takes the string
+ representation of a Decimal value and return an actual
+ decimal, if that module is present. If not, returns a float.
+ """
+ if _USE_DECIMAL:
+ ret = Decimal(strval)
+ else:
+ ret = float(strval)
+ return ret
+
+
def _escQuote(self, val):
ret = val
if isinstance(val, basestring):
@@ -1955,18 +1963,26 @@
return ret
- def _convert_decimal(self, strval):
- """This is a converter routine. Takes the string
- representation of a Decimal value and return an actual
- decimal, if that module is present. If not, returns a float.
+ def _fldReplace(self, expr, dictName=None):
+ """The list comprehensions require the field names be the keys
+ in a dictionary expression. Users, though, should not have to
know
+ about this. This takes a user-defined, SQL-like expressions,
and
+ substitutes any field name with the corresponding dict
+ expression.
"""
- if _USE_DECIMAL:
- ret = Decimal(strval)
- else:
- ret = float(strval)
+ keys = self[0].keys()
+ patTemplate = "(.*\\b)%s(\\b.*)"
+ ret = expr
+ if dictName is None:
+ dictName = self._dictSubName
+ for kk in keys:
+ pat = patTemplate % kk
+ mtch = re.match(pat, ret)
+ if mtch:
+ ret = mtch.groups()[0] + "%s['%s']" %
(dictName, kk) + mtch.groups()[1]
return ret
+
-
def _makeCreateTable(self):
"""Makes the CREATE TABLE string needed to represent
this data set. There must be at least one record in the
@@ -1991,11 +2007,44 @@
else:
qt = ""
insList.append("quote(%(" + key + ")s)")
- self._insertTemplate = "insert into %s values (%s)" %
(self._sqliteTableName,
- ", ".join(insList))
- return "create table %s (%s)" % (self._sqliteTableName, ",
".join(retList))
+ self._insertTemplate = "insert into dataset values (%s)" % ",
".join(insList)
+ return "create table dataset (%s)" % ", ".join(retList)
+ def replace(self, field, valOrExpr, scope=None):
+ """Replaces the value of the specified field with the given
value
+ or expression. All records matching the scope are affected; if
+ no scope is specified, all records are affected.
+
+ 'valOrExpr' will be treated as a literal value, unless it is
prefixed
+ with an equals sign. All expressions will therefore be a string
+ beginning with '='. Literals can be of any type.
+ """
+
+# dabo.trace()
+
+
+ if scope is None:
+ scope = "True"
+ else:
+ scope = self._fldReplace(scope, "rec")
+
+ literal = True
+ if isinstance(valOrExpr, basestring):
+ if valOrExpr.strip()[0] == "=":
+ literal = False
+ valOrExpr = valOrExpr.replace("=", "", 1)
+ valOrExpr = self._fldReplace(valOrExpr, "rec")
+ for rec in self:
+ if eval(scope):
+ if literal:
+ rec[field] = valOrExpr
+ else:
+ expr = "rec['%s'] = %s" % (field,
valOrExpr)
+ exec(expr)
+
+
+
def select(self, sqlExpr):
"""This will query the data set and return the resulting
data set. It requires that SQLite and pysqlite2 are installed;
@@ -2007,10 +2056,8 @@
The 'from dataset' is case-insensitive.
"""
if not _useSQLite:
+ dabo.errorLog.write(_("SQLite and pysqlite2 must be
installed to use this function"))
return None
- fromClause = "from %s " % self._sqliteTableName
- sql = re.sub("\\bfrom dataset\\b", fromClause, sqlExpr, re.I)
-
conn = sqlite.connect(":memory:")
crs = conn.cursor()
crs.execute(self._makeCreateTable())
@@ -2022,7 +2069,7 @@
crs.execute(self._insertTemplate % quoted)
# We have a table now with the necessary data. Run the query!
- crs.execute(sql)
+ crs.execute(sqlExpr)
tmpres = crs.fetchall()
dscrp = [fld[0] for fld in crs.description]
res = []
_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-dev