Contact: fumanchu@aminus.org

Log in as guest/dejavu to create tickets

I think I've seen this ORM somewhere before...

root/trunk/storage/storeodbc.py

Revision 46 (checked in by fumanchu, 8 years ago)

1. Changed AdapterFromDB to take unit arg only on consume.
2. Abstracted SM's into db.StorageManagerDB base class. All stores now have save_expanded functionality.
3. Fixed storeodbc. Finally.
4. Added decimal.Decimal to adapters.
5. New precision, scale hints. db.FieldTypeAdapter? has new numeric_max_precision attribute.
6. Broke chunks of modeling.html out into managing.html.
7. New tests in zoo_fixture.

Line 
1 """ODBC Storage Manager for Dejavu."""
2
3 import dbi, odbc
4 import threading
5 import warnings
6 import datetime
7 from dejavu import logic
8 from dejavu.storage import db
9
10
11 class FieldTypeAdapterODBC(db.FieldTypeAdapter):
12    
13     # dbiDate objects have limited range. Use strings instead.
14     def coerce_datetime_datetime(self, cls, key): return u"CHAR(19)"
15     def coerce_datetime_date(self, cls, key): return u"CHAR(10)"
16     def coerce_datetime_time(self, cls, key): return u"CHAR(8)"
17    
18     def coerce_decimal_Decimal(self, cls, key):
19         warnings.warn("The precision of %s.%s cannot be determined for "
20                       "ODBC stores. Values may be stored incorrectly."
21                       % (cls.__name__, key))
22         return u"NUMERIC"
23    
24     def coerce_fixedpoint_FixedPoint(self, cls, key):
25         warnings.warn("The precision of %s.%s cannot be determined for "
26                       "ODBC stores. Values may be stored incorrectly."
27                       % (cls.__name__, key))
28         return u"NUMERIC"
29    
30     def coerce_long(self, cls, key):
31         prop = getattr(cls, key)
32         bytes = int(prop.hints.get(u'bytes', 0))
33         if bytes <= 4:
34             return self.coerce_int(cls, key)
35         elif bytes <= 8:
36             # BIGINT is usually 8 bytes
37             return "BIGINT"
38         # Anything larger than 8 bytes, use decimal/numeric.
39         warnings.warn("The precision of %s.%s cannot be determined for "
40                       "ODBC stores. Values may be stored incorrectly."
41                       % (cls.__name__, key))
42         return u"NUMERIC"
43
44
45 class SQLDecompilerODBC(db.SQLDecompiler):
46    
47     # --------------------------- Dispatchees --------------------------- #
48    
49     def dejavu_icontainedby(self, op1, op2):
50         if isinstance(op1, db.ConstWrapper):
51             # Looking for text in a field. Use Like (reverse terms).
52             return "{fn LCASE(" + op2 + ")} LIKE '%" + op1.strip("'\"").lower() + "%'"
53         else:
54             # Looking for field in (a, b, c).
55             # Force all args to lowercase for case-insensitive comparison.
56             atoms = [self.adapter.coerce(x).lower() for x in op2.basevalue]
57             return "{fn LCASE(%s)} IN (%s)" % (op1, ", ".join(atoms))
58    
59     def dejavu_icontains(self, x, y):
60         return self.dejavu_icontainedby(y, x)
61    
62     def dejavu_istartswith(self, x, y):
63         y = y.strip("'\"")
64         return "{fn LCASE(" + x + ")} LIKE '" + y + "%'"
65    
66     def dejavu_iendswith(self, x, y):
67         y = y.strip("'\"")
68         return "{fn LCASE(" + x + ")} LIKE '%" + y + "'"
69    
70     def dejavu_ieq(self, x, y):
71         return "{fn LCASE(" + x + ")} = {fn LCASE(" + y + ")}"
72    
73     def dejavu_now(self):
74         return self.adapter.coerce(datetime.datetime.now())
75    
76     def dejavu_today(self):
77         return self.adapter.coerce(datetime.date.today())
78    
79     def dejavu_year(self, x):
80 ##        return "{fn DATEPART(year, " + x + ")}"
81         self.imperfect = True
82         return db.cannot_represent
83    
84     def func__builtin___len(self, x):
85         return "{fn LENGTH(" + x + ")}"
86
87
88 class StorageManagerODBC(db.StorageManagerDB):
89     """StoreManager to save and retrieve Dejavu Units via ODBC."""
90    
91     identifier_caseless = True
92     decompiler = SQLDecompilerODBC
93     typeAdapter = FieldTypeAdapterODBC()
94    
95     def __init__(self, name, arena, allOptions={}):
96         db.StorageManagerDB.__init__(self, name, arena, allOptions)
97         self.connstring = allOptions['Connect']
98    
99     def _get_conn(self):
100         return odbc.odbc(self.connstring)
101    
102     def execute(self, query, conn=None):
103         """execute(query, conn=None) -> result set."""
104         if conn is None:
105             conn = self.connection()
106         try:
107             cursor = conn.cursor()
108             cursor.execute(query)
109             return cursor
110         except Exception, x:
111             x.args += (query,)
112             raise x
113         except dbi.progError, x:
114             # Force query to string type
115             x += "\n" + str(query)
116             raise x
117    
118     def fetch(self, query, conn=None):
119         """fetch(query, conn=None) -> rowdata, columns."""
120         res = self.execute(query, conn)
121         return res.fetchall(), res.description
122    
123     def create_database(self):
124         raise NotImplementedError
125    
126     def drop_database(self):
127         raise NotImplementedError
128
Note: See TracBrowser for help on using the browser.