Statistics
| Branch: | Tag: | Revision:

root / snf-quotaholder-app / quotaholder_django / quotaholder_app / models.py @ 39462ae0

History | View | Annotate | Download (8.5 kB)

1
# Copyright 2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34

    
35
from synnefo.lib.commissioning import CorruptedError
36

    
37
from django.core import exceptions
38
from django.db.models import (Model, BigIntegerField, CharField,
39
                              IntegerField, SubfieldBase,
40
                              ForeignKey, AutoField, DecimalField)
41
from django.db import transaction
42
from .managers import ForUpdateManager
43

    
44
class IntDecimalField(IntegerField):
45

    
46
    __metaclass__ = SubfieldBase
47

    
48
    def __init__(self, max_digits=None, **kwargs):
49
        self.max_digits, self.decimal_places = max_digits, 0
50
        IntegerField.__init__(self, **kwargs)
51

    
52
    def get_internal_type(self):
53
        return "DecimalField"
54

    
55
    def to_python(self, value):
56
        if value is None:
57
            return value
58
        try:
59
            return long(value)
60
        except (ValueError, TypeError):
61
            raise exceptions.ValidationError(self.error_messages['invalid'])
62

    
63
DECIMAL_DIGITS  =   38
64

    
65
def intDecimalField(**kwargs):
66
    return IntDecimalField(max_digits=DECIMAL_DIGITS, **kwargs)
67

    
68
class Holder(Model):
69

    
70
    attribute   =   CharField(max_length=4096, primary_key=True)
71
    intval      =   BigIntegerField()
72
    strval      =   CharField(max_length=4096)
73

    
74
    objects     =   ForUpdateManager()
75

    
76
class Entity(Model):
77

    
78
    entity      =   CharField(max_length=4096, primary_key=True)
79
    owner       =   ForeignKey('self', to_field='entity',
80
                               related_name='entities')
81
    key         =   CharField(max_length=4096, null=False)
82

    
83
    objects     =   ForUpdateManager()
84

    
85
class Policy(Model):
86

    
87
    policy          =   CharField(max_length=4096, primary_key=True)
88
    quantity        =   intDecimalField()
89
    capacity        =   intDecimalField()
90
    import_limit    =   intDecimalField()
91
    export_limit    =   intDecimalField()
92

    
93
    objects     =   ForUpdateManager()
94

    
95
class Holding(Model):
96

    
97
    entity      =   ForeignKey(Entity, to_field='entity')
98
    resource    =   CharField(max_length=4096, null=False)
99

    
100
    policy      =   ForeignKey(Policy, to_field='policy')
101
    flags       =   BigIntegerField(null=False, default=0)
102

    
103
    imported    =   intDecimalField(default=0)
104
    importing   =   intDecimalField(default=0)
105
    exported    =   intDecimalField(default=0)
106
    exporting   =   intDecimalField(default=0)
107
    returned    =   intDecimalField(default=0)
108
    returning   =   intDecimalField(default=0)
109
    released    =   intDecimalField(default=0)
110
    releasing   =   intDecimalField(default=0)
111

    
112
    objects     =   ForUpdateManager()
113

    
114
    class Meta:
115
        unique_together = (('entity', 'resource'),)
116

    
117

    
118
from datetime import datetime
119

    
120
def now():
121
    return datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f')[:24]
122

    
123

    
124
class Commission(Model):
125

    
126
    serial      =   AutoField(primary_key=True)
127
    entity      =   ForeignKey(Entity, to_field='entity')
128
    name        =   CharField(max_length=4096, null=True)
129
    clientkey   =   CharField(max_length=4096, null=False)
130
    issue_time  =   CharField(max_length=24, default=now)
131

    
132
    objects     =   ForUpdateManager()
133

    
134
class Provision(Model):
135

    
136
    serial      =   ForeignKey( Commission,
137
                                to_field='serial',
138
                                related_name='provisions'   )
139

    
140
    entity      =   ForeignKey(Entity, to_field='entity')
141
    resource    =   CharField(max_length=4096, null=False)
142
    quantity    =   intDecimalField()
143

    
144
    objects     =   ForUpdateManager()
145

    
146
class ProvisionLog(Model):
147

    
148
    serial              =   BigIntegerField()
149
    source              =   CharField(max_length=4096)
150
    target              =   CharField(max_length=4096)
151
    name                =   CharField(max_length=4096)
152
    issue_time          =   CharField(max_length=4096)
153
    log_time            =   CharField(max_length=4096)
154
    resource            =   CharField(max_length=4096)
155
    source_quantity     =   intDecimalField()
156
    source_capacity     =   intDecimalField()
157
    source_import_limit =   intDecimalField()
158
    source_export_limit =   intDecimalField()
159
    source_imported     =   intDecimalField()
160
    source_exported     =   intDecimalField()
161
    source_returned     =   intDecimalField()
162
    source_released     =   intDecimalField()
163
    target_quantity     =   intDecimalField()
164
    target_capacity     =   intDecimalField()
165
    target_import_limit =   intDecimalField()
166
    target_export_limit =   intDecimalField()
167
    target_imported     =   intDecimalField()
168
    target_exported     =   intDecimalField()
169
    target_returned     =   intDecimalField()
170
    target_released     =   intDecimalField()
171
    delta_quantity      =   intDecimalField()
172
    reason              =   CharField(max_length=4096)
173

    
174
    objects     =   ForUpdateManager()
175

    
176
    def source_allocated_through(self):
177
        return self.source_imported - self.source_released
178

    
179
    def source_allocated(self):
180
        return (+ self.source_allocated_through()
181
                - self.source_exported
182
                + self.source_returned)
183

    
184
    def source_inbound_through(self):
185
        return self.source_imported
186

    
187
    def source_inbound(self):
188
        return self.source_inbound_through() + self.source_returned
189

    
190
    def source_outbound_through(self):
191
        return self.source_released
192

    
193
    def source_outbound(self):
194
        return self.source_outbound_through() + self.source_exported
195

    
196
    def target_allocated_through(self):
197
        return self.target_imported - self.target_released
198

    
199
    def target_allocated(self):
200
        return (+ self.target_allocated_through()
201
                - self.target_exported
202
                + self.target_returned)
203

    
204
    def target_inbound_through(self):
205
        return self.target_imported
206

    
207
    def target_inbound(self):
208
        return self.target_inbound_through() + self.target_returned
209

    
210
    def target_outbound_through(self):
211
        return self.target_released
212

    
213
    def target_outbound(self):
214
        return self.target_outbound_through() + self.target_exported
215

    
216
class CallSerial(Model):
217

    
218
    serial      =   BigIntegerField(null=False)
219
    clientkey   =   CharField(max_length=4096, null=False)
220

    
221
    objects     =   ForUpdateManager()
222

    
223
    class Meta:
224
        unique_together = (('serial', 'clientkey'),)
225

    
226

    
227
def _access(*args, **kwargs):
228
    method = args[0]
229
    model = args[1]
230
    args = args[2:]
231
    o = model.objects
232
    try:
233
        if kwargs['for_update']:
234
            del kwargs['for_update']
235
            o = o.select_for_update()
236
    except KeyError:
237
        pass
238
    f = getattr(o, method)
239
    return f(*args, **kwargs)
240

    
241
def _get(*args, **kwargs):
242
    return _access('get', *args, **kwargs)
243

    
244
def _filter(*args, **kwargs):
245
    return _access('filter', *args, **kwargs)
246

    
247
def db_get_holding(*args, **kwargs):
248
    return _get(Holding, *args, **kwargs)
249

    
250
def db_get_entity(*args, **kwargs):
251
    return _get(Entity, *args, **kwargs)
252

    
253
def db_get_policy(*args, **kwargs):
254
    return _get(Policy, *args, **kwargs)
255

    
256
def db_get_commission(*args, **kwargs):
257
    return _get(Commission, *args, **kwargs)
258

    
259
def db_get_callserial(*args, **kwargs):
260
    return _get(CallSerial, *args, **kwargs)
261

    
262
def db_filter_provision(*args, **kwargs):
263
    return _filter(Provision, *args, **kwargs)