<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: mapper code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Fri, 25 Jul 2008 04:03:28 GMT</pubDate>
    <description>DZone Snippets: mapper code</description>
    <item>
      <title>ORM for pys60</title>
      <link>http://snippets.dzone.com/posts/show/1675</link>
      <description>I have asked for this a few months.&lt;br /&gt;Here's my own first version for an ORM.&lt;br /&gt;It's adapted from SQLAlchemy and SQLObject.&lt;br /&gt;(and whatever library I have searched)&lt;br /&gt;&lt;br /&gt;You need to create a database manually first.&lt;br /&gt;My previous snippets (&lt;a href=http://www.bigbold.com/snippets/posts/show/1669&gt;shell&lt;/a&gt;, &lt;a href=http://www.bigbold.com/snippets/posts/show/1668&gt;SQL&lt;/a&gt;) may help.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;from __future__ import generators&lt;br /&gt;import e32db, re&lt;br /&gt;db = e32db.Dbms()&lt;br /&gt;dbv = e32db.Db_view()&lt;br /&gt;db.open(u'C:\\test.db')&lt;br /&gt;&lt;br /&gt;# Some helping classes (need more in next version)&lt;br /&gt;class String:&lt;br /&gt;    pass&lt;br /&gt;&lt;br /&gt;class Integer:&lt;br /&gt;    pass&lt;br /&gt;&lt;br /&gt;class Float:&lt;br /&gt;    pass&lt;br /&gt;&lt;br /&gt;class column:&lt;br /&gt;    def __init__(self, coltype):&lt;br /&gt;        self.coltype = coltype&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Here's the mother of all your classes that map to database tables.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class Mapper(object):&lt;br /&gt;    def __init__(self, id=None, **kw):&lt;br /&gt;        if id is None:&lt;br /&gt;            self.id = self._insert(**kw)&lt;br /&gt;        else:&lt;br /&gt;            self.id = id&lt;br /&gt;    def _insert(self, **kw):&lt;br /&gt;        names = ','.join(kw.keys())&lt;br /&gt;        values = ','.join([self.quote(k,v) for k,v in kw.items()])&lt;br /&gt;        tablename = self.__class__.__name__&lt;br /&gt;        q = u"INSERT INTO %s(%s) VALUES (%s)" % (tablename, names, values)&lt;br /&gt;        db.execute(q)&lt;br /&gt;        # get last insert ID&lt;br /&gt;        dbv.prepare(db, u'SELECT id FROM '+tablename+' ORDER BY id DESC')&lt;br /&gt;        dbv.first_line()&lt;br /&gt;        dbv.get_line()&lt;br /&gt;        return dbv.col(1)&lt;br /&gt;    def __getattr__(self, name):&lt;br /&gt;        if name in self.mapping.__dict__:&lt;br /&gt;            q = 'SELECT '+name+' FROM '+self.__class__.__name__&lt;br /&gt;            q += ' WHERE id='+str(self.id)&lt;br /&gt;            dbv.prepare(db, unicode(q))&lt;br /&gt;            dbv.first_line()&lt;br /&gt;            dbv.get_line()&lt;br /&gt;            return dbv.col(1)&lt;br /&gt;        else:&lt;br /&gt;            return self.__dict__[name]&lt;br /&gt;    def __repr__(self):&lt;br /&gt;        return '&lt;%s id=%d&gt;' % (self.__class__.__name__, self.id)&lt;br /&gt;    def quote(self, name, value):&lt;br /&gt;        if self.mapping.__dict__[name].coltype == String:&lt;br /&gt;            return "'%s'" % value.replace("'", "''")  # encode single quote&lt;br /&gt;        else:&lt;br /&gt;            return str(value)&lt;br /&gt;    def __setattr__(self, name, value):&lt;br /&gt;        if name in self.mapping.__dict__:&lt;br /&gt;            q = 'UPDATE '+self.__class__.__name__+' SET '+name+'='&lt;br /&gt;            q += self.quote(name, value) + " WHERE id=" + str(self.id)&lt;br /&gt;            db.execute(unicode(q))&lt;br /&gt;        else:&lt;br /&gt;            self.__dict__[name] = value&lt;br /&gt;    def set(self, **kw):&lt;br /&gt;        q = "UPDATE "+self.__class__.__name__+" SET "&lt;br /&gt;        for k, v in kw.items():&lt;br /&gt;            q += k+'='+self.quote(k,v)+','&lt;br /&gt;        q = q[:-1]+" WHERE id=%s" % self.id&lt;br /&gt;        db.execute(unicode(q))&lt;br /&gt;    def delete(self):&lt;br /&gt;        q = 'DELETE FROM '+self.__class__.__name__+" WHERE id=" + str(self.id)&lt;br /&gt;        db.execute(unicode(q))&lt;br /&gt;        self.id = None&lt;br /&gt;    def dict(self):&lt;br /&gt;        names = [k for k in self.mapping.__dict__.keys() if not k.startswith('__')]&lt;br /&gt;        q = 'SELECT '+','.join(names)+' FROM '+self.__class__.__name__&lt;br /&gt;        q += ' WHERE id=' + str(self.id)&lt;br /&gt;        dbv.prepare(db, unicode(q))&lt;br /&gt;        dbv.first_line()&lt;br /&gt;        dbv.get_line()&lt;br /&gt;        dct = {'id': self.id}&lt;br /&gt;        for i in range(dbv.col_count()):&lt;br /&gt;            dct[names[i]] = dbv.col(i+1)&lt;br /&gt;        return dct&lt;br /&gt;    def select(cls, where=None, orderby=None):&lt;br /&gt;        q = 'SELECT id FROM '+cls.__name__&lt;br /&gt;        if where:&lt;br /&gt;            q += ' WHERE '+where&lt;br /&gt;        if orderby:&lt;br /&gt;            q += ' ORDER BY '+orderby&lt;br /&gt;        dbv = e32db.Db_view()  # need its own cursor&lt;br /&gt;        dbv.prepare(db, unicode(q))&lt;br /&gt;        dbv.first_line()&lt;br /&gt;        for i in range(dbv.count_line()):&lt;br /&gt;            dbv.get_line()&lt;br /&gt;            yield cls(dbv.col(1))&lt;br /&gt;            dbv.next_line()&lt;br /&gt;    select = classmethod(select)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Here's how you create your class.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class Person(Mapper):&lt;br /&gt;    class mapping:&lt;br /&gt;        # doesn't need id = column(Integer)&lt;br /&gt;        name = column(String)&lt;br /&gt;        age = column(Integer)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;</description>
      <pubDate>Fri, 10 Mar 2006 01:30:46 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1675</guid>
      <author>korakot (Korakot Chaovavanich)</author>
    </item>
  </channel>
</rss>
