CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-unqlite

Fast Python bindings for the UnQLite embedded NoSQL database.

Overview
Eval results
Files

cursors.mddocs/

Cursor Operations

Efficient database traversal and iteration capabilities for large datasets with positioning and filtering support. Cursors provide low-level access for manual record traversal and bulk operations.

Capabilities

Cursor Creation and Management

Create and manage database cursors for efficient traversal.

def cursor(self):
    """Create a cursor for iterating through the database.
    Returns Cursor object."""
    ...

class Cursor:
    def __enter__(self):
        """Enter context manager. Resets cursor position."""
        ...
        
    def __exit__(self, exc_type, exc_val, exc_tb):
        """Exit context manager."""
        ...

Usage Example:

db = unqlite.UnQLite(':mem:')

# Add test data
for i in range(10):
    db[f'key{i:02d}'] = f'value{i}'

# Create and use cursor
cursor = db.cursor()

# Use as context manager for automatic cleanup
with db.cursor() as cursor:
    cursor.first()
    while cursor.is_valid():
        key = cursor.key()
        value = cursor.value()
        print(f"{key}: {value}")
        try:
            cursor.next_entry()
        except StopIteration:
            break

Cursor Positioning

Move cursor to specific positions within the database.

def reset(self):
    """Reset the cursor's position."""
    ...

def seek(self, key, flags=UNQLITE_CURSOR_MATCH_EXACT):
    """Seek to the given key using specified matching flags."""
    ...

def first(self):
    """Set cursor to the first record in the database."""
    ...

def last(self):
    """Set cursor to the last record in the database."""
    ...

Usage Example:

db = unqlite.UnQLite(':mem:')

# Add sorted test data
keys = ['apple', 'banana', 'cherry', 'date', 'elderberry']
for key in keys:
    db[key] = f'fruit:{key}'

with db.cursor() as cursor:
    # Move to first record
    cursor.first()
    print(f"First: {cursor.key()} = {cursor.value()}")
    
    # Move to last record  
    cursor.last()
    print(f"Last: {cursor.key()} = {cursor.value()}")
    
    # Seek to specific key
    cursor.seek('cherry')
    print(f"Found: {cursor.key()} = {cursor.value()}")
    
    # Seek with different matching modes
    cursor.seek('c', flags=unqlite.UNQLITE_CURSOR_MATCH_GE)  # Greater or equal
    print(f"First key >= 'c': {cursor.key()}")

Cursor Movement

Navigate between records sequentially.

def next_entry(self):
    """Move cursor to the next entry. Raises StopIteration at end."""
    ...

def previous_entry(self):
    """Move cursor to the previous entry. Raises StopIteration at beginning."""
    ...

def is_valid(self):
    """Return True if cursor points to a valid record."""
    ...

Usage Example:

db = unqlite.UnQLite(':mem:')

# Add test data
for i in range(5):
    db[f'item{i}'] = f'data{i}'

with db.cursor() as cursor:
    # Forward iteration
    cursor.first()
    print("Forward iteration:")
    while cursor.is_valid():
        print(f"  {cursor.key()}: {cursor.value()}")
        try:
            cursor.next_entry()
        except StopIteration:
            break
    
    # Backward iteration
    cursor.last()
    print("Backward iteration:")
    while cursor.is_valid():
        print(f"  {cursor.key()}: {cursor.value()}")
        try:
            cursor.previous_entry()
        except StopIteration:
            break

Data Access

Access key and value data at cursor's current position.

def key(self):
    """Retrieve the key at the cursor's current location."""
    ...

def value(self):
    """Retrieve the value at the cursor's current location."""
    ...

def delete(self):
    """Delete the record at the cursor's current location."""
    ...

Usage Example:

db = unqlite.UnQLite(':mem:')

# Add test data with different types
db['string_key'] = 'text_value'
db['json_key'] = '{"type": "json", "valid": true}'
db['binary_key'] = b'\x00\x01\x02\x03'

with db.cursor() as cursor:
    cursor.first()
    while cursor.is_valid():
        key = cursor.key()
        value = cursor.value()
        
        print(f"Key: {key} (type: {type(key)})")
        print(f"Value: {value} (type: {type(value)})")
        
        # Delete specific records
        if key == 'binary_key':
            cursor.delete()
            print("Deleted binary record")
        else:
            try:
                cursor.next_entry()
            except StopIteration:
                break

Iterator Interface

Use cursors as Python iterators for convenient traversal.

def __iter__(self):
    """Return iterator for cursor."""
    ...

def __next__(self):
    """Get next key-value pair. Raises StopIteration at end."""
    ...

def fetch_until(self, stop_key, include_stop_key=True):
    """Iterate until specified key is reached."""
    ...

Usage Example:

db = unqlite.UnQLite(':mem:')

# Add range of data
for i in range(20):
    db[f'record{i:03d}'] = f'data_{i}'

# Iterate using cursor as iterator
with db.cursor() as cursor:
    print("All records:")
    for key, value in cursor:
        print(f"  {key}: {value}")

# Partial iteration with fetch_until
with db.cursor() as cursor:
    cursor.seek('record005')
    print("Records from record005 to record010:")
    for key, value in cursor.fetch_until('record010'):
        print(f"  {key}: {value}")

Database-Level Iteration Methods

UnQLite provides convenient iteration methods that use cursors internally.

def keys(self):
    """Efficiently iterate through the database's keys."""
    ...

def values(self):
    """Efficiently iterate through the database's values."""  
    ...

def items(self):
    """Efficiently iterate through the database's key-value pairs."""
    ...

def range(self, start_key, end_key, include_end_key=True):
    """Iterate over a range of keys."""
    ...

def __iter__(self):
    """Return iterator for database keys."""
    ...

Usage Example:

db = unqlite.UnQLite(':mem:')

# Add test data
data = {'alpha': '1', 'beta': '2', 'gamma': '3', 'delta': '4'}
db.update(data)

# Iterate over keys only
print("Keys:")
for key in db.keys():
    print(f"  {key}")

# Iterate over values only  
print("Values:")
for value in db.values():
    print(f"  {value}")

# Iterate over key-value pairs
print("Items:")
for key, value in db.items():
    print(f"  {key}: {value}")

# Range iteration
print("Range from 'beta' to 'gamma':")
for key, value in db.range('beta', 'gamma'):
    print(f"  {key}: {value}")

# Database as iterator (keys only)
print("Database iteration:")
for key in db:
    print(f"  {key}: {db[key]}")

Cursor Seek Modes

Control how the cursor positions itself when seeking to keys.

# Exact match (default)
unqlite.UNQLITE_CURSOR_MATCH_EXACT

# Less than or equal to key
unqlite.UNQLITE_CURSOR_MATCH_LE

# Greater than or equal to key  
unqlite.UNQLITE_CURSOR_MATCH_GE

Usage Example:

db = unqlite.UnQLite(':mem:')

# Add sorted data
keys = ['aardvark', 'bear', 'cat', 'dog', 'elephant']
for key in keys:
    db[key] = f'animal:{key}'

with db.cursor() as cursor:
    # Find exact match
    try:
        cursor.seek('cat', unqlite.UNQLITE_CURSOR_MATCH_EXACT)
        print(f"Exact match: {cursor.key()}")
    except:
        print("Exact match not found")
    
    # Find first key >= 'cow' (will find 'dog')
    cursor.seek('cow', unqlite.UNQLITE_CURSOR_MATCH_GE)
    print(f"First key >= 'cow': {cursor.key()}")
    
    # Find last key <= 'cow' (will find 'cat')
    cursor.seek('cow', unqlite.UNQLITE_CURSOR_MATCH_LE)  
    print(f"Last key <= 'cow': {cursor.key()}")

Performance Considerations

Cursors are highly efficient for:

  • Large dataset traversal: O(1) per record vs O(n) for repeated lookups
  • Sequential processing: Optimal disk/memory access patterns
  • Range queries: Efficient key range iteration
  • Bulk operations: Process many records with minimal overhead
db = unqlite.UnQLite('large.db')

# Efficient: Use cursor for large dataset processing
with db.cursor() as cursor:
    for key, value in cursor:
        # Process each record efficiently
        process_record(key, value)

# Inefficient: Individual key lookups
for key in db.keys():  # This internally uses a cursor
    value = db[key]    # This is an additional lookup
    process_record(key, value)

Error Handling

Cursor operations handle various error conditions:

db = unqlite.UnQLite(':mem:')

with db.cursor() as cursor:
    try:
        # Movement operations raise StopIteration at boundaries
        cursor.first()
        while True:
            print(cursor.key())
            cursor.next_entry()  # Will eventually raise StopIteration
            
    except StopIteration:
        print("Reached end of database")
    
    try:
        # Seek operations may raise exceptions for invalid keys
        cursor.seek('nonexistent_key')
        
    except unqlite.UnQLiteError as e:
        print(f"Seek failed: {e}")

Install with Tessl CLI

npx tessl i tessl/pypi-unqlite

docs

cursors.md

database-management.md

index.md

json-collections.md

jx9-scripting.md

key-value.md

transactions.md

utilities.md

tile.json