[schema] restore constraint checking when running on old sqlite
Old sqlite3 doesn't provide CHECK constraint names in error messages,
preventing us from translating a backend integrity error into a
ValidationError. This was added in 2012, but the sqlite3 version in
RHEL6 is older; so if we run on old sqlite, keep checking the
constraints in python rather than only in SQL.
Closes #10927494
--- a/schema.py Wed Feb 17 17:20:29 2016 +0100
+++ b/schema.py Wed Feb 17 14:00:39 2016 +0100
@@ -1140,12 +1140,6 @@
# additional cw specific constraints ###########################################
-# these are implemented as CHECK constraints in sql, don't do the work
-# twice
-StaticVocabularyConstraint.check = lambda *args: True
-IntervalBoundConstraint.check = lambda *args: True
-BoundaryConstraint.check = lambda *args: True
-
class BaseRQLConstraint(RRQLExpression, BaseConstraint):
"""base class for rql constraints"""
distinct_query = None
--- a/server/schemaserial.py Wed Feb 17 17:20:29 2016 +0100
+++ b/server/schemaserial.py Wed Feb 17 14:00:39 2016 +0100
@@ -23,12 +23,13 @@
import os
import json
import sys
+import sqlite3
from six import PY2, text_type, string_types
from logilab.common.shellutils import ProgressBar, DummyProgressBar
-from yams import BadSchemaDefinition, schema as schemamod, buildobjs as ybo
+from yams import BadSchemaDefinition, schema as schemamod, buildobjs as ybo, constraints
from cubicweb import Binary
from cubicweb.schema import (KNOWN_RPROPERTIES, CONSTRAINTS, ETYPE_NAME_MAP,
@@ -312,12 +313,20 @@
res.setdefault(eid, {}).setdefault(action, []).append( (expr, mainvars, expreid) )
return res
+
def deserialize_rdef_constraints(cnx):
"""return the list of relation definition's constraints as instances"""
+ if cnx.repo.system_source.dbdriver != 'sqlite' or sqlite3.sqlite_version_info >= (3, 7, 12):
+ # these are implemented as CHECK constraints in sql, don't do the work twice. Unless we
+ # are using too old version of sqlite which misses the constraint name in the integrity
+ # error so we've to check them by ourselves anyway
+ constraints.StaticVocabularyConstraint.check = lambda *args: True
+ constraints.IntervalBoundConstraint.check = lambda *args: True
+ constraints.BoundaryConstraint.check = lambda *args: True
res = {}
for rdefeid, ceid, ct, val in cnx.execute(
- 'Any E, X,TN,V WHERE E constrained_by X, X is CWConstraint, '
- 'X cstrtype T, T name TN, X value V', build_descr=False):
+ 'Any E, X,TN,V WHERE E constrained_by X, X is CWConstraint, '
+ 'X cstrtype T, T name TN, X value V', build_descr=False):
cstr = CONSTRAINTS[ct].deserialize(val)
cstr.eid = ceid
res.setdefault(rdefeid, []).append(cstr)