Skip to content

Commit 481e97a

Browse files
committed
Merge branch 'tornado' of github.com:PyMySQL/Tornado-MySQL into tornado
2 parents f2296d0 + 1ba40eb commit 481e97a

File tree

6 files changed

+137
-50
lines changed

6 files changed

+137
-50
lines changed

tornado_mysql/connections.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,7 @@ def init_unbuffered_query(self):
10781078
self.connection = None
10791079
else:
10801080
self.field_count = first_packet.read_length_encoded_integer()
1081-
self._get_descriptions()
1081+
yield self._get_descriptions()
10821082

10831083
# Apparently, MySQLdb picks this number because it's the maximum
10841084
# value of a 64bit unsigned integer. Since we're emulating MySQLdb,

tornado_mysql/cursors.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ def fetchone(self):
408408
self._check_executed()
409409
row = yield self.read_next()
410410
if row is None:
411-
raise gen.Return()
411+
raise gen.Return(None)
412412
self.rownumber += 1
413413
raise gen.Return(row)
414414

@@ -443,6 +443,7 @@ def fetchmany(self, size=None):
443443
self.rownumber += 1
444444
raise gen.Return(rows)
445445

446+
@gen.coroutine
446447
def scroll(self, value, mode='relative'):
447448
self._check_executed()
448449

@@ -452,7 +453,7 @@ def scroll(self, value, mode='relative'):
452453
"Backwards scrolling not supported by this cursor")
453454

454455
for _ in range_type(value):
455-
self.read_next()
456+
yield self.read_next()
456457
self.rownumber += value
457458
elif mode == 'absolute':
458459
if value < self.rownumber:
@@ -461,7 +462,7 @@ def scroll(self, value, mode='relative'):
461462

462463
end = value - self.rownumber
463464
for _ in range_type(end):
464-
self.read_next()
465+
yield self.read_next()
465466
self.rownumber = value
466467
else:
467468
raise err.ProgrammingError("unknown scroll mode %s" % mode)

tornado_mysql/pools.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def _close_conn(self, conn):
8080
self._opened_conns -= 1
8181

8282
@coroutine
83-
def execute(self, query, params):
83+
def execute(self, query, params=None):
8484
"""Execute query in pool.
8585
8686
Returns future yielding closed cursor.

tornado_mysql/tests/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from tornado_mysql.tests.test_nextset import *
44
from tornado_mysql.tests.test_DictCursor import *
55
from tornado_mysql.tests.test_connection import TestConnection
6-
6+
from tornado_mysql.tests.test_SSCursor import TestSSCursor
77
#from pymysql.tests.thirdparty import *
88

99
if __name__ == "__main__":

tornado_mysql/tests/test_SSCursor.py

Lines changed: 129 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,97 @@
1-
import sys
1+
from tornado_mysql import ProgrammingError
2+
from tornado import gen
3+
from tornado.testing import gen_test
4+
from tornado_mysql import NotSupportedError
25

3-
from tornado_mysql.tests import base
46
import tornado_mysql.cursors
7+
from tornado_mysql.tests import base
58

69

710
class TestSSCursor(base.PyMySQLTestCase):
11+
12+
data = [
13+
('America', '', 'America/Jamaica'),
14+
('America', '', 'America/Los_Angeles'),
15+
('America', '', 'America/Lima'),
16+
('America', '', 'America/New_York'),
17+
('America', '', 'America/Menominee'),
18+
('America', '', 'America/Havana'),
19+
('America', '', 'America/El_Salvador'),
20+
('America', '', 'America/Costa_Rica'),
21+
('America', '', 'America/Denver'),
22+
('America', '', 'America/Detroit'),]
23+
24+
@gen_test
825
def test_SSCursor(self):
926
affected_rows = 18446744073709551615
1027

1128
conn = self.connections[0]
12-
data = [
13-
('America', '', 'America/Jamaica'),
14-
('America', '', 'America/Los_Angeles'),
15-
('America', '', 'America/Lima'),
16-
('America', '', 'America/New_York'),
17-
('America', '', 'America/Menominee'),
18-
('America', '', 'America/Havana'),
19-
('America', '', 'America/El_Salvador'),
20-
('America', '', 'America/Costa_Rica'),
21-
('America', '', 'America/Denver'),
22-
('America', '', 'America/Detroit'),]
2329

2430
try:
2531
cursor = conn.cursor(tornado_mysql.cursors.SSCursor)
2632

2733
# Create table
28-
cursor.execute(('CREATE TABLE tz_data ('
29-
'region VARCHAR(64),'
30-
'zone VARCHAR(64),'
31-
'name VARCHAR(64))'))
34+
yield cursor.execute('DROP TABLE IF EXISTS tz_data;')
35+
yield cursor.execute(('CREATE TABLE tz_data ('
36+
'region VARCHAR(64),'
37+
'zone VARCHAR(64),'
38+
'name VARCHAR(64))'))
3239

3340
# Test INSERT
34-
for i in data:
35-
cursor.execute('INSERT INTO tz_data VALUES (%s, %s, %s)', i)
41+
for i in self.data:
42+
yield cursor.execute('INSERT INTO tz_data VALUES (%s, %s, %s)', i)
3643
self.assertEqual(conn.affected_rows(), 1, 'affected_rows does not match')
37-
conn.commit()
38-
44+
yield conn.commit()
3945
# Test fetchone()
4046
iter = 0
41-
cursor.execute('SELECT * FROM tz_data')
47+
yield cursor.execute('SELECT * FROM tz_data;')
4248
while True:
43-
row = cursor.fetchone()
49+
row = yield cursor.fetchone()
50+
4451
if row is None:
4552
break
4653
iter += 1
4754

4855
# Test cursor.rowcount
4956
self.assertEqual(cursor.rowcount, affected_rows,
50-
'cursor.rowcount != %s' % (str(affected_rows)))
57+
'cursor.rowcount != %s' % (str(affected_rows)))
5158

5259
# Test cursor.rownumber
5360
self.assertEqual(cursor.rownumber, iter,
54-
'cursor.rowcount != %s' % (str(iter)))
61+
'cursor.rowcount != %s' % (str(iter)))
5562

5663
# Test row came out the same as it went in
57-
self.assertEqual((row in data), True,
58-
'Row not found in source data')
64+
self.assertEqual((row in self.data), True,
65+
'Row not found in source self.data')
5966

6067
# Test fetchall
61-
cursor.execute('SELECT * FROM tz_data')
62-
self.assertEqual(len(cursor.fetchall()), len(data),
63-
'fetchall failed. Number of rows does not match')
68+
yield cursor.execute('SELECT * FROM tz_data')
69+
r = yield cursor.fetchall()
70+
self.assertEqual(len(r), len(self.data),
71+
'fetchall failed. Number of rows does not match')
6472

6573
# Test fetchmany
66-
cursor.execute('SELECT * FROM tz_data')
67-
self.assertEqual(len(cursor.fetchmany(2)), 2,
68-
'fetchmany failed. Number of rows does not match')
74+
yield cursor.execute('SELECT * FROM tz_data')
75+
r = yield cursor.fetchmany(2)
76+
self.assertEqual(len(r), 2,
77+
'fetchmany failed. Number of rows does not match')
6978

7079
# So MySQLdb won't throw "Commands out of sync"
7180
while True:
72-
res = cursor.fetchone()
81+
res = yield cursor.fetchone()
7382
if res is None:
7483
break
7584

7685
# Test update, affected_rows()
77-
cursor.execute('UPDATE tz_data SET zone = %s', ['Foo'])
78-
conn.commit()
79-
self.assertEqual(cursor.rowcount, len(data),
80-
'Update failed. affected_rows != %s' % (str(len(data))))
86+
yield cursor.execute('UPDATE tz_data SET zone = %s', ['Foo'])
87+
yield conn.commit()
88+
self.assertEqual(cursor.rowcount, len(self.data),
89+
'Update failed. affected_rows != %s' % (str(len(self.data))))
8190

8291
# Test executemany
83-
cursor.executemany('INSERT INTO tz_data VALUES (%s, %s, %s)', data)
84-
self.assertEqual(cursor.rowcount, len(data),
85-
'executemany failed. cursor.rowcount != %s' % (str(len(data))))
92+
yield cursor.executemany('INSERT INTO tz_data VALUES (%s, %s, %s)', self.data)
93+
self.assertEqual(cursor.rowcount, len(self.data),
94+
'executemany failed. cursor.rowcount != %s' % (str(len(self.data))))
8695

8796
# Test multiple datasets
8897
cursor.execute('SELECT 1; SELECT 2; SELECT 3')
@@ -94,11 +103,88 @@ def test_SSCursor(self):
94103
self.assertFalse(cursor.nextset())
95104

96105
finally:
97-
cursor.execute('DROP TABLE tz_data')
98-
cursor.close()
106+
yield cursor.execute('DROP TABLE tz_data')
107+
yield cursor.close()
108+
109+
@gen.coroutine
110+
def _prepare(self):
111+
conn = self.connections[0]
112+
cursor = conn.cursor()
113+
yield cursor.execute('DROP TABLE IF EXISTS tz_data;')
114+
yield cursor.execute('CREATE TABLE tz_data ('
115+
'region VARCHAR(64),'
116+
'zone VARCHAR(64),'
117+
'name VARCHAR(64))')
118+
119+
yield cursor.executemany(
120+
'INSERT INTO tz_data VALUES (%s, %s, %s)', self.data)
121+
yield conn.commit()
122+
yield cursor.close()
123+
124+
@gen.coroutine
125+
def _cleanup(self):
126+
conn = self.connections[0]
127+
cursor = conn.cursor()
128+
yield cursor.execute('DROP TABLE IF EXISTS tz_data;')
129+
130+
@gen_test
131+
def test_sscursor_executemany(self):
132+
conn = self.connections[0]
133+
yield self._prepare()
134+
cursor = conn.cursor(tornado_mysql.cursors.SSCursor)
135+
# Test executemany
136+
yield cursor.executemany(
137+
'INSERT INTO tz_data VALUES (%s, %s, %s)', self.data)
138+
msg = 'executemany failed. cursor.rowcount != %s'
139+
self.assertEqual(cursor.rowcount, len(self.data),
140+
msg % (str(len(self.data))))
141+
yield self._cleanup()
142+
143+
@gen_test
144+
def test_sscursor_scroll_relative(self):
145+
conn = self.connections[0]
146+
yield self._prepare()
147+
cursor = conn.cursor(tornado_mysql.cursors.SSCursor)
148+
yield cursor.execute('SELECT * FROM tz_data;')
149+
yield cursor.scroll(1)
150+
ret = yield cursor.fetchone()
151+
self.assertEqual(('America', '', 'America/Los_Angeles'), ret)
152+
yield self._cleanup()
153+
154+
@gen_test
155+
def test_sscursor_scroll_absolute(self):
156+
conn = self.connections[0]
157+
yield self._prepare()
158+
cursor = conn.cursor(tornado_mysql.cursors.SSCursor)
159+
yield cursor.execute('SELECT * FROM tz_data;')
160+
yield cursor.scroll(2, mode='absolute')
161+
ret = yield cursor.fetchone()
162+
self.assertEqual(('America', '', 'America/Lima'), ret)
163+
yield self._cleanup()
164+
165+
@gen_test
166+
def test_sscursor_scroll_errors(self):
167+
yield self._prepare()
168+
conn = self.connections[0]
169+
cursor = conn.cursor(tornado_mysql.cursors.SSCursor)
170+
171+
yield cursor.execute('SELECT * FROM tz_data;')
172+
173+
with self.assertRaises(NotSupportedError):
174+
yield cursor.scroll(-2, mode='relative')
175+
176+
yield cursor.scroll(2, mode='absolute')
177+
178+
with self.assertRaises(NotSupportedError):
179+
yield cursor.scroll(1, mode='absolute')
180+
with self.assertRaises(ProgrammingError):
181+
yield cursor.scroll(3, mode='not_valid_mode')
182+
yield self._cleanup()
183+
99184

100185
__all__ = ["TestSSCursor"]
101186

187+
102188
if __name__ == "__main__":
103189
import unittest
104190
unittest.main()

tornado_mysql/tests/test_nextset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def test_multi_cursor(self):
6363
self.assertTrue(res)
6464

6565
self.assertEqual([(2,)], list(cur1))
66-
res = yield cur.nextset()
66+
res = yield cur1.nextset()
6767
self.assertIsNone(res)
6868

6969
#TODO: How about SSCursor and nextset?

0 commit comments

Comments
 (0)