source: mauRepo/MolesManager/trunk/src/libs/epb.py @ 8435

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/mauRepo/MolesManager/trunk/src/libs/epb.py@8435
Revision 8435, 8.7 KB checked in by mnagni, 7 years ago (diff)

Corrects how the CEDA_Observation.phenomenonTime both in the ingestion side and in the GUI side.
"Should" not require a brand new db migration

Line 
1'''
2BSD Licence
3Copyright (c) 2012, Science & Technology Facilities Council (STFC)
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without modification,
7are permitted provided that the following conditions are met:
8
9    * Redistributions of source code must retain the above copyright notice,
10        this list of conditions and the following disclaimer.
11    * Redistributions in binary form must reproduce the above copyright notice,
12        this list of conditions and the following disclaimer in the documentation
13        and/or other materials provided with the distribution.
14    * Neither the name of the Science & Technology Facilities Council (STFC)
15        nor the names of its contributors may be used to endorse or promote
16        products derived from this software without specific prior written permission.
17
18THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29Created on 10 Jan 2012
30
31@author: Maurizio Nagni
32'''
33from sqlalchemy.orm import subqueryload
34from sqlalchemy.sql.expression import text
35from MolesManager.forms.date import methodsWithDecorator
36
37class EPB(object):
38
39    @classmethod
40    def buildFilter(cls, key, keyValue):
41        try:
42            return '%s = \'%s\'' % (key, keyValue)
43        except RuntimeError as er:
44            print er
45
46    @classmethod
47    def search(cls, clazz, inst_key, session):
48        """
49            Searches a required instance by id
50            @param clazz: the class type to search for
51            @param inst_key: the instance id for which the search is done. If None return a query object
52            @param session: a session to use for the query
53            @return the required instance
54        """
55        if inst_key:
56            res = session.query(clazz).get(inst_key)
57        else:
58            res = session.query(clazz)
59           
60        if res is None:
61            return None
62        return res           
63       
64
65
66    @classmethod
67    def searchEager(cls, clazz, inst_id, session):
68        """
69            Searches a required instance by id loading eagerly ALL its field. Please use carefully because \
70            it could impact the performance
71            @param clazz: the class type to search for
72            @param inst_id: the instance id for which the search is done
73            @param session: a session to use for the query   
74            @return the required instance                   
75        """
76        res = session.query(clazz).options(subqueryload('*')).get(inst_id)
77        if res is None:
78            return None
79           
80        return res
81
82    @classmethod
83    def searchSelectiveLoad(cls, clazz, inst_id, attrs, session):
84        """
85            Searches a required instance by id loading \
86            the specified fields. The parameter "attrs" is a single string or a list of attributes
87            owned by the instance of "clazz". Furthermore such list may contain
88            also the children of the main attributes. For example "attrs" may look
89            like
90            ['resultAccumulation', 'identifier.authority', 'resultTime.position.dateTime8601.month', \
91                      'relatedParty.party', 'result.source.function', 'permission', \
92                      'geographicExtent', 'phenomenonTime', 'keywords', 'description', \
93                      'inSupportOf.abstract', 'dataLineage']
94            the first parameter refers to the main class so is equivalent to
95            clazz.resultAccumulation
96            the second parameter is equivalent to invoke
97            clazz.identifier.authority
98            As single string "attrs" could be as well just 'identifier.authority'
99            @param clazz: the class type to search for
100            @param inst_id: the instance id for which the search is done
101            @param attrs: a single string or a list of attributes to load
102            @param session: a session to use for the query
103            @return the required instance             
104        """         
105        if session is None:
106            raise Exception("Session is None!")       
107        res = EPB.search(clazz, inst_id, session)
108        if res is None:
109            return None
110        EPB._drillData(res, attrs)
111        return res
112
113    @classmethod
114    def loadAttributes(cls, instance, attributes, session):
115        """
116            Loads the given instance with the required attributes.
117            The parameter "attributes" is a single string or a list of attributes
118            owned by the instance of "clazz". Furthermore such list may contain
119            also the children of the main attributes. For example "attrs" may look
120            like
121            ['resultAccumulation', 'identifier.authority', 'resultTime.position.dateTime8601.month', \
122                      'relatedParty.party', 'result.source.function', 'permission', \
123                      'geographicExtent', 'phenomenonTime.*', 'keywords', 'description', \
124                      'inSupportOf.abstract', 'dataLineage']
125            the first parameter refers to the main class so is equivalent to
126            instance.resultAccumulation
127            the second parameter is equivalent to invoke
128            instance.identifier.authority
129            As single string "attributes" could be as well just 'identifier.authority'
130            An universal marker '*' can be used to request a full loading from the attribute downward
131            It does not return anything because it does not close the session
132            @param instance: an instance containing the appropriate id
133            @param attributes: a single string or a list of attributes to load
134            @param session: the session to use for the operation                             
135        """
136        if instance is None:
137            raise Exception("Instance is None!")
138        if session is None:
139            raise Exception("Session is None!")
140        session.merge(instance)
141        EPB._drillData(instance, attributes)                   
142
143
144    @classmethod   
145    def searchOrCreate(cls, clazz, session, clazz_id = None):
146        if clazz_id is not None:
147            return EPB.search(clazz, clazz_id, session)
148        else:                       
149            return clazz()
150       
151
152    @classmethod
153    def getAllObjects(cls, clazz, session):     
154        res = session.query(clazz)
155        if res is None:
156            return None
157        return res
158
159    @classmethod
160    def executeNative(self, sqlNative, session):
161        return session.execute(text(sqlNative))     
162
163    @classmethod
164    def _getSession(cls, dbManager, session = None):
165        if session:
166            return session       
167        return dbManager.createDbSession()
168
169    @classmethod
170    def _drillData(cls, obj, attrs):
171        """
172            @param obj: its an instance already living inside an SQLAlchemy session
173            @param attrs: a list of attributes owned by the obj parameter. It accepts dot separated attributes as childern of obj attributes.
174        """
175        #if is a single field wrap it in a list and recalls itself
176        if not isinstance(attrs, list):
177            EPB._drillData(obj, [attrs])
178        for item in attrs:
179            attr = item.split('.')[0] 
180            if attr == '*':
181                EPB._drillALLData(obj)         
182            elif isinstance(obj, list):
183                for element in obj:
184                    EPB._drillData(element, [item])
185            else:
186                if hasattr(obj, attr):
187                    nobj = getattr(obj, attr) 
188                    if len(attr) != len(item):
189                        EPB._drillData(nobj, [item[len(attr) + 1:]])
190
191    @classmethod
192    def _drillALLData(cls, obj):
193        if isinstance(obj, list):
194            for element in obj:
195                EPB._drillALLData(element)
196        else:
197            keys = dir(obj)
198            keys.extend(list(methodsWithDecorator(type(obj), "property")))
199            for key in keys:
200                try:
201                    if '_' not in key:
202                        nobj = getattr(obj, key)
203                        EPB._drillALLData(nobj)
204                except Exception as e:
205                    pass
206       
Note: See TracBrowser for help on using the repository browser.