[Sqlalchemy-commits] [1355] sqlalchemy/trunk/test: *another* big types change....the old way was sti
Brought to you by:
zzzeek
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><style type="text/css"><!-- #msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; } #msg dt { float: left; width: 6em; font-weight: bold; } #msg dt:after { content:':';} #msg dl, #msg dt, #msg ul, #msg li { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; } #msg dl a { font-weight: bold} #msg dl a:link { color:#fc3; } #msg dl a:active { color:#ff0; } #msg dl a:visited { color:#cc6; } h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; } #msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; } #msg ul, pre { overflow: auto; } #patch { width: 100%; } #patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;} #patch .propset h4, #patch .binary h4 {margin:0;} #patch pre {padding:0;line-height:1.2em;margin:0;} #patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;} #patch .propset .diff, #patch .binary .diff {padding:10px 0;} #patch span {display:block;padding:0 10px;} #patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;} #patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;} #patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;} #patch .lines, .info {color:#888;background:#fff;} --></style> <title>[1355] sqlalchemy/trunk/test: *another* big types change....the old way was still wrong...this way is better (still need to go through it again since i am apparently type-impaired....)</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1355</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-04-28 20:05:13 -0500 (Fri, 28 Apr 2006)</dd> </dl> <h3>Log Message</h3> <pre>*another* big types change....the old way was still wrong...this way is better (still need to go through it again since i am apparently type-impaired....)</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemydatabasesmysqlpy">sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemytypespy">sqlalchemy/trunk/lib/sqlalchemy/types.py</a></li> <li><a href="#sqlalchemytrunktesttesttypespy">sqlalchemy/trunk/test/testtypes.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemydatabasesmysqlpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py (1354 => 1355)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py 2006-04-29 00:08:07 UTC (rev 1354) +++ sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py 2006-04-29 01:05:13 UTC (rev 1355) </span><span class="lines">@@ -79,6 +79,11 @@ </span><span class="cx"> return "BINARY(%d)" % self.length </span><span class="cx"> else: </span><span class="cx"> return "BLOB" </span><ins>+ def convert_result_value(self, value, engine): + if value is None: + return None + else: + return buffer(value) </ins><span class="cx"> </span><span class="cx"> class MSBoolean(sqltypes.Boolean): </span><span class="cx"> def get_col_spec(self): </span><span class="lines">@@ -142,7 +147,6 @@ </span><span class="cx"> </span><span class="cx"> def type_descriptor(self, typeobj): </span><span class="cx"> return sqltypes.adapt_type(typeobj, colspecs) </span><del>- </del><span class="cx"> def last_inserted_ids(self): </span><span class="cx"> return self.context.last_inserted_ids </span><span class="cx"> </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemytypespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/types.py (1354 => 1355)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/types.py 2006-04-29 00:08:07 UTC (rev 1354) +++ sqlalchemy/trunk/lib/sqlalchemy/types.py 2006-04-29 01:05:13 UTC (rev 1355) </span><span class="lines">@@ -17,9 +17,7 @@ </span><span class="cx"> except: </span><span class="cx"> import pickle </span><span class="cx"> </span><del>-class TypeEngine(object): - def __init__(self, *args, **kwargs): - pass </del><ins>+class AbstractType(object): </ins><span class="cx"> def _get_impl_dict(self): </span><span class="cx"> try: </span><span class="cx"> return self._impl_dict </span><span class="lines">@@ -27,32 +25,45 @@ </span><span class="cx"> self._impl_dict = {} </span><span class="cx"> return self._impl_dict </span><span class="cx"> impl_dict = property(_get_impl_dict) </span><ins>+ def get_constructor_args(self): + return {} + def adapt_args(self): + return self + +class TypeEngine(AbstractType): + def __init__(self, *args, **params): + pass </ins><span class="cx"> def engine_impl(self, engine): </span><span class="cx"> try: </span><span class="cx"> return self.impl_dict[engine] </span><span class="cx"> except: </span><span class="cx"> return self.impl_dict.setdefault(engine, engine.type_descriptor(self)) </span><del>- def _get_impl(self): - if hasattr(self, '_impl'): - return self._impl - else: - return NULLTYPE - def _set_impl(self, impl): - self._impl = impl - impl = property(_get_impl, _set_impl) </del><span class="cx"> def get_col_spec(self): </span><ins>+ raise NotImplementedError() + def convert_bind_param(self, value, engine): + return value + def convert_result_value(self, value, engine): + return value + +class TypeDecorator(AbstractType): + def __init__(self, *args, **params): + pass + def engine_impl(self, engine): + try: + return self.impl_dict[engine] + except: + typedesc = engine.type_descriptor(self.impl) + tt = self.__class__(**self.get_constructor_args()) + tt.impl = typedesc + self.impl_dict[engine] = tt + return tt + def get_col_spec(self): </ins><span class="cx"> return self.impl.get_col_spec() </span><span class="cx"> def convert_bind_param(self, value, engine): </span><span class="cx"> return self.impl.convert_bind_param(value, engine) </span><span class="cx"> def convert_result_value(self, value, engine): </span><span class="cx"> return self.impl.convert_result_value(value, engine) </span><del>- def set_impl(self, impltype): - self.impl = impltype(**self.get_constructor_args()) - def get_constructor_args(self): - return {} - def adapt_args(self): - return self - </del><ins>+ </ins><span class="cx"> def to_instance(typeobj): </span><span class="cx"> if typeobj is None: </span><span class="cx"> return NULLTYPE </span><span class="lines">@@ -73,9 +84,7 @@ </span><span class="cx"> else: </span><span class="cx"> # couldnt adapt...raise exception ? </span><span class="cx"> return typeobj </span><del>- typeobj.set_impl(impltype) - typeobj.impl.impl = NULLTYPE - return typeobj </del><ins>+ return impltype(**t2.get_constructor_args()) </ins><span class="cx"> </span><span class="cx"> class NullTypeEngine(TypeEngine): </span><span class="cx"> def get_col_spec(self): </span><span class="lines">@@ -85,11 +94,7 @@ </span><span class="cx"> def convert_result_value(self, value, engine): </span><span class="cx"> return value </span><span class="cx"> </span><del>-class TypeDecorator(object): - """TypeDecorator is deprecated""" - pass </del><span class="cx"> </span><del>- </del><span class="cx"> class String(TypeEngine): </span><span class="cx"> def __init__(self, length = None): </span><span class="cx"> self.length = length </span><span class="lines">@@ -111,7 +116,8 @@ </span><span class="cx"> else: </span><span class="cx"> return self </span><span class="cx"> </span><del>-class Unicode(String): </del><ins>+class Unicode(TypeDecorator): + impl = String </ins><span class="cx"> def convert_bind_param(self, value, engine): </span><span class="cx"> if value is not None and isinstance(value, unicode): </span><span class="cx"> return value.encode(engine.encoding) </span><span class="lines">@@ -164,19 +170,20 @@ </span><span class="cx"> def get_constructor_args(self): </span><span class="cx"> return {'length':self.length} </span><span class="cx"> </span><del>-class PickleType(Binary): </del><ins>+class PickleType(TypeDecorator): </ins><span class="cx"> def __init__(self, protocol=pickle.HIGHEST_PROTOCOL): </span><span class="cx"> """allows the pickle protocol to be specified""" </span><span class="cx"> self.protocol = protocol </span><ins>+ self.impl = Binary() </ins><span class="cx"> def convert_result_value(self, value, engine): </span><span class="cx"> if value is None: </span><span class="cx"> return None </span><del>- buf = Binary.convert_result_value(self, value, engine) </del><ins>+ buf = self.impl.convert_result_value(value, engine) </ins><span class="cx"> return pickle.loads(str(buf)) </span><span class="cx"> def convert_bind_param(self, value, engine): </span><span class="cx"> if value is None: </span><span class="cx"> return None </span><del>- return Binary.convert_bind_param(self, pickle.dumps(value, self.protocol), engine) </del><ins>+ return self.impl.convert_bind_param(pickle.dumps(value, self.protocol), engine) </ins><span class="cx"> def get_constructor_args(self): </span><span class="cx"> return {} </span><span class="cx"> </span></span></pre></div> <a id="sqlalchemytrunktesttesttypespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/test/testtypes.py (1354 => 1355)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/test/testtypes.py 2006-04-29 00:08:07 UTC (rev 1354) +++ sqlalchemy/trunk/test/testtypes.py 2006-04-29 01:05:13 UTC (rev 1355) </span><span class="lines">@@ -17,7 +17,8 @@ </span><span class="cx"> def adapt_args(self): </span><span class="cx"> return self </span><span class="cx"> </span><del>-class MyDecoratedType(types.String): </del><ins>+class MyDecoratedType(types.TypeDecorator): + impl = String </ins><span class="cx"> def convert_bind_param(self, value, engine): </span><span class="cx"> return "BIND_IN"+ value </span><span class="cx"> def convert_result_value(self, value, engine): </span><span class="lines">@@ -29,6 +30,21 @@ </span><span class="cx"> def convert_result_value(self, value, engine): </span><span class="cx"> return value + "UNI_BIND_OUT" </span><span class="cx"> </span><ins>+class AdaptTest(PersistTest): + def testadapt(self): + e1 = create_engine('postgres://') + e2 = create_engine('sqlite://') + e3 = create_engine('mysql://') + + type = String(40) + + t1 = type.engine_impl(e1) + t2 = type.engine_impl(e2) + t3 = type.engine_impl(e3) + assert t1 != t2 + assert t2 != t3 + assert t3 != t1 + </ins><span class="cx"> class OverrideTest(PersistTest): </span><span class="cx"> """tests user-defined types, including a full type as well as a TypeDecorator""" </span><span class="cx"> </span><span class="lines">@@ -132,6 +148,15 @@ </span><span class="cx"> self.assert_(isinstance(x['plain_data'], unicode) and x['plain_data'] == unicodedata) </span><span class="cx"> finally: </span><span class="cx"> db.engine.convert_unicode = prev_unicode </span><ins>+ + +class Foo(object): + def __init__(self, moredata): + self.data = 'im data' + self.stuff = 'im stuff' + self.moredata = moredata + def __eq__(self, other): + return other.data == self.data and other.stuff == self.stuff and other.moredata==self.moredata </ins><span class="cx"> </span><span class="cx"> class BinaryTest(AssertMixin): </span><span class="cx"> def setUpAll(self): </span><span class="lines">@@ -140,20 +165,29 @@ </span><span class="cx"> Column('primary_id', Integer, primary_key=True), </span><span class="cx"> Column('data', Binary), </span><span class="cx"> Column('data_slice', Binary(100)), </span><del>- Column('misc', String(30))) </del><ins>+ Column('misc', String(30)), + Column('pickled', PickleType)) </ins><span class="cx"> binary_table.create() </span><span class="cx"> def tearDownAll(self): </span><span class="cx"> binary_table.drop() </span><span class="cx"> def testbinary(self): </span><ins>+ testobj1 = Foo('im foo 1') + testobj2 = Foo('im foo 2') + </ins><span class="cx"> stream1 =self.get_module_stream('sqlalchemy.sql') </span><span class="cx"> stream2 =self.get_module_stream('sqlalchemy.engine') </span><del>- binary_table.insert().execute(primary_id=1, misc='sql.pyc', data=stream1, data_slice=stream1[0:100]) - binary_table.insert().execute(primary_id=2, misc='engine.pyc', data=stream2, data_slice=stream2[0:99]) </del><ins>+ binary_table.insert().execute(primary_id=1, misc='sql.pyc', data=stream1, data_slice=stream1[0:100], pickled=testobj1) + binary_table.insert().execute(primary_id=2, misc='engine.pyc', data=stream2, data_slice=stream2[0:99], pickled=testobj2) </ins><span class="cx"> l = binary_table.select().execute().fetchall() </span><ins>+ print type(l[0]['data']) + return </ins><span class="cx"> print len(stream1), len(l[0]['data']), len(l[0]['data_slice']) </span><span class="cx"> self.assert_(list(stream1) == list(l[0]['data'])) </span><span class="cx"> self.assert_(list(stream1[0:100]) == list(l[0]['data_slice'])) </span><span class="cx"> self.assert_(list(stream2) == list(l[1]['data'])) </span><ins>+ self.assert_(testobj1 == l[0]['pickled']) + self.assert_(testobj2 == l[1]['pickled']) + </ins><span class="cx"> def get_module_stream(self, name): </span><span class="cx"> mod = __import__(name) </span><span class="cx"> for token in name.split('.')[1:]: </span></span></pre> </div> </div> </body> </html> |