"""Sequential mutation examples in :memory:, not actual concurrent DB/snapshot test."""
import sqlite3,json
ROWS=[(1,10),(2,10),(3,20),(4,30),(5,40)]
def db():
    c=sqlite3.connect(':memory:',isolation_level=None);c.execute('CREATE TABLE item(id INTEGER PRIMARY KEY,t INTEGER NOT NULL)');c.executemany('INSERT INTO item VALUES(?,?)',ROWS);return c
def page(c,cursor=None,offset=None,limit=2):
    if cursor is not None:return [list(x)for x in c.execute('SELECT id,t FROM item WHERE (t,id)>(?,?) ORDER BY t,id LIMIT ?',(*cursor,limit))]
    return [list(x)for x in c.execute('SELECT id,t FROM item ORDER BY t,id LIMIT ? OFFSET ?',(limit,offset or 0))]
def demo():
    c=db();first=page(c);baseline_offset=page(c,offset=2);baseline_keyset=page(c,cursor=(10,2));assert baseline_offset==baseline_keyset==[[3,20],[4,30]];c.close()
    outcomes={}
    for name,sql in [('insert_before','INSERT INTO item VALUES(9,5)'),('delete_before','DELETE FROM item WHERE id=1'),('move_seen_after','UPDATE item SET t=35 WHERE id=1'),('move_unseen_before','UPDATE item SET t=5 WHERE id=5')]:
        c=db();first=page(c);assert first==[[1,10],[2,10]];cursor=(first[-1][1],first[-1][0]);c.execute(sql);offset=page(c,offset=2);keyset=page(c,cursor=cursor);remaining=page(c,cursor=cursor,limit=20);outcomes[name]={'first':first,'cursor_t_id':list(cursor),'mutation_sql':sql,'offset_second':offset,'keyset_second':keyset,'all_after_cursor':remaining};c.close()
    assert outcomes['insert_before']['offset_second']==[[2,10],[3,20]]and outcomes['insert_before']['keyset_second']==[[3,20],[4,30]]
    assert outcomes['delete_before']['offset_second']==[[4,30],[5,40]]and outcomes['delete_before']['keyset_second']==[[3,20],[4,30]]
    assert 1 in [x[0]for x in outcomes['move_seen_after']['all_after_cursor']]and 5 not in [x[0]for x in outcomes['move_unseen_before']['all_after_cursor']]
    c=db();first_one=page(c,limit=1);wrong=[list(x)for x in c.execute('SELECT id,t FROM item WHERE t>? ORDER BY t,id LIMIT 1',(10,))];correct=page(c,cursor=(10,1),limit=1);assert wrong==[[3,20]]and correct==[[2,10]];c.close()
    return {'sqlite_version':sqlite3.sqlite_version,'authored_rows':[list(x)for x in ROWS],'without_mutation':{'first':first,'offset_next':baseline_offset,'keyset_next':baseline_keyset},'mutation_cases':outcomes,'tie_case':{'first':first_one,'time_only_wrong_next':wrong,'time_and_unique_id_next':correct},'scope':'Ascending non-NULL integer(t,id), strict> cursor, sequential changes between queries. No snapshot guarantee, actual concurrent transaction, cursor authentication or access permission implemented. Moving sort keys can repeat/miss rows even with keyset; new rows before cursor not a complete-export promise.'}
if __name__=='__main__':print(json.dumps(demo(),indent=2))
