handle lgc.adbh api changes within regards of backup/restore:
* new backup_commands method instead of backup_command
* some backend still return command as string as expected by os.system, not subprocess.call
"""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-2010 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,existsfromglobimportglobfromlogilab.common.modutilsimportLazyObjectfromlogilab.common.textutilsimportsplitstripfromyamsimportBASE_GROUPSfromcubicwebimportCW_SOFTWARE_ROOT# 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_MS=8# multi-sourcesDBG_MORE=16# more verbosityDBG_ALL=1+2+4+8+16# current debug modeDEBUG=0defset_debug(debugmode):"""change the repository debugging mode"""globalDEBUGifnotdebugmode:DEBUG=0returnifisinstance(debugmode,basestring):formodeinsplitstrip(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) """fromcubicweb.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)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,password=pwd)# trigger vreg initialisation of entity classesconfig.cubicweb_appobject_path=set(('entities',))config.cube_appobject_path=set(('entities',))repo.vreg.set_schema(repo.schema)assertlen(repo.sources)==1,repo.sourceshandler=config.migration_handler(schema,interactive=False,cnx=cnx,repo=repo)# install additional driver specific sql fileshandler.install_custom_sql_scripts(join(CW_SOFTWARE_ROOT,'schemas'),driver)fordirectoryinreversed(config.cubes_path()):handler.install_custom_sql_scripts(join(directory,'schema'),driver)initialize_schema(config,schema,handler)# 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_schema# deactivate every hooks but those responsible to set metadata# so, NO INTEGRITY CHECKS are done, to have quicker db creationoldmode=config.set_hooks_mode(config.DENY_ALL)changes=config.enable_hook_category('metadata')paths=[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 databasemhandler.session.set_pool()serialize_schema(mhandler.session,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)# restore hooks configifchanges:config.disable_hook_category(changes)config.set_hooks_mode(oldmode)# 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'),}