テーブル定義を扱うクラス

K-enq.tdの開発は続いています。今日は、ずっと延ばし延ばしにしてきたテーブル定義を扱うクラスを、ようやく書きはじめました。というか、今思ったんだけど、テーブル定義じゃなくてフォーム定義だよなあ。名前を変えるかどうかは、また今度考えることにしよう。

アンケートなどに使うHTMLのフォームの設定を保存管理するための、簡単なクラスです。もちろん書きはじめたところで、まだ全然できていないんですけど、最終的にはこのテーブル定義クラスと、まだ書きはじめてもいないフォーム出力クラスを組み合わせて、アンケートフォームを出力するところまでいくつもりです。

以下に書いたTableDefinitionクラスですが、テーブル(というかフォーム)のデータを扱うデータベース(というかテーブル)と、各アンケートのフォームアイテム(つまりフィールド)を扱うテーブルを__init__()で作っています。

そして、テーブルのリストを得るためのメソッドとテーブルを作るためのメソッドを仮に作ったところ。テーブル、というかフォームなんだけど、それのIDは仮にrandomを使って生成していて、仮にということは、後々、もう少しましな方法を選択するってことです。機械的に生成したいんだけど、数値だけというのもなんだし、もうちょっと人が見てわかりやすい方がいいかなって。それと、IDがバッティングした場合、例外を発生させようかと思っていたんですが、そうじゃなくて、Sessionクラスでやってたように、ID生成後、かぶってないことを確認してレコードを追加するようにしたほうがスマートだと思っています。

まあ、そんな感じで、ちょっとずつ進めています。

# -*- coding: utf-8 -*-
'''
Class table definition
'''

import sqlite3
import pickle
import base64

class TableDefinition:
    '''Class of table definition'''

    def __init__(self, dbpath):
        self.dbpath = dbpath
        self.dbtabledefinition = u'tabledefinition'
        self.dbitemdefinition = u'itemdefinition'

        connection = self._open_db()
        cursor = connection.cursor()
        cursor.execute('select * from sqlite_master \
        where type=\'table\' and name=\'%s\';' % \
                       self.dbtabledefinition)
        tablecount = cursor.fetchall()
        if len(tablecount) == 0:
            cursor.execute('create table %s (tid primary key, title, \
            abbr_title, summary, start_date, end_date, active);' % \
                           self.dbtabledefinition)

        cursor.execute('select * from sqlite_master \
        where type=\'table\' and name=\'%s\';' % \
                       self.dbitemdefinition)
        tablecount = cursor.fetchall()
        if len(tablecount) == 0:
            cursor.execute('create table %s (iid, tid, title, abbr_title, \
            number, level, order_number, summary, type, default_value, \
            require, active, primary key(iid, tid));' % \
                           self.dbitemdefinition)
        cursor.close()
        connection.commit()
        connection.close()


    def create_table(self, title=u'untitled', abbr_title=None, summary=None, \
                     start_date=None, end_date=None, active=False):
        import random
        tid = random.random()
        start_date = self._pickle(start_date)
        end_date = self._pickle(end_date)
        active = self._pickle(active)

        connection = self._open_db()
        cursor = connection.cursor()
        recordcount = self._count_table(cursor, tid)
        if recordcount == 0:
            try:
                cursor.execute('insert into %s (tid, title, abbr_title, \
                summary, start_date, end_date, active) \
                values(\'%s\', \'%s\', \'%s\', \'%s\', \'%s\', \'%s\', \
                \'%s\');' % \
                               (self.dbtabledefinition, tid, title, \
                                abbr_title, summary, start_date, end_date, \
                                active))
            except:
                raise
            finally:
                cursor.close()
                connection.commit()
                connection.close()
        else:
            cursor.close()
            connection.close()

    def get_table_list(self):
        connection = self._open_db()
        cursor = connection.cursor()
        cursor.execute('select * from %s order by start_date' % \
                       self.dbtabledefinition)
        tablelist = list()
        for record in cursor.fetchall():
            tablelist.append({u'tid': record[0], \
                              u'title': record[1], \
                              u'abbr_title': record[2], \
                              u'summary' : record[3], \
                              u'start_date': self._unpickle(record[4]), \
                              u'end_date': self._unpickle(record[5]), \
                              u'active': self._unpickle(record[6])})
        cursor.close()
        connection.close()
        return tablelist
                             

    # internal methods

    def _open_db(self):
        return sqlite3.connect(self.dbpath)

    def _pickle(self, value):
        return base64.encodestring(pickle.dumps(value))

    def _unpickle(self, value):
        if value == None or value == u'None':
            return u''
        else:
            return pickle.loads(base64.decodestring(value))

    def _count_table(self, cursor, tid):
        cursor.execute('select count(*) from %s where tid=\'%s\';' % \
                       (self.dbtabledefinition, tid))
        recordcount = cursor.fetchone()
        return recordcount[0]