Commit 81c6cac3 authored by Sylvain Thénault's avatar Sylvain Thénault
Browse files

[repository] Drop the entities.extid column and associated cache

This was not necessary anymore with promoted usage of the new data import API.
Turn repository's _type_extid_cache to _type_cache with only the entity's type
as key.

This introduces an backward incompatible change: entity_metas dict doesn't
contains anymore the extid key, but it doesn't seem used at all anywhere, so
this sounds acceptable.

Closes #15538317
parent 054a947b5415
......@@ -146,7 +146,6 @@ class MassiveObjectStore(stores.RQLObjectStore):
self.sql('CREATE TABLE IF NOT EXISTS cwmassive_initialized'
'(retype text, type varchar(128))')
self.sql("INSERT INTO cwmassive_initialized VALUES (%(e)s, 'etype')", {'e': etype})
self.sql('ALTER TABLE cw_%s ADD COLUMN extid VARCHAR(256)' % etype.lower())
attrs = self.metagen.base_etype_attrs(etype)
data = copy(attrs) # base_etype_attrs is @cached, a copy is necessary
data.update(kwargs)
......@@ -158,10 +157,6 @@ class MassiveObjectStore(stores.RQLObjectStore):
default_values = self.default_values[etype]
missing_keys = set(default_values) - set(data)
data.update((key, default_values[key]) for key in missing_keys)
extid = self.metagen.entity_extid(etype, data['eid'], data)
if extid is not None:
extid = b64encode(extid).decode('ascii')
data['extid'] = extid
self.metagen.init_entity_attrs(etype, data['eid'], data)
self._data_entities[etype].append(data)
return data['eid']
......@@ -203,9 +198,7 @@ class MassiveObjectStore(stores.RQLObjectStore):
cu = self.sql('SELECT retype, type FROM cwmassive_initialized')
for retype, _type in cu.fetchall():
self.logger.info('Cleanup for %s' % retype)
if _type == 'etype':
self.sql('ALTER TABLE cw_%s DROP COLUMN extid' % retype)
elif _type == 'rtype':
if _type == 'rtype':
# Cleanup relations tables
self._cleanup_relations(retype)
self.sql('DELETE FROM cwmassive_initialized WHERE retype = %(e)s',
......@@ -268,8 +261,7 @@ class MassiveObjectStore(stores.RQLObjectStore):
if not buf:
# The buffer is empty. This is probably due to error in _create_copyfrom_buffer
raise ValueError('Error in buffer creation for etype %s' % etype)
columns = ['cw_%s' % attr if attr != 'extid' else attr
for attr in columns]
columns = ['cw_%s' % attr for attr in columns]
cursor = self._cnx.cnxset.cu
try:
cursor.copy_from(buf, 'cw_%s' % etype.lower(), null='NULL', columns=columns)
......@@ -303,8 +295,8 @@ class MassiveObjectStore(stores.RQLObjectStore):
for parent_eschema in chain(eschema.ancestors(), [eschema]):
self._insert_meta_relation(etype, parent_eschema.eid, 'is_instance_of_relation')
# finally insert records into the entities table
self.sql("INSERT INTO entities (eid, type, extid) "
"SELECT cw_eid, '%s', extid FROM cw_%s "
self.sql("INSERT INTO entities (eid, type) "
"SELECT cw_eid, '%s' FROM cw_%s "
"WHERE NOT EXISTS (SELECT 1 FROM entities WHERE eid=cw_eid)"
% (etype, etype.lower()))
......
......@@ -417,13 +417,10 @@ class SQLGenSourceWrapper(object):
# add_info is _copypasted_ from the one in NativeSQLSource. We want it
# there because it will use the _handlers of the SQLGenSourceWrapper, which
# are not like the ones in the native source.
def add_info(self, cnx, entity, source, extid):
def add_info(self, cnx, entity, source):
"""add type and source info for an eid into the system table"""
# begin by inserting eid/type/source/extid into the entities table
if extid is not None:
assert isinstance(extid, binary_type)
extid = b64encode(extid).decode('ascii')
attrs = {'type': entity.cw_etype, 'eid': entity.eid, 'extid': extid}
# begin by inserting eid/type/source into the entities table
attrs = {'type': entity.cw_etype, 'eid': entity.eid}
self._handle_insert_entity_sql(cnx, self.sqlgen.insert('entities', attrs), attrs)
# insert core relations: is, is_instance_of and cw_source
self._handle_is_relation_sql(cnx, 'INSERT INTO is_relation(eid_from,eid_to) VALUES (%s,%s)',
......
......@@ -213,8 +213,8 @@ class NoHookRQLObjectStore(RQLObjectStore):
entity.cw_edited.update(kwargs, skipsec=False)
cnx = self._cnx
entity.eid = self._create_eid(cnx)
entity_source, extid = self.metagen.init_entity(entity)
self._system_source.add_info(cnx, entity, entity_source, extid)
entity_source = self.metagen.init_entity(entity)
self._system_source.add_info(cnx, entity, entity_source)
self._system_source.add_entity(cnx, entity)
kwargs = dict()
if inspect.getargspec(self._add_relation).keywords:
......@@ -288,7 +288,6 @@ class MetadataGenerator(object):
if source is None:
source = cnx.repo.system_source
self.source = source
self._need_extid = source is not cnx.repo.system_source
self._now = datetime.now(pytz.utc)
# attributes/relations shared by all entities of the same type
self._etype_attrs = []
......@@ -342,20 +341,6 @@ class MetadataGenerator(object):
rels[rel] = genfunc(etype)
return rels
def entity_extid(self, etype, eid, attrs):
"""Return the extid for the entity of given type and eid, to be inserted in the 'entities'
system table.
"""
if self._need_extid:
extid = attrs.get('cwuri')
if extid is None:
raise Exception('entity from an external source but no extid specified')
elif isinstance(extid, text_type):
extid = extid.encode('utf-8')
else:
extid = None
return extid
def init_entity_attrs(self, etype, eid, attrs):
"""Insert into an entity attrs dictionary attributes whose value is set per instance, not per
type.
......@@ -412,12 +397,10 @@ class _MetaGeneratorBWCompatWrapper(object):
return entity, rels
def init_entity(self, entity):
# if cwuri is specified, this is an extid. It's not if it's generated in the above loop
extid = self._mdgen.entity_extid(entity.cw_etype, entity.eid, entity.cw_edited)
attrs = dict(entity.cw_edited)
self._mdgen.init_entity_attrs(entity.cw_etype, entity.eid, attrs)
entity.cw_edited.update(attrs, skipsec=False)
return self._mdgen.source, extid
return self._mdgen.source
@add_metaclass(class_deprecated)
......@@ -482,10 +465,6 @@ class MetaGenerator(object):
return entity, rels
def init_entity(self, entity):
# if cwuri is specified, this is an extid. It's not if it's generated in the above loop
extid = entity.cw_edited.get('cwuri')
if isinstance(extid, text_type):
extid = extid.encode('utf-8')
for attr in self.entity_attrs:
if attr in entity.cw_edited:
# already set, skip this attribute
......@@ -493,7 +472,7 @@ class MetaGenerator(object):
genfunc = self.generate(attr)
if genfunc:
entity.cw_edited.edited_attribute(attr, genfunc(entity))
return self.source, extid
return self.source
def generate(self, rtype):
return getattr(self, 'gen_%s' % rtype, None)
......
......@@ -126,7 +126,6 @@ class MassImportSimpleTC(testlib.CubicWebTC):
crs = cnx.system_sql('SELECT indexname FROM pg_indexes')
indexes = [r[0] for r in crs.fetchall()]
self.assertNotIn('entities_pkey', indexes)
self.assertNotIn('entities_extid_idx', indexes)
self.assertNotIn('owned_by_relation_pkey', indexes)
self.assertNotIn('owned_by_relation_to_idx', indexes)
......@@ -139,7 +138,6 @@ class MassImportSimpleTC(testlib.CubicWebTC):
crs = cnx.system_sql('SELECT indexname FROM pg_indexes')
indexes = [r[0] for r in crs.fetchall()]
self.assertIn('entities_pkey', indexes)
self.assertIn('entities_extid_idx', indexes)
self.assertIn(build_index_name('owned_by_relation', ['eid_from', 'eid_to'], 'key_'),
indexes)
self.assertIn(build_index_name('owned_by_relation', ['eid_from'], 'idx_'),
......@@ -221,7 +219,6 @@ where table_schema = %(s)s''', {'s': pgh.pg_schema}).fetchall()
crs = cnx.system_sql('SELECT indexname FROM pg_indexes')
indexes = [r[0] for r in crs.fetchall()]
self.assertIn('entities_pkey', indexes)
self.assertIn('entities_extid_idx', indexes)
self.assertIn(build_index_name('owned_by_relation', ['eid_from', 'eid_to'], 'key_'),
indexes)
self.assertIn(build_index_name('owned_by_relation', ['eid_from'], 'idx_'),
......@@ -255,7 +252,6 @@ where table_schema = %(s)s''', {'s': pgh.pg_schema}).fetchall()
crs = cnx.system_sql('SELECT indexname FROM pg_indexes')
indexes = [r[0] for r in crs.fetchall()]
self.assertNotIn('entities_pkey', indexes)
self.assertNotIn('entities_extid_idx', indexes)
self.assertNotIn(build_index_name('owned_by_relation', ['eid_from', 'eid_to'], 'key_'),
indexes)
self.assertNotIn(build_index_name('owned_by_relation', ['eid_from'], 'idx_'),
......@@ -268,7 +264,6 @@ where table_schema = %(s)s''', {'s': pgh.pg_schema}).fetchall()
crs = cnx.system_sql('SELECT indexname FROM pg_indexes')
indexes = [r[0] for r in crs.fetchall()]
self.assertIn('entities_pkey', indexes)
self.assertIn('entities_extid_idx', indexes)
self.assertIn(build_index_name('owned_by_relation', ['eid_from', 'eid_to'], 'key_'),
indexes)
self.assertIn(build_index_name('owned_by_relation', ['eid_from'], 'idx_'),
......
......@@ -125,7 +125,7 @@ def turn_repo_on(repo):
if repo._needs_refresh:
for cnxset in repo.cnxsets:
cnxset.reconnect()
repo._type_extid_cache = {}
repo._type_cache = {}
repo.querier._rql_cache = {}
repo.system_source.reset_caches()
repo._needs_refresh = False
......
......@@ -202,7 +202,7 @@ class BaseQuerierTC(TestCase):
self._access = RepoAccess(self.repo, 'admin', FakeRequest)
self.ueid = self.session.user.eid
assert self.ueid != -1
self.repo._type_extid_cache = {} # clear cache
self.repo._type_cache = {} # clear cache
self.maxeid = self.get_max_eid()
do_monkey_patch()
self._dumb_sessions = []
......
......@@ -147,55 +147,3 @@ class UpdateFTIHook(MetaDataHook):
elif ftcontainer == 'object':
cnx.repo.system_source.index_entity(
cnx, cnx.entity_from_eid(self.eidto))
# entity source handling #######################################################
class ChangeEntitySourceUpdateCaches(hook.Operation):
oldsource = entity = None # make pylint happy
def postcommit_event(self):
self.oldsource.reset_caches()
repo = self.cnx.repo
entity = self.entity
repo._type_extid_cache[entity.eid] = (entity.cw_etype, None)
class ChangeEntitySourceDeleteHook(MetaDataHook):
"""support for moving an entity from an external source by watching 'Any
cw_source CWSource' relation
"""
__regid__ = 'cw.metadata.source-change'
__select__ = MetaDataHook.__select__ & hook.match_rtype('cw_source')
events = ('before_delete_relation',)
def __call__(self):
if (self._cw.deleted_in_transaction(self.eidfrom)
or self._cw.deleted_in_transaction(self.eidto)):
return
schange = self._cw.transaction_data.setdefault('cw_source_change', {})
schange[self.eidfrom] = self.eidto
class ChangeEntitySourceAddHook(MetaDataHook):
__regid__ = 'cw.metadata.source-change'
__select__ = MetaDataHook.__select__ & hook.match_rtype('cw_source')
events = ('before_add_relation',)
def __call__(self):
schange = self._cw.transaction_data.get('cw_source_change')
if schange is not None and self.eidfrom in schange:
newsource = self._cw.entity_from_eid(self.eidto)
if newsource.name != 'system':
raise Exception('changing source to something else than the '
'system source is unsupported')
syssource = newsource.repo_source
oldsource = self._cw.entity_from_eid(schange[self.eidfrom])
entity = self._cw.entity_from_eid(self.eidfrom)
attrs = {'type': entity.cw_etype, 'eid': entity.eid, 'extid': None}
self._cw.system_sql(syssource.sqlgen.update('entities', attrs, ['eid']), attrs)
# register an operation to update repository/sources caches
ChangeEntitySourceUpdateCaches(self._cw, entity=entity,
oldsource=oldsource.repo_source)
......@@ -309,9 +309,9 @@ class CWETypeRenameOp(MemSchemaOperation):
self.info('renamed table %s to %s', oldname, newname)
sqlexec('UPDATE entities SET type=%(newname)s WHERE type=%(oldname)s',
{'newname': newname, 'oldname': oldname})
for eid, (etype, extid) in cnx.repo._type_extid_cache.items():
for eid, etype in cnx.repo._type_cache.items():
if etype == oldname:
cnx.repo._type_extid_cache[eid] = (newname, extid)
cnx.repo._type_cache[eid] = newname
# recreate the indexes
for rschema in eschema.subject_relations():
if rschema.inlined or (rschema.final and eschema.rdef(rschema.type).indexed):
......
......@@ -127,12 +127,6 @@ add_foreign_keys()
cu = session.cnxset.cu
helper = repo.system_source.dbhelper
helper.drop_index(cu, 'entities', 'extid', False)
# don't use create_index because it doesn't work for columns that may be NULL
# on sqlserver
for query in helper.sqls_create_multicol_unique_index('entities', ['extid']):
cu.execute(query)
sql('DELETE FROM entities WHERE eid < 0')
commit()
......
......@@ -5,3 +5,4 @@ rql('DELETE CWProperty X WHERE X pkey "system.version.pyramid"',
sql('DROP TABLE moved_entities')
sql('ALTER TABLE entities DROP COLUMN asource')
sql('ALTER TABLE entities DROP COLUMN extid')
......@@ -379,15 +379,6 @@ if applcubicwebversion < (3, 5, 0) and cubicwebversion >= (3, 5, 0):
sync_schema_props_perms()
if applcubicwebversion < (3, 2, 2) and cubicwebversion >= (3, 2, 1):
from base64 import b64encode
for eid, extid in sql('SELECT eid, extid FROM entities '
'WHERE extid is NOT NULL',
ask_confirm=False):
sql('UPDATE entities SET extid=%(extid)s WHERE eid=%(eid)s',
{'extid': b64encode(extid), 'eid': eid}, ask_confirm=False)
commit()
if applcubicwebversion < (3, 2, 0) and cubicwebversion >= (3, 2, 0):
add_cube('card', update_database=False)
......
......@@ -14,12 +14,12 @@ assert olddn != newdn
raw_input("Ensure you've stopped the instance, type enter when done.")
for eid, extid in sql("SELECT eid, extid FROM entities WHERE source='%s'" % uri):
olduserdn = b64decode(extid)
for eid, olduserdn in rql("Any X, XURI WHERE X cwuri XURI, X cw_source S, S name %(name)s",
{'name': uri}):
newuserdn = olduserdn.replace(olddn, newdn)
if newuserdn != olduserdn:
print(olduserdn, '->', newuserdn)
sql("UPDATE entities SET extid='%s' WHERE eid=%s" % (b64encode(newuserdn), eid))
sql("UPDATE cw_cwuser SET cw_cwuri='%s' WHERE cw_eid=%s" % (newuserdn, eid))
commit()
......
......@@ -414,7 +414,6 @@ def check(repo, cnx, checks, reindex, fix, withpb=True):
SYSTEM_INDICES = {
# see cw/server/sources/native.py
'entities_type_idx': ('entities', 'type'),
'entities_extid_idx': ('entities', 'extid'),
'transactions_tx_time_idx': ('transactions', 'tx_time'),
'transactions_tx_user_idx': ('transactions', 'tx_user'),
'tx_entity_actions_txa_action_idx': ('tx_entity_actions', 'txa_action'),
......
......@@ -179,9 +179,8 @@ class Repository(object):
self.sources_by_uri = {'system': self.system_source}
# querier helper, need to be created after sources initialization
self.querier = querier.QuerierHelper(self, self.schema)
# cache eid -> (type, extid)
self._type_extid_cache = {}
# cache extid -> eid
# cache eid -> type
self._type_cache = {}
# open some connection sets
if config.init_cnxset_pool:
self.init_cnxset_pool()
......@@ -714,33 +713,29 @@ class Repository(object):
# * correspondance between eid and local id (i.e. specific to a given source)
def clear_caches(self, eids):
etcache = self._type_extid_cache
etcache = self._type_cache
rqlcache = self.querier._rql_cache
for eid in eids:
try:
etype, extid = etcache.pop(int(eid)) # may be a string in some cases
etype = etcache.pop(int(eid)) # may be a string in some cases
rqlcache.pop(('%s X WHERE X eid %s' % (etype, eid),), None)
except KeyError:
etype = None
rqlcache.pop(('Any X WHERE X eid %s' % eid,), None)
self.system_source.clear_eid_cache(eid, etype)
def type_and_extid_from_eid(self, eid, cnx):
"""Return the type and extid of the entity with id `eid`."""
def type_from_eid(self, eid, cnx):
"""Return the type of the entity with id `eid`"""
try:
eid = int(eid)
except ValueError:
raise UnknownEid(eid)
try:
return self._type_extid_cache[eid]
return self._type_cache[eid]
except KeyError:
etype, extid = self.system_source.eid_type_extid(cnx, eid)
self._type_extid_cache[eid] = (etype, extid)
return etype, extid
def type_from_eid(self, eid, cnx):
"""Return the type of the entity with id `eid`"""
return self.type_and_extid_from_eid(eid, cnx)[0]
etype = self.system_source.eid_type(cnx, eid)
self._type_cache[eid] = etype
return etype
def querier_cache_key(self, cnx, rql, args, eidkeys):
cachekey = [rql]
......@@ -757,13 +752,13 @@ class Repository(object):
args[key] = int(args[key])
return tuple(cachekey)
def add_info(self, cnx, entity, source, extid=None):
def add_info(self, cnx, entity, source):
"""add type and source info for an eid into the system table,
and index the entity with the full text index
"""
# begin by inserting eid/type/source/extid into the entities table
# begin by inserting eid/type/source into the entities table
hook.CleanupNewEidsCacheOp.get_instance(cnx).add_data(entity.eid)
self.system_source.add_info(cnx, entity, source, extid)
self.system_source.add_info(cnx, entity, source)
def _delete_cascade_multi(self, cnx, entities):
"""same as _delete_cascade but accepts a list of entities with
......@@ -804,16 +799,9 @@ class Repository(object):
entities, rql)
def init_entity_caches(self, cnx, entity, source):
"""add entity to connection entities cache and repo's extid cache.
Return entity's ext id if the source isn't the system source.
"""
"""Add entity to connection entities cache and repo's cache."""
cnx.set_entity_cache(entity)
if source.uri == 'system':
extid = None
else:
extid = source.get_extid(entity)
self._type_extid_cache[entity.eid] = (entity.cw_etype, extid)
return extid
self._type_cache[entity.eid] = entity.cw_etype
def glob_add_entity(self, cnx, edited):
"""add an entity to the repository
......@@ -829,7 +817,7 @@ class Repository(object):
# allocate an eid to the entity before calling hooks
entity.eid = self.system_source.create_eid(cnx)
# set caches asap
extid = self.init_entity_caches(cnx, entity, source)
self.init_entity_caches(cnx, entity, source)
if server.DEBUG & server.DBG_REPO:
print('ADD entity', self, entity.cw_etype, entity.eid, edited)
prefill_entity_caches(entity)
......@@ -838,7 +826,7 @@ class Repository(object):
edited.set_defaults()
if cnx.is_hook_category_activated('integrity'):
edited.check(creation=True)
self.add_info(cnx, entity, source, extid)
self.add_info(cnx, entity, source)
try:
source.add_entity(cnx, entity)
except (UniqueTogetherError, ViolatedConstraint) as exc:
......
......@@ -45,7 +45,7 @@ def group_mapping(cnx, interactive=True):
"""
res = {}
for eid, name in cnx.execute('Any G, N WHERE G is CWGroup, G name N',
build_descr=False):
build_descr=False):
res[name] = eid
if not interactive:
return res
......@@ -147,8 +147,8 @@ def deserialize_schema(schema, cnx):
{'x': etype, 'n': netype})
cnx.commit(False)
tocleanup = [eid]
tocleanup += (eid for eid, cached in repo._type_extid_cache.items()
if etype == cached[0])
tocleanup += (eid for eid, cached in repo._type_cache.items()
if etype == cached)
repo.clear_caches(tocleanup)
cnx.commit(False)
if needcopy:
......
......@@ -778,11 +778,16 @@ class Connection(RequestSessionBase):
def source_defs(self):
return self.repo.source_defs()
@_open_only
def entity_type(self, eid):
"""Return entity type for the entity with id `eid`."""
return self.repo.type_from_eid(eid, self)
@deprecated('[3.24] use entity_type(eid) instead')
@_open_only
def entity_metas(self, eid):
"""Return a dictionary {type, extid}) for the entity with id `eid`."""
etype, extid = self.repo.type_and_extid_from_eid(eid, self)
return {'type': etype, 'extid': extid}
"""Return a dictionary {type}) for the entity with id `eid`."""
return {'type': self.repo.type_from_eid(eid, self)}
# core method #############################################################
......
......@@ -192,12 +192,6 @@ class AbstractSource(object):
else:
self.urls = []
@staticmethod
def decode_extid(extid):
if extid is None:
return extid
return b64decode(extid)
# source initialization / finalization #####################################
def set_schema(self, schema):
......@@ -301,10 +295,6 @@ class AbstractSource(object):
# write modification api ###################################################
# read-only sources don't have to implement methods below
def get_extid(self, entity):
"""return the external id for the given newly inserted entity"""
raise NotImplementedError(self)
def add_entity(self, cnx, entity):
"""add a new entity to the source"""
raise NotImplementedError(self)
......@@ -339,14 +329,14 @@ class AbstractSource(object):
# system source interface #################################################
def eid_type_extid(self, cnx, eid):
"""return a tuple (type, extid) for the entity with id <eid>"""
def eid_type(self, cnx, eid):
"""Return the type of entity `eid`."""
raise NotImplementedError(self)
def create_eid(self, cnx):
raise NotImplementedError(self)
def add_info(self, cnx, entity, source, extid):
def add_info(self, cnx, entity, source):
"""add type and source info for an eid into the system table"""
raise NotImplementedError(self)
......
......@@ -15,14 +15,8 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""Adapters for native cubicweb sources.
Notes:
* extid (aka external id, the primary key of an entity in the external source
from which it comes from) are stored in a varchar column encoded as a base64
string. This is because it should actually be Bytes but we want an index on
it for fast querying.
"""
"""Adapters for native cubicweb sources."""
from __future__ import print_function
from threading import Lock
......@@ -814,16 +808,13 @@ class NativeSQLSource(SQLAdapterMixIn, AbstractSource):
# system source interface #################################################
def eid_type_extid(self, cnx, eid): # pylint: disable=E0202
"""return a tuple (type, extid) for the entity with id <eid>"""
sql = 'SELECT type, extid FROM entities WHERE eid=%s' % eid
def eid_type(self, cnx, eid): # pylint: disable=E0202
"""Return the entity's type for `eid`."""
sql = 'SELECT type FROM entities WHERE eid=%s' % eid
try:
res = self.doexec(cnx, sql).fetchone()
if res is not None:
if not isinstance(res, list):
res = list(res)
res[-1] = self.decode_extid(res[-1])
return res
return res[0]
except Exception:
self.exception('failed to query entities table for eid %s', eid)
raise UnknownEid(eid)
......@@ -836,14 +827,11 @@ class NativeSQLSource(SQLAdapterMixIn, AbstractSource):
_handle_insert_entity_sql = doexec
_handle_is_instance_of_sql = _handle_source_relation_sql = _handle_is_relation_sql
def add_info(self, cnx, entity, source, extid):
def add_info(self, cnx, entity, source):
"""add type and source info for an eid into the system table"""
assert cnx.cnxset is not None
# begin by inserting eid/type/source/extid into the entities table
if extid is not None:
assert isinstance(extid, binary_type)
extid = b64encode(extid).decode('ascii')
attrs = {'type': text_type(entity.cw_etype), 'eid': entity.eid, 'extid': extid}
# begin by inserting eid/type/source into the entities table
attrs = {'type': text_type(entity.cw_etype), 'eid': entity.eid}
self._handle_insert_entity_sql(cnx, self.sqlgen.insert('entities', attrs), attrs)
# insert core relations: is, is_instance_of and cw_source
......@@ -1131,7 +1119,7 @@ class NativeSQLSource(SQLAdapterMixIn, AbstractSource):
# restore the entity
action.changes['cw_eid'] = eid
# restore record in entities (will update fti if needed)
self.add_info(cnx, entity, self, None)
self.add_info(cnx, entity, self)
sql = self.sqlgen.insert(SQL_PREFIX + etype, action.changes)
self.doexec(cnx, sql, action.changes)
self.repo.hm.call_hooks('after_add_entity', cnx, entity=entity)
......@@ -1332,8 +1320,7 @@ def sql_schema(driver):
for sql in ("""
CREATE TABLE entities (
eid INTEGER PRIMARY KEY NOT NULL,
type VARCHAR(64) NOT NULL,
extid VARCHAR(256)
type VARCHAR(64) NOT NULL
);;
CREATE INDEX entities_type_idx ON entities(type);;