B [schema update] may remove has_text unexpectedly, give another argument to fix it
"""Server subcube of cubicweb : defines objects used only on the server(repository) sideThis module contains functions to initialize a new repository.:organization: Logilab:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses"""__docformat__="restructuredtext en"importsysfromos.pathimportjoin,existsfromlogilab.common.modutilsimportLazyObjectfromlogilab.common.textutilsimportget_csv# server-side debugging ########################################################## server debugging flags. They may be combined using binary operators.DBG_NONE=0# no debug informationDBG_RQL=1# rql execution informationDBG_SQL=2# executed sqlDBG_REPO=4# repository eventsDBG_MORE=8# repository events# current debug modeDEBUG=0defset_debug(debugmode):"""change the repository debugging mode"""globalDEBUGifnotdebugmode:DEBUG=0returnifisinstance(debugmode,basestring):formodeinget_csv(debugmode,sep='|'):DEBUG|=globals()[mode]else:DEBUG|=debugmodeclassdebugged(object):"""repository debugging context manager / decorator Can be used either as a context manager: >>> with debugged(server.DBG_RQL | server.DBG_REPO): ... # some code in which you want to debug repository activity, ... # seing information about RQL being executed an repository events. or as a function decorator: >>> @debugged(server.DBG_RQL | server.DBG_REPO) ... def some_function(): ... # some code in which you want to debug repository activity, ... # seing information about RQL being executed an repository events debug mode will be reseted at its original value when leaving the "with" block or the decorated function """def__init__(self,debugmode):self.debugmode=debugmodeself._clevel=Nonedef__enter__(self):"""enter with block"""self._clevel=DEBUGset_debug(self.debugmode)def__exit__(self,exctype,exc,traceback):"""leave with block"""set_debug(self._clevel)returntracebackisNonedef__call__(self,func):"""decorate function"""defwrapped(*args,**kwargs):_clevel=DEBUGset_debug(self.debugmode)try:returnfunc(*args,**kwargs)finally:set_debug(self._clevel)returnwrapped# database initialization ######################################################definit_repository(config,interactive=True,drop=False,vreg=None):"""initialise a repository database by creating tables add filling them with the minimal set of entities (ie at least the schema, base groups and a initial user) """fromglobimportglobfromyamsimportBASE_GROUPSfromcubicweb.dbapiimportin_memory_cnxfromcubicweb.server.repositoryimportRepositoryfromcubicweb.server.utilsimportmanager_userpasswdfromcubicweb.server.sqlutilsimportsqlexec,sqlschema,sqldropschema# configuration to avoid db schema loading and user'state checking# on connectionread_instance_schema=config.read_instance_schemabootstrap_schema=config.bootstrap_schemaconfig.read_instance_schema=Falseconfig.creating=Trueconfig.bootstrap_schema=Trueconfig.consider_user_state=Falseconfig.set_language=False# only enable the system source at initialization time + admin which is not# an actual source but contains initial manager account informationconfig.enabled_sources=('system','admin')repo=Repository(config,vreg=vreg)assertlen(repo.sources)==1,repo.sourcesschema=repo.schemasourcescfg=config.sources()_title='-> creating tables 'print_title,source=sourcescfg['system']driver=source['db-driver']sqlcnx=repo.system_source.get_connection()sqlcursor=sqlcnx.cursor()execute=sqlcursor.executeifdrop:dropsql=sqldropschema(schema,driver)try:sqlexec(dropsql,execute)exceptException,ex:print'-> drop failed, skipped (%s).'%exsqlcnx.rollback()# schema entities and relations tables# can't skip entities table even if system source doesn't support them,# they are used sometimes by generated sql. Keeping them empty is much# simpler than fixing this...ifsqlcnx.logged_user!=source['db-user']:schemasql=sqlschema(schema,driver,user=source['db-user'])else:schemasql=sqlschema(schema,driver)#skip_entities=[str(e) for e in schema.entities()# if not repo.system_source.support_entity(str(e))])sqlexec(schemasql,execute,pbtitle=_title)# install additional driver specific sql filesforfpathinglob(join(config.schemas_lib_dir(),'*.sql.%s'%driver)):print'-> installing',fpathsqlexec(open(fpath).read(),execute,False,delimiter=';;')fordirectoryinconfig.cubes_path():forfpathinglob(join(directory,'schema','*.sql.%s'%driver)):print'-> installing',fpathsqlexec(open(fpath).read(),execute,False,delimiter=';;')sqlcursor.close()sqlcnx.commit()sqlcnx.close()session=repo.internal_session()try:login=unicode(sourcescfg['admin']['login'])pwd=sourcescfg['admin']['password']exceptKeyError:ifinteractive:msg='enter login and password of the initial manager account'login,pwd=manager_userpasswd(msg=msg,confirm=True)else:login,pwd=unicode(source['db-user']),source['db-password']print'-> inserting default user and default groups.'# sort for eid predicatability as expected in some server testsforgroupinsorted(BASE_GROUPS):session.execute('INSERT CWGroup X: X name %(name)s',{'name':unicode(group)})session.execute('INSERT CWUser X: X login %(login)s, X upassword %(pwd)s',{'login':login,'pwd':pwd})session.execute('SET U in_group G WHERE G name "managers"')session.commit()# reloging using the admin userconfig._cubes=None# avoid assertion errorrepo,cnx=in_memory_cnx(config,login,pwd)assertlen(repo.sources)==1,repo.sourceshandler=config.migration_handler(schema,interactive=False,cnx=cnx,repo=repo)initialize_schema(config,schema,handler)# insert versionshandler.cmd_add_entity('CWProperty',pkey=u'system.version.cubicweb',value=unicode(config.cubicweb_version()))forcubeinconfig.cubes():handler.cmd_add_entity('CWProperty',pkey=u'system.version.%s'%cube.lower(),value=unicode(config.cube_version(cube)))# some entities have been added before schema entities, fix the 'is' and# 'is_instance_of' relationsforrtypein('is','is_instance_of'):handler.sqlexec('INSERT INTO %s_relation ''SELECT X.eid, ET.cw_eid FROM entities as X, cw_CWEType as ET ''WHERE X.type=ET.cw_name AND NOT EXISTS('' SELECT 1 from is_relation '' WHERE eid_from=X.eid AND eid_to=ET.cw_eid)'%rtype)# yoo !cnx.commit()config.enabled_sources=Noneforuri,source_configinconfig.sources().items():ifuriin('admin','system'):# not an actual source or init_creating already calledcontinuesource=repo.get_source(uri,source_config)source.init_creating()cnx.commit()cnx.close()session.close()# restore initial configurationconfig.creating=Falseconfig.read_instance_schema=read_instance_schemaconfig.bootstrap_schema=bootstrap_schemaconfig.consider_user_state=Trueconfig.set_language=Trueprint'-> database for instance %s initialized.'%config.appiddefinitialize_schema(config,schema,mhandler,event='create'):fromcubicweb.server.schemaserialimportserialize_schemapaths=[pforpinconfig.cubes_path()+[config.apphome]ifexists(join(p,'migration'))]# execute cubicweb's pre<event> scriptmhandler.exec_event_script('pre%s'%event)# execute cubes pre<event> script if anyforpathinreversed(paths):mhandler.exec_event_script('pre%s'%event,path)# enter instance'schema into the databaseserialize_schema(mhandler.rqlcursor,schema)# execute cubicweb's post<event> scriptmhandler.exec_event_script('post%s'%event)# execute cubes'post<event> script if anyforpathinreversed(paths):mhandler.exec_event_script('post%s'%event,path)# sqlite'stored procedures have to be registered at connexion opening timeSQL_CONNECT_HOOKS={}# add to this set relations which should have their add security checking done# *BEFORE* adding the actual relation (done after by default)BEFORE_ADD_RELATIONS=set(('owned_by',))# add to this set relations which should have their add security checking done# *at COMMIT TIME* (done after by default)ON_COMMIT_ADD_RELATIONS=set(())# available sources registrySOURCE_TYPES={'native':LazyObject('cubicweb.server.sources.native','NativeSQLSource'),# XXX private sources installed by an external cube'pyrorql':LazyObject('cubicweb.server.sources.pyrorql','PyroRQLSource'),'ldapuser':LazyObject('cubicweb.server.sources.ldapuser','LDAPUserSource'),}