1 import sqlite3
2 import os
5 """A metaclass used to represent the tables of a database.
6
7 Intstances of a table class are stored in the rows attribute,
8 indexed by their primary key. For instance, Slide.rows['foobar']
9 accesses the instance 'foobar' from the Slide class,
10 which uses the Table metaclass.
11
12 Intstances can also be accessed like a dictionary (e.g. Slide['foobar']),
13 or like attributes (e.g. Slide.foobar) - this comes in handy when
14 scripting slides for a large scale video game.
15 """
16 - def __init__(cls, name, bases=(), attrs={}):
22 if not key: return None
23 if type(key) ==cls: return key
24 else: return cls.rows[key]
26 if type(item)==cls: return item in cls.rows.values()
27 else: return item in cls.rows.keys()
29 return cls.rows.itervalues()
31 """A generic row of a database.
32
33 This class is used in place of custom classes that
34 would just be used to store data without performing behavior.
35 A good example of this in practice are stages."""
36 @staticmethod
42 return self.cells[attr]
44 return self.cells[key]
48 return item in self.cells
52 """Represents an SQLite database used to store data for Pyzzle games.
53
54 This class performs higher level functionality than classes within
55 the sqlite3 module. It also acts as an Adapter Class that may allow
56 other file formats to be implemented in the future."""
58 self._connection=sqlite3.connect(file)
59 self._connection.row_factory = sqlite3.Row
60 self._cursor = self._connection.cursor()
61 - def load(self, TableClass, tablename=None, idcolumn='id'):
62 """Loads all instances a Table class from rows in pyzzle.datafile.
63 @param TableClass: A class that uses the Table metaclass.
64 @param tablename: The name of the table in the database.
65 If not specified, the name of TableClass is used instead.
66 @param idcolumn: The name of the primary key column for the table.
67 """
68 tablename = tablename if tablename else TableClass.__name__
69 query='select * from '+tablename
70 results=self._cursor.execute(query)
71 rows={}
72 for cells in results:
73 rows[cells[idcolumn]]=TableClass._load(cells)
74 return rows
75 - def save(self, TableClass, tablename=None, idcolumn='id'):
76 """Saves all members of a Table class to pyzzle.datafile."""
77 tablename = tablename if tablename else TableClass.__name__
78 self._cursor.execute('delete from '+tablename)
79
80 for row in TableClass:
81 cells=row._save()
82 query=' '.join(['insert into',tablename,'(',
83 ', '.join(cells.keys()),
84 ') values (',
85 ', '.join(('?')*len(cells)),')'])
86 self._cursor.execute(query, cells.values())
87 self._connection.commit()
89 self._cursor.close()
90 self._connection.close()
91