Code

Ticket #851: sqlaccess.py

File sqlaccess.py, 3.2 KB (added by aaronsw, 8 years ago)

Patch to proxy thd new SQL API to the old

Line 
1# TODO:
2# - automatically .save() by default (although you can turn it off)
3# - Map all Django lookup types
4# - Map all Django lookup functions
5
6mapping = {
7    '>': 'gt',
8    '<': 'lt',
9    '>=': 'ge',
10    '<=': 'le',
11    '==': 'eq',
12    '!=': 'ne'
13}
14
15u_mapping = {
16    '+': 'pos',
17    '-': 'neg',
18    '~': 'inv'
19}
20
21class Atom:
22    def __init__(self, start=(), modifiers=None):
23        self._start = start
24        self._modifiers = modifiers
25       
26        def makefunc(self, key):
27            return lambda x: Statement(self, key, x)
28
29        def u_makefunc(self, key):
30            return lambda x: Atom(self._start, key)
31       
32        for (key,val) in mapping.items():
33            setattr(self, '__'+val+'__', makefunc(self, key)) 
34       
35        for (key,val) in u_mapping.items():
36            setattr(self, '__'+val+'__', u_makefunc(self, key))
37   
38    def __pos__(self): return Atom(self._start, '+')
39   
40    def __getattr__(self, x):
41        if x.startswith('_'): return x.__dict__[x]
42        return Atom(self._start+(x,))
43   
44    def __repr__(self): return '.'.join(self._start)
45   
46    def _django(self): return '__'.join(self._start)
47           
48class Statement:
49    def __init__(self, atom, operator, value):
50        self._atom = atom
51        self._operator = operator
52        self._value = value
53       
54        if isinstance(value, Atom) and value._modifiers:
55            self._operator += value._modifiers
56
57    def __and__(self, x): return Group(self, 'and', x)
58    def __or__(self, x): return Group(self, 'or', y)
59   
60    def __repr__(self):
61        return repr(self._atom) + ' ' + self._operator + ' ' +repr(self._value)
62       
63    def _django(self):
64        mapping = {
65            '>': 'gt',
66            '<': 'lt',
67            '>=': 'gte',
68            '<=': 'lte',
69            '==': 'exact',
70            '!=': 'ne'
71        }
72           
73        return {self._atom._django() + '__' + mapping[self._operator]:self._value}
74
75class Group:
76    def __init__(self, stmt1, operator, stmt2):
77        self._stmt1 = stmt1
78        self._operator = operator
79        self._stmt2 = stmt2
80   
81    def __repr__(self):
82        return '('+repr(self._stmt1)+') ' + self._operator + ' ('+repr(self._stmt2)+')'
83   
84    def _django(self):
85        if self._operator == 'and':
86            return self._stmt1._django() + self._stmt2._django()
87        else:
88            raise "I don't think Django supports that operator."
89
90q = Atom()
91
92## django-specific below this line
93
94class Table:
95    def __init__(self, table):
96        self.table = table
97       
98    def get(self, *args):
99        query = {}
100        for x in args:
101            query.update(x._django())
102        return Result(self.table, query)
103   
104class Result:
105    def __init__(self, table, query):
106        self.table = table
107        self.query = query
108
109    def __getitem__(self, x):
110        if x == 0: return self.table.get_object(**self.query)
111        else: 
112            iterator = self.table.get_iterator(**self.query)
113            i = -1
114            while i != x:
115                iterator.next()
116                i += 1
117            return iterator.next()
118   
119    def __len__(self): return self.table.get_count(**self.query)
120   
121    def __iter__(self):
122        return self.table.get_iterator(**self.query)