"""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), all rights reserved.:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr"""__docformat__="restructuredtext en"importsysfromos.pathimportjoin,existsfromlogilab.common.modutilsimportLazyObject# server debugging flagDEBUG=Falsedefinit_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) """fromglobimportglobfromcubicweb.schemaimportBASEGROUPSfromcubicweb.dbapiimportin_memory_cnxfromcubicweb.server.repositoryimportRepositoryfromcubicweb.server.utilsimportmanager_userpasswdfromcubicweb.server.sqlutilsimportsqlexec,sqlschema,sqldropschema# configuration to avoid db schema loading and user'state checking# on connectionread_application_schema=config.read_application_schemabootstrap_schema=config.bootstrap_schemaconfig.read_application_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()print'creating necessary tables into the system source'source=sourcescfg['system']driver=source['db-driver']sqlcnx=repo.system_source.get_connection()sqlcursor=sqlcnx.cursor()defexecute(sql,args=None):repo.system_source.doexec(sqlcursor,sql,args)ifdrop: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)# install additional driver specific sql filesforfpathinglob(join(config.schemas_lib_dir(),'*.sql.%s'%driver)):print'install',fpathsqlexec(open(fpath).read(),execute,False,delimiter=';;')fordirectoryinconfig.cubes_path():forfpathinglob(join(directory,'schema','*.sql.%s'%driver)):print'install',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 groups'needisfix=[]forgroupinBASEGROUPS:rset=session.execute('INSERT CWGroup X: X name %(name)s',{'name':unicode(group)})needisfix.append((rset.rows[0][0],rset.description[0][0]))rset=session.execute('INSERT CWUser X: X login %(login)s, X upassword %(pwd)s',{'login':login,'pwd':pwd})needisfix.append((rset.rows[0][0],rset.description[0][0]))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)# admin user and groups have been added before schema entities, fix the 'is'# relationforeid,etypeinneedisfix:handler.session.unsafe_execute('SET X is E WHERE X eid %(x)s, E name %(name)s',{'x':eid,'name':etype},'x')handler.session.unsafe_execute('SET X is_instance_of E WHERE X eid %(x)s, E name %(name)s',{'x':eid,'name':etype},'x')# 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)))# 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_application_schema=read_application_schemaconfig.bootstrap_schema=bootstrap_schemaconfig.consider_user_state=Trueconfig.set_language=Trueprint'application %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 application'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)defset_debug(debugmode):globalDEBUGDEBUG=debugmodedefdebugged(func):"""decorator to activate debug mode"""defwrapped(*args,**kwargs):globalDEBUGDEBUG=Truetry:returnfunc(*args,**kwargs)finally:DEBUG=Falsereturnwrapped# 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'),}