Browse Source

Datasources plugins enhancement and loading bugfixes

- now we have a LodelHook to trigger migration handlers loading
- datasources initialization in dyncode is now trigger by a hook (lodel2_plugin_loaded)
- datasources loading by dyncode is better
Yann Weber 8 years ago
parent
commit
9a82936fbf

+ 14
- 5
lodel/leapi/lefactory.py View File

@@ -15,6 +15,7 @@ def dyncode_from_em(model):
15 15
     # Header
16 16
     imports = """from lodel.leapi.leobject import LeObject
17 17
 from lodel.leapi.datahandlers.base_classes import DataField
18
+from lodel.plugin.hooks import LodelHook
18 19
 """
19 20
     for module in modules:
20 21
         imports += "import %s\n" % module
@@ -27,14 +28,27 @@ from lodel.leapi.datahandlers.base_classes import DataField
27 28
 {classes}
28 29
 {bootstrap_instr}
29 30
 dynclasses = {class_list}
31
+{init_hook}
30 32
 """.format(
31 33
             imports = imports,
32 34
             classes = cls_code,
33 35
             bootstrap_instr = bootstrap_instr,
34 36
             class_list = '[' + (', '.join([cls for cls in class_list]))+']',
37
+            init_hook = datasource_init_hook(),
35 38
     )
36 39
     return res_code
37 40
 
41
+##@brief Produce the source code of the LodelHook that initialize datasources
42
+#in dyncode
43
+#@return str
44
+def datasource_init_hook():
45
+    return """
46
+@LodelHook("lodel2_plugins_loaded")
47
+def lodel2_dyncode_datasources_init(self, caller, payload):
48
+    for cls in dynclasses:
49
+        cls._init_datasources()
50
+"""
51
+
38 52
 ##@brief return A list of EmClass sorted by dependencies
39 53
 #
40 54
 # The first elts in the list depends on nothing, etc.
@@ -134,10 +148,5 @@ class {clsname}({parents}):
134 148
     fields = '{' + (', '.join(['\n\t%s: %s' % (repr(emfield.uid),data_handler_constructor(emfield)) for emfield in em_class.fields()])) + '}',
135 149
 )
136 150
     bootstrap += "\n"
137
-    for em_class in get_classes(model):
138
-        # Dyncode datasource bootstrap instructions
139
-        bootstrap += """{classname}._init_datasources()
140
-""".format(
141
-            classname = LeObject.name2objname(em_class.uid))
142 151
     return res, set(imports), bootstrap
143 152
     

+ 1
- 2
lodel/leapi/leobject.py View File

@@ -229,11 +229,10 @@ a read only as a read&write datasource"
229 229
 
230 230
         ds_conf = getattr(ds_conf, ds_name)
231 231
         #Checks that the datasource plugin exists
232
-        ds_plugin_module = Plugin.get(ds_plugin).module
232
+        ds_plugin_module = Plugin.get(ds_plugin).loader_module()
233 233
         try:
234 234
             datasource_class = getattr(ds_plugin_module, "Datasource")
235 235
         except AttributeError as e:
236
-            raise e
237 236
             expt_msg += "The datasource plugin %s seems to be invalid. Error \
238 237
 raised when trying to import Datasource"
239 238
             expt_msg %= ds_identifier

+ 15
- 3
lodel/plugin/plugins.py View File

@@ -60,8 +60,11 @@ class Plugin(object):
60 60
         self.started()
61 61
         self.name = plugin_name
62 62
         self.path = self.plugin_path(plugin_name)
63
-
63
+        
64
+        ##@brief Stores the plugin module
64 65
         self.module = None
66
+        ##@breif Stores the plugin loader module
67
+        self.__loader_module = None
65 68
         self.__confspecs = dict()
66 69
         self.loaded = False
67 70
         
@@ -110,6 +113,7 @@ class Plugin(object):
110 113
 
111 114
     ##@brief Try to import a file from a variable in __init__.py
112 115
     #@param varname str : The variable name
116
+    #@return loaded module
113 117
     #@throw AttributeError if varname not found
114 118
     #@throw ImportError if the file fails to be imported
115 119
     #@throw PluginError if the filename was not valid
@@ -208,7 +212,7 @@ class Plugin(object):
208 212
         
209 213
         #Loading the plugin
210 214
         try:
211
-            self._import_from_init_var(LOADER_FILENAME_VARNAME)
215
+            self.__loader_module = self._import_from_init_var(LOADER_FILENAME_VARNAME)
212 216
         except AttributeError:
213 217
             msg = "Malformed plugin {plugin}. No {varname} found in __init__.py"
214 218
             msg = msg.format(
@@ -223,7 +227,12 @@ class Plugin(object):
223 227
             raise PluginError(msg)
224 228
         logger.debug("Plugin '%s' loaded" % self.name)
225 229
         self.loaded = True
226
-             
230
+    
231
+    def loader_module(self):
232
+        if not self.loaded:
233
+            raise RuntimeError("Plugin %s not loaded yet."%self.name)
234
+        return self.__loader_module
235
+
227 236
     ##@brief Call load method on every pre-loaded plugins
228 237
     #
229 238
     # Called by loader to trigger hooks registration.
@@ -245,6 +254,9 @@ class Plugin(object):
245 254
                 msg += "\n\t%20s : %s" % (name,e)
246 255
             msg += "\n"
247 256
             raise PluginError(msg)
257
+        from lodel.plugin.hooks import LodelHook
258
+        LodelHook.call_hook(
259
+            "lodel2_plugins_loaded", cls, cls._plugin_instances)
248 260
     
249 261
     ##@return a copy of __confspecs attr
250 262
     @property

+ 1
- 1
plugins/dummy_datasource/__init__.py View File

@@ -1,5 +1,5 @@
1 1
 from lodel.settings.validator import SettingValidator
2
-from .main import DummyDatasource as Datasource
2
+from .datasource import DummyDatasource as Datasource
3 3
 
4 4
 __loader__ = 'main.py'
5 5
 __plugin_deps__ = []

+ 5
- 49
plugins/dummy_datasource/main.py View File

@@ -1,53 +1,9 @@
1 1
 #-*- coding:utf-8 -*-
2 2
 
3
-class DummyDatasource(object):
4
-    
5
-    def __init__(self, *conn_args, **conn_kwargs):
6
-        self.conn_args = conn_args
7
-        self.conn_kwargs = conn_kwargs
3
+from lodel.plugin import LodelHook
4
+from .datasource import DummyDatasource as Datasource
8 5
 
9
-    ## @brief returns a selection of documents from the datasource
10
-    # @param target_cls Emclass
11
-    # @param field_list list
12
-    # @param filters list : List of filters
13
-    # @param rel_filters list : List of relational filters
14
-    # @param order list : List of column to order. ex: order = [('title', 'ASC'),]
15
-    # @param group list : List of tupple representing the column to group together. ex: group = [('title', 'ASC'),]
16
-    # @param limit int : Number of records to be returned
17
-    # @param offset int: used with limit to choose the start record
18
-    # @param instanciate bool : If true, the records are returned as instances, else they are returned as dict
19
-    # @return list
20
-    def select(self, target_cls, field_list, filters, rel_filters=None, order=None, group=None, limit=None, offset=0,
21
-               instanciate=True):
22
-        pass
6
+@LodelHook('datasources_migration_init')
7
+def dummy_migration_handler_init():
8
+    from .migration_handler import DummyMigrationHandler as migration_handler
23 9
 
24
-    ##@brief Deletes records according to given filters
25
-    #@param target Emclass : class of the record to delete
26
-    #@param filters list : List of filters
27
-    #@param relational_filters list : List of relational filters
28
-    #@return int : number of deleted records
29
-    def delete(self, target, filters, relational_filters):
30
-        pass
31
-
32
-    ## @brief updates records according to given filters
33
-    #@param target Emclass : class of the object to insert
34
-    #@param filters list : List of filters
35
-    #@param rel_filters list : List of relational filters
36
-    #@param upd_datas dict : datas to update (new values)
37
-    #@return int : Number of updated records
38
-    def update(self, target, filters, relational_filters, upd_datas):
39
-        pass
40
-
41
-    ## @brief Inserts a record in a given collection
42
-    # @param target Emclass : class of the object to insert
43
-    # @param new_datas dict : datas to insert
44
-    # @return the inserted uid
45
-    def insert(self, target, new_datas):
46
-        pass
47
-
48
-    ## @brief Inserts a list of records in a given collection
49
-    # @param target Emclass : class of the objects inserted
50
-    # @param datas_list list : list of dict
51
-    # @return list : list of the inserted records' ids
52
-    def insert_multi(self, target, datas_list):
53
-        pass

+ 2
- 10
plugins/mongodb_datasource/__init__.py View File

@@ -1,3 +1,4 @@
1
+#-*- coding: utf-8 -*-
1 2
 from .utils import connect, get_connection_args
2 3
 
3 4
 __loader__ = "main.py"
@@ -12,13 +13,4 @@ __fullname__ = "MongoDB plugin"
12 13
 #
13 14
 # @return bool|str : True if all the checks are OK, an error message if not
14 15
 def _activate():
15
-    default_connection_args = get_connection_args()
16
-    connection_check = connect(
17
-        default_connection_args['host'],
18
-        default_connection_args['port'],
19
-        default_connection_args['db_name'],
20
-        default_connection_args['username'],
21
-        default_connection_args['password'])
22
-    if not connection_check:
23
-        return False
24
-    return True
16
+    return True

+ 2
- 5
plugins/mongodb_datasource/main.py View File

@@ -1,11 +1,8 @@
1 1
 from lodel.plugin import LodelHook
2 2
 
3
+from .datasource import MongoDbDatasource as Datasource
3 4
 
4
-@LodelHook('mongodb_mh_init')
5
+@LodelHook('datasources_migration_init')
5 6
 def mongodb_migration_handler_init():
6 7
     import plugins.mongodb_datasource.migration_handler as migration_handler
7 8
 
8
-
9
-@LodelHook('mongodb_ds_init')
10
-def mongodb_datasource_init():
11
-    import plugins.mongodb_datasource.datasource as datasource

Loading…
Cancel
Save