Creates a user-defined function that you can later use from within SQL
statements under the function name *name*. *num_params* is the number of
- parameters the function accepts, and *func* is a Python callable that is called
- as the SQL function.
+ parameters the function accepts (if *num_params* is -1, the function may
+ take any number of arguments), and *func* is a Python callable that is
+ called as the SQL function.
The function can return any of the types supported by SQLite: bytes, str, int,
float and None.
Creates a user-defined aggregate function.
The aggregate class must implement a ``step`` method, which accepts the number
- of parameters *num_params*, and a ``finalize`` method which will return the
+ of parameters *num_params* (if *num_params* is -1, the function may take
+ any number of arguments), and a ``finalize`` method which will return the
final result of the aggregate.
The ``finalize`` method can return any of the types supported by SQLite:
def func_islonglong(v):
return isinstance(v, int) and v >= 1<<31
+def func(*args):
+ return len(args)
+
class AggrNoStep:
def __init__(self):
pass
def finalize(self):
return self.val
+class AggrCheckTypes:
+ def __init__(self):
+ self.val = 0
+
+ def step(self, whichType, *vals):
+ theType = {"str": str, "int": int, "float": float, "None": type(None),
+ "blob": bytes}
+ for val in vals:
+ self.val += int(theType[whichType] is type(val))
+
+ def finalize(self):
+ return self.val
+
class AggrSum:
def __init__(self):
self.val = 0.0
self.con.create_function("isnone", 1, func_isnone)
self.con.create_function("isblob", 1, func_isblob)
self.con.create_function("islonglong", 1, func_islonglong)
+ self.con.create_function("spam", -1, func)
def tearDown(self):
self.con.close()
val = cur.fetchone()[0]
self.assertEqual(val, 1)
+ def CheckAnyArguments(self):
+ cur = self.con.cursor()
+ cur.execute("select spam(?, ?)", (1, 2))
+ val = cur.fetchone()[0]
+ self.assertEqual(val, 2)
+
+
class AggregateTests(unittest.TestCase):
def setUp(self):
self.con = sqlite.connect(":memory:")
self.con.create_aggregate("excStep", 1, AggrExceptionInStep)
self.con.create_aggregate("excFinalize", 1, AggrExceptionInFinalize)
self.con.create_aggregate("checkType", 2, AggrCheckType)
+ self.con.create_aggregate("checkTypes", -1, AggrCheckTypes)
self.con.create_aggregate("mysum", 1, AggrSum)
def tearDown(self):
val = cur.fetchone()[0]
self.assertEqual(val, 1)
+ def CheckAggrCheckParamsInt(self):
+ cur = self.con.cursor()
+ cur.execute("select checkTypes('int', ?, ?)", (42, 24))
+ val = cur.fetchone()[0]
+ self.assertEqual(val, 2)
+
def CheckAggrCheckParamFloat(self):
cur = self.con.cursor()
cur.execute("select checkType('float', ?)", (3.14,))