Merge pull request #8 from abbbi/master

sqlite3: make it possible to set text_factory upon initialization
This commit is contained in:
Thiago Avelino 2014-12-25 20:48:25 -02:00
commit 1398dd9cad
2 changed files with 47 additions and 1 deletions

View File

@ -52,12 +52,19 @@ class SQLitePlugin(object):
name = 'sqlite' name = 'sqlite'
api = 2 api = 2
''' python3 moves unicode to str '''
try:
unicode
except NameError:
unicode = str
def __init__(self, dbfile=':memory:', autocommit=True, dictrows=True, def __init__(self, dbfile=':memory:', autocommit=True, dictrows=True,
keyword='db'): keyword='db', text_factory=unicode):
self.dbfile = dbfile self.dbfile = dbfile
self.autocommit = autocommit self.autocommit = autocommit
self.dictrows = dictrows self.dictrows = dictrows
self.keyword = keyword self.keyword = keyword
self.text_factory = text_factory
def setup(self, app): def setup(self, app):
''' Make sure that other installed plugins don't affect the same ''' Make sure that other installed plugins don't affect the same
@ -91,6 +98,7 @@ class SQLitePlugin(object):
autocommit = g('autocommit', self.autocommit) autocommit = g('autocommit', self.autocommit)
dictrows = g('dictrows', self.dictrows) dictrows = g('dictrows', self.dictrows)
keyword = g('keyword', self.keyword) keyword = g('keyword', self.keyword)
text_factory = g('keyword', self.text_factory)
# Test if the original callback accepts a 'db' keyword. # Test if the original callback accepts a 'db' keyword.
# Ignore it if it does not need a database handle. # Ignore it if it does not need a database handle.
@ -101,6 +109,8 @@ class SQLitePlugin(object):
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
# Connect to the database # Connect to the database
db = sqlite3.connect(dbfile) db = sqlite3.connect(dbfile)
# set text factory
db.text_factory = text_factory
# This enables column access by name: row['column_name'] # This enables column access by name: row['column_name']
if dictrows: if dictrows:
db.row_factory = sqlite3.Row db.row_factory = sqlite3.Row

36
test.py
View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
import os import os
import unittest import unittest
import sqlite3 import sqlite3
@ -6,6 +7,12 @@ import tempfile
import bottle import bottle
from bottle.ext import sqlite from bottle.ext import sqlite
''' python3 moves unicode to str '''
try:
unicode
except NameError:
unicode = str
class SQLiteTest(unittest.TestCase): class SQLiteTest(unittest.TestCase):
@ -48,6 +55,35 @@ class SQLiteTest(unittest.TestCase):
# I have two plugins working with different names # I have two plugins working with different names
self._request('/') self._request('/')
def test_text_factory(self):
# set text factory to str, unicode (default) would cause
# PrammingError: You must not use 8-bit bytestrings .. exception
self.app.install(sqlite.Plugin(keyword='db2',text_factory=str))
@self.app.get('/')
def test(db, db2):
char = 'ööö'
db2.execute("CREATE TABLE todo (id INTEGER PRIMARY KEY, task char(100) NOT NULL)")
db2.execute("INSERT INTO todo (id,task) VALUES ('1',:TEST)", { "TEST": char })
count = len(db2.execute("SELECT * FROM todo").fetchall())
self.assertEqual(count, 1)
self._request('/')
def test_text_factory_fail(self):
self.app.install(sqlite.Plugin(keyword='db3',text_factory=unicode))
@self.app.get('/')
def test(db, db3):
char = 'ööö'
db3.execute("CREATE TABLE todo (id INTEGER PRIMARY KEY, task char(100) NOT NULL)")
try:
db3.execute("INSERT INTO todo (id,task) VALUES ('1',:TEST)", { "TEST": char })
except sqlite3.ProgrammingError as e:
pass
self._request('/')
def test_raise_sqlite_integrity_error(self): def test_raise_sqlite_integrity_error(self):
@self.app.get('/') @self.app.get('/')
def test(db): def test(db):