goa/dbmyams.py
changeset 1808 aa09e20dd8c0
parent 1802 d628defebc17
child 1977 606923dff11b
equal deleted inserted replaced
1693:49075f57cf2c 1808:aa09e20dd8c0
     3 MISSING FEATURES:
     3 MISSING FEATURES:
     4  - ListProperty, StringList, EmailProperty, etc. (XXX)
     4  - ListProperty, StringList, EmailProperty, etc. (XXX)
     5  - ReferenceProperty.verbose_name, collection_name, etc. (XXX)
     5  - ReferenceProperty.verbose_name, collection_name, etc. (XXX)
     6 
     6 
     7 XXX proprify this knowing we'll use goa.db
     7 XXX proprify this knowing we'll use goa.db
       
     8 :organization: Logilab
       
     9 :copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
    10 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     8 """
    11 """
     9 
    12 
    10 from os.path import join
    13 from os.path import join
    11 from datetime import datetime, date, time
    14 from datetime import datetime, date, time
    12 
    15 
    13 from google.appengine.ext import db
    16 from google.appengine.ext import db
    14 from google.appengine.api import datastore_types
    17 from google.appengine.api import datastore_types
    15 
    18 
    16 from yams.schema2sql import eschema_attrs
       
    17 from yams.constraints import SizeConstraint
       
    18 from yams.reader import PyFileReader
       
    19 from yams.buildobjs import (String, Int, Float, Boolean, Date, Time, Datetime,
    19 from yams.buildobjs import (String, Int, Float, Boolean, Date, Time, Datetime,
    20                             Interval, Password, Bytes, ObjectRelation,
    20                             Bytes, SubjectRelation)
    21                             SubjectRelation, RestrictedEntityType)
       
    22 from yams.buildobjs import metadefinition, EntityType
    21 from yams.buildobjs import metadefinition, EntityType
    23 
    22 
    24 from cubicweb.schema import CubicWebSchemaLoader
    23 from cubicweb.schema import CubicWebSchemaLoader
    25 from cubicweb.goa import db as goadb
    24 from cubicweb.goa import db as goadb
    26 
    25 
    70         else:
    69         else:
    71             kwargs['default'] = 'today'
    70             kwargs['default'] = 'today'
    72     # XXX no equivalent to Django's `auto_now`
    71     # XXX no equivalent to Django's `auto_now`
    73     return dbm2y_default_factory(prop, **kwargs)
    72     return dbm2y_default_factory(prop, **kwargs)
    74 
    73 
    75     
    74 
    76 def dbm2y_relation_factory(etype, prop, multiple=False):
    75 def dbm2y_relation_factory(etype, prop, multiple=False):
    77     """called if `prop` is a `db.ReferenceProperty`"""
    76     """called if `prop` is a `db.ReferenceProperty`"""
    78     if multiple:
    77     if multiple:
    79         cardinality = '**'
    78         cardinality = '**'
    80     elif prop.required:
    79     elif prop.required:
    85     try:
    84     try:
    86         return SubjectRelation(prop.data_type.kind(), cardinality=cardinality)
    85         return SubjectRelation(prop.data_type.kind(), cardinality=cardinality)
    87     except AttributeError, ex:
    86     except AttributeError, ex:
    88         # hack, data_type is still _SELF_REFERENCE_MARKER
    87         # hack, data_type is still _SELF_REFERENCE_MARKER
    89         return SubjectRelation(etype, cardinality=cardinality)
    88         return SubjectRelation(etype, cardinality=cardinality)
    90     
    89 
    91     
    90 
    92 DBM2Y_FACTORY = {
    91 DBM2Y_FACTORY = {
    93     basestring: dbm2y_string_factory,
    92     basestring: dbm2y_string_factory,
    94     datastore_types.Text: dbm2y_string_factory,
    93     datastore_types.Text: dbm2y_string_factory,
    95     int: dbm2y_default_factory,
    94     int: dbm2y_default_factory,
    96     float: dbm2y_default_factory,
    95     float: dbm2y_default_factory,
   109         super(GaeSchemaLoader, self).__init__(*args, **kwargs)
   108         super(GaeSchemaLoader, self).__init__(*args, **kwargs)
   110         self.defined = {}
   109         self.defined = {}
   111         self.created = []
   110         self.created = []
   112         self.loaded_files = []
   111         self.loaded_files = []
   113         self._instantiate_handlers()
   112         self._instantiate_handlers()
   114         
   113 
   115     def finalize(self, register_base_types=False):
   114     def finalize(self, register_base_types=False):
   116         return self._build_schema('google-appengine', register_base_types)
   115         return self._build_schema('google-appengine', register_base_types)
   117 
   116 
   118     def load_dbmodel(self, name, props):
   117     def load_dbmodel(self, name, props):
   119         clsdict = {}
   118         clsdict = {}
   150         erdef = self.pyreader.import_erschema(ertype, schemamod)
   149         erdef = self.pyreader.import_erschema(ertype, schemamod)
   151 
   150 
   152     def import_yams_cube_schema(self, templpath):
   151     def import_yams_cube_schema(self, templpath):
   153         for filepath in self.get_schema_files(templpath):
   152         for filepath in self.get_schema_files(templpath):
   154             self.handle_file(filepath)
   153             self.handle_file(filepath)
   155         
   154 
   156     @property
   155     @property
   157     def pyreader(self):
   156     def pyreader(self):
   158         return self._live_handlers['.py']
   157         return self._live_handlers['.py']
   159         
   158 
   160 import os
   159 import os
   161 from cubicweb import CW_SOFTWARE_ROOT
   160 from cubicweb import CW_SOFTWARE_ROOT
   162 
   161 
   163 if os.environ.get('APYCOT_ROOT'):
   162 if os.environ.get('APYCOT_ROOT'):
   164     SCHEMAS_LIB_DIRECTORY = join(os.environ['APYCOT_ROOT'],
   163     SCHEMAS_LIB_DIRECTORY = join(os.environ['APYCOT_ROOT'],
   170     """high level method to load all the schema for a lax application"""
   169     """high level method to load all the schema for a lax application"""
   171     # IMPORTANT NOTE: dbmodel schemas must be imported **BEFORE**
   170     # IMPORTANT NOTE: dbmodel schemas must be imported **BEFORE**
   172     # the loader is instantiated because this is where the dbmodels
   171     # the loader is instantiated because this is where the dbmodels
   173     # are registered in the yams schema
   172     # are registered in the yams schema
   174     for compname in config['included-cubes']:
   173     for compname in config['included-cubes']:
   175         comp = __import__('%s.schema' % compname)
   174         __import__('%s.schema' % compname)
   176     loader = GaeSchemaLoader(use_gauthservice=config['use-google-auth'], db=db)
   175     loader = GaeSchemaLoader(use_gauthservice=config['use-google-auth'], db=db)
   177     loader.lib_directory = SCHEMAS_LIB_DIRECTORY
   176     loader.lib_directory = SCHEMAS_LIB_DIRECTORY
   178     if schemaclasses is not None:
   177     if schemaclasses is not None:
   179         for cls in schemaclasses:
   178         for cls in schemaclasses:
   180             loader.load_dbmodel(cls.__name__, goadb.extract_dbmodel(cls))
   179             loader.load_dbmodel(cls.__name__, goadb.extract_dbmodel(cls))
   181     elif config['schema-type'] == 'dbmodel':
   180     elif config['schema-type'] == 'dbmodel':
   182         import schema as appschema
   181         import schema as appschema
   183         for objname, obj in vars(appschema).items():
   182         for obj in vars(appschema).values():
   184             if isinstance(obj, type) and issubclass(obj, goadb.Model) and obj.__module__ == appschema.__name__:
   183             if isinstance(obj, type) and issubclass(obj, goadb.Model) and obj.__module__ == appschema.__name__:
   185                 loader.load_dbmodel(obj.__name__, goadb.extract_dbmodel(obj))
   184                 loader.load_dbmodel(obj.__name__, goadb.extract_dbmodel(obj))
   186     for erschema in ('EGroup', 'EEType', 'ERType', 'RQLExpression',
   185     for erschema in ('CWGroup', 'CWEType', 'CWRType', 'RQLExpression',
   187                      'is_', 'is_instance_of',
   186                      'is_', 'is_instance_of',
   188                      'read_permission', 'add_permission',
   187                      'read_permission', 'add_permission',
   189                      'delete_permission', 'update_permission'):
   188                      'delete_permission', 'update_permission'):
   190         loader.import_yams_schema(erschema, 'bootstrap')  
   189         loader.import_yams_schema(erschema, 'bootstrap')
   191     loader.handle_file(join(SCHEMAS_LIB_DIRECTORY, 'base.py'))
   190     loader.handle_file(join(SCHEMAS_LIB_DIRECTORY, 'base.py'))
   192     cubes = config['included-yams-cubes']
   191     cubes = config['included-yams-cubes']
   193     for cube in reversed(config.expand_cubes(cubes)):
   192     for cube in reversed(config.expand_cubes(cubes)):
   194         config.info('loading cube %s', cube)
   193         config.info('loading cube %s', cube)
   195         loader.import_yams_cube_schema(config.cube_dir(cube))
   194         loader.import_yams_cube_schema(config.cube_dir(cube))
   196     if config['schema-type'] == 'yams':
   195     if config['schema-type'] == 'yams':
   197         loader.import_yams_cube_schema('.')
   196         loader.import_yams_cube_schema('.')
   198     if extrahook is not None:
   197     if extrahook is not None:
   199         extrahook(loader)
   198         extrahook(loader)
   200     if config['use-google-auth']:
   199     if config['use-google-auth']:
   201         loader.defined['EUser'].remove_relation('upassword')
   200         loader.defined['CWUser'].remove_relation('upassword')
   202         loader.defined['EUser'].permissions['add'] = ()
   201         loader.defined['CWUser'].permissions['add'] = ()
   203         loader.defined['EUser'].permissions['delete'] = ()
   202         loader.defined['CWUser'].permissions['delete'] = ()
   204     for etype in ('EGroup', 'RQLExpression'):
   203     for etype in ('CWGroup', 'RQLExpression'):
   205         read_perm_rel = loader.defined[etype].get_relations('read_permission').next()
   204         read_perm_rel = loader.defined[etype].get_relations('read_permission').next()
   206         read_perm_rel.cardinality = '**'
   205         read_perm_rel.cardinality = '**'
   207     # XXX not yet ready for EUser workflow
   206     # XXX not yet ready for CWUser workflow
   208     loader.defined['EUser'].remove_relation('in_state')
   207     loader.defined['CWUser'].remove_relation('in_state')
   209     loader.defined['EUser'].remove_relation('wf_info_for')
   208     loader.defined['CWUser'].remove_relation('wf_info_for')
   210     # remove RQLConstraint('NOT O name "owners"') on EUser in_group EGroup
   209     # remove RQLConstraint('NOT O name "owners"') on CWUser in_group CWGroup
   211     # since "owners" group is not persistent with gae
   210     # since "owners" group is not persistent with gae
   212     loader.defined['EUser'].get_relations('in_group').next().constraints = []
   211     loader.defined['CWUser'].get_relations('in_group').next().constraints = []
   213     # return the full schema including the cubes' schema
   212     # return the full schema including the cubes' schema
   214     for ertype in loader.defined.values():
   213     for ertype in loader.defined.values():
   215         if getattr(ertype, 'inlined', False):
   214         if getattr(ertype, 'inlined', False):
   216             ertype.inlined = False
   215             ertype.inlined = False
   217     return loader.finalize()
   216     return loader.finalize()
   218