Skip to content

Commit

Permalink
Added macros for two common cases of chained commands.
Browse files Browse the repository at this point in the history
This is to work around the thread syncronisation latency.

Cases are:
1) insert + get_last_rowid()
2) select + fetchall()

I added perf tests, and for the cases there is an ~2x & ~1.5x speedup respectively.
  • Loading branch information
grigi committed Oct 2, 2018
1 parent 7988102 commit 9ccb0fb
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
31 changes: 31 additions & 0 deletions aiosqlite/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,19 @@ def _conn(self) -> sqlite3.Connection:

return self._connection

def _execute_insert(
self, sql: str, parameters: Iterable[Any]
) -> Optional[sqlite3.Row]:
cursor = self._conn.execute(sql, parameters)
cursor.execute("SELECT last_insert_rowid()")
return cursor.fetchone()

def _execute_fetchall(
self, sql: str, parameters: Iterable[Any]
) -> Iterable[sqlite3.Row]:
cursor = self._conn.execute(sql, parameters)
return cursor.fetchall()

def run(self) -> None:
"""Execute function calls on a separate thread."""
while self._running:
Expand Down Expand Up @@ -211,6 +224,24 @@ async def execute(self, sql: str, parameters: Iterable[Any] = None) -> Cursor:
cursor = await self._execute(self._conn.execute, sql, parameters)
return Cursor(self, cursor)

@contextmanager
async def execute_insert(
self, sql: str, parameters: Iterable[Any] = None
) -> Optional[sqlite3.Row]:
"""Helper to insert and get the last_insert_rowid."""
if parameters is None:
parameters = []
return await self._execute(self._execute_insert, sql, parameters)

@contextmanager
async def execute_fetchall(
self, sql: str, parameters: Iterable[Any] = None
) -> Iterable[sqlite3.Row]:
"""Helper to execute a query and return all the data."""
if parameters is None:
parameters = []
return await self._execute(self._execute_fetchall, sql, parameters)

@contextmanager
async def executemany(
self, sql: str, parameters: Iterable[Iterable[Any]]
Expand Down
49 changes: 49 additions & 0 deletions tests/perf.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,52 @@ async def test_inserts(self):
yield
await db.execute("insert into perf (k) values (1), (2), (3)")
await db.commit()

@timed
async def test_insert_ids(self):
async with aiosqlite.connect(TEST_DB) as db:
await db.execute("create table perf (i integer primary key asc, k integer)")
await db.commit()

while True:
yield
cursor = await db.execute("insert into perf (k) values (1)")
await cursor.execute("select last_insert_rowid()")
await cursor.fetchone()
await db.commit()

@timed
async def test_insert_macro_ids(self):
async with aiosqlite.connect(TEST_DB) as db:
await db.execute("create table perf (i integer primary key asc, k integer)")
await db.commit()

while True:
yield
await db.execute_insert("insert into perf (k) values (1)")
await db.commit()

@timed
async def test_select(self):
async with aiosqlite.connect(TEST_DB) as db:
await db.execute("create table perf (i integer primary key asc, k integer)")
for i in range(100):
await db.execute("insert into perf (k) values (%d)" % (i, ))
await db.commit()

while True:
yield
cursor = await db.execute("select i, k from perf")
assert len(await cursor.fetchall()) == 100

@timed
async def test_select_macro(self):
async with aiosqlite.connect(TEST_DB) as db:
await db.execute("create table perf (i integer primary key asc, k integer)")
for i in range(100):
await db.execute("insert into perf (k) values (%d)" % (i, ))
await db.commit()

while True:
yield
assert len(await db.execute_fetchall("select i, k from perf")) == 100

0 comments on commit 9ccb0fb

Please sign in to comment.