Skip to main content

A Python database library with .irodb format and hash-based indexing

Project description

IRODB - Lightweight Database Engine

Python 3.7+ License: MIT Code Style

๐Ÿ“‹ Overview

IRODB is a lightweight, file-based database engine for Python applications. It provides a simple yet powerful interface for storing and retrieving structured data with built-in support for data integrity through cryptographic hashing.

โœจ Key Features

  • ๐Ÿ” Data Integrity: SHA-256 hashing for all records
  • ๐Ÿ“ File-Based Storage: No external dependencies or servers needed
  • ๐Ÿ” Flexible Querying: Query by any field with multiple conditions
  • โšก Hash Indexing: Fast lookups using hash-based indexes
  • ๐Ÿ”„ ACID Operations: Atomic operations with rollback capabilities
  • ๐Ÿ“Š Schema Validation: Enforce data types and required fields
  • ๐Ÿ› ๏ธ Multi-Table Support: Create and manage multiple tables
  • ๐Ÿงน Vacuum Operation: Optimize database size and performance
  • ๐Ÿ”ง Cross-Platform: Works on Windows, Linux, and macOS

๐Ÿš€ Quick Start

from irodb.core import IRODB

# Create or open a database
db = IRODB('my_database.irodb', auto_create=True)

# Create a table with schema
db.create_table('users', {
    'name': str,
    'age': int,
    'email': str,
    'active': bool
}, enable_hash_index=True)

# Insert data
db.insert('users', {
    'name': 'Alice',
    'age': 30,
    'email': 'alice@example.com',
    'active': True
})

# Query data
results = db.select('users', {'name': 'Alice'})
print(results)

# Update data
db.update('users', {'name': 'Alice'}, {'age': 31})

# Delete data
db.delete('users', {'active': False})

# Close database
db.close()

๐Ÿ“ฆ Installation

From Source

# Clone the repository
git clone https://github.com/IROTECHLAB/irodb.git

# Navigate to the directory
cd irodb

# Install in development mode
pip install -e .

Using pip

pip install irotechlab_irodb

๐Ÿ“š Documentation

Database Operations

Creating a Database

from irodb.core import IRODB

# Auto-create if doesn't exist
db = IRODB('data.irodb', auto_create=True)

# Open existing database
db = IRODB('data.irodb', auto_create=False)

Table Management

# Create a table with schema
db.create_table('products', {
    'name': str,
    'price': float,
    'quantity': int,
    'available': bool
})

# Create table with hash index
db.create_table('users', {
    'username': str,
    'email': str
}, enable_hash_index=True)

# List all tables
print(db.tables.keys())

CRUD Operations

Insert Data

# Insert single record
row_id = db.insert('users', {
    'name': 'Bob',
    'age': 25,
    'email': 'bob@example.com',
    'active': True
})

# Insert with hash return
row_id, row_hash = db.insert('users', {
    'name': 'Charlie',
    'age': 35,
    'email': 'charlie@example.com',
    'active': False
}, return_hash=True)

Select/Query Data

# Select all records
all_users = db.select('users')

# Select with conditions
active_users = db.select('users', {'active': True})

# Select with limit
first_10 = db.select('users', limit=10)

# Complex conditions
results = db.select('users', {'age': 30, 'active': True})

Update Data

# Update single record
updated = db.update('users', {'name': 'Bob'}, {'age': 26})

# Update multiple records
updated = db.update('users', {'active': True}, {'status': 'active'})

Delete Data

# Delete single record
deleted = db.delete('users', {'name': 'Bob'})

# Delete multiple records
deleted = db.delete('users', {'active': False})

Hash Features

Hash Generation

# Insert with hash generation
row_id, row_hash = db.insert('users', {
    'name': 'Alice',
    'age': 30,
    'email': 'alice@example.com'
}, return_hash=True)

print(f"Record hash: {row_hash}")

Find by Hash

# Find records by exact hash
results = db.find_by_hash('users', row_hash)

# Find records by hashed value
results = db.find_by_hashed_value('users', 'Alice')

Hash Integrity Verification

# Verify hash integrity of a table
integrity = db.verify_hash_integrity('users')
print(f"Total rows: {integrity['total_rows']}")
print(f"Valid hashes: {integrity['valid_hashes']}")
print(f"Invalid hashes: {integrity['invalid_hashes']}")

# Get hash statistics
stats = db.get_hash_statistics('users')
print(f"Unique hashes: {stats['unique_hashes']}")

Advanced Features

Multiple Tables

# Create multiple tables
db.create_table('users', {'name': str, 'age': int})
db.create_table('products', {'name': str, 'price': float})
db.create_table('orders', {'user_id': int, 'product_id': int})

# Work with multiple tables
db.insert('users', {'name': 'Alice', 'age': 30})
db.insert('products', {'name': 'Laptop', 'price': 999.99})
db.insert('orders', {'user_id': 1, 'product_id': 1})

Vacuum Operation

# Optimize database by removing deleted records
db.vacuum()

Database Info

# Get database information
info = {
    'tables': len(db.tables),
    'rows': sum(len(pickle.loads(db._read_page(t['page']))['rows']) 
               for t in db.tables.values())
}
print(info)

๐Ÿ—๏ธ Project Structure

Based on the actual file structure:

irodb/
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ setup.py
โ”œโ”€โ”€ LICENSE
โ”œโ”€โ”€ .gitignore
โ”œโ”€โ”€ irodb/
โ”‚   โ”œโ”€โ”€ __init__.py          # Package initialization
โ”‚   โ”œโ”€โ”€ core.py              # Core database engine (19.51KB)
โ”‚   โ”œโ”€โ”€ constants.py         # Constants and configuration (1.09KB)
โ”‚   โ”œโ”€โ”€ exceptions.py        # Custom exceptions (909.00B)
โ”‚   โ”œโ”€โ”€ hash_system.py       # Hash-based features (8.49KB)
โ”‚   โ”œโ”€โ”€ index.py             # Indexing system (3.56KB)
โ”‚   โ”œโ”€โ”€ transaction.py       # Transaction management (3.99KB)
โ”‚   โ””โ”€โ”€ utils.py             # Utility functions (4.67KB)
โ”œโ”€โ”€ tests/
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ””โ”€โ”€ test_core.py
โ””โ”€โ”€ examples/
    โ””โ”€โ”€ basic_usage.py

Module Descriptions

Module Size Description
core.py 19.51KB Main database engine with CRUD operations
hash_system.py 8.49KB SHA-256 hashing and integrity verification
utils.py 4.67KB Helper functions and utilities
transaction.py 3.99KB ACID transaction support
index.py 3.56KB Indexing and fast lookups
constants.py 1.09KB Configuration constants
exceptions.py 909B Custom exception classes
init.py 617B Package exports

๐Ÿงช Running Tests

# Run all tests
python tests/test_core.py

# Run specific test class
python -m unittest tests.test_core.TestCRUDOperations

# Run with coverage (if coverage installed)
coverage run -m unittest discover tests
coverage report -m

๐Ÿ“ Examples

Basic Usage Example

from irodb.core import IRODB

# Initialize database
db = IRODB('example.irodb', auto_create=True)

# Create table
db.create_table('employees', {
    'name': str,
    'department': str,
    'salary': int,
    'active': bool
}, enable_hash_index=True)

# Insert sample data
employees = [
    {'name': 'Alice', 'department': 'Engineering', 'salary': 80000, 'active': True},
    {'name': 'Bob', 'department': 'Sales', 'salary': 60000, 'active': True},
    {'name': 'Charlie', 'department': 'Engineering', 'salary': 90000, 'active': False}
]

for emp in employees:
    db.insert('employees', emp)

# Query active engineers
active_engineers = db.select('employees', {
    'department': 'Engineering',
    'active': True
})

print(f"Active engineers: {len(active_engineers)}")

# Update employee salary
db.update('employees', {'name': 'Alice'}, {'salary': 85000})

# Verify hash integrity
integrity = db.verify_hash_integrity('employees')
print(f"Hash integrity: {integrity['valid_hashes']}/{integrity['total_rows']}")

# Close database
db.close()

Hash Demo Example

from irodb.core import IRODB

# Create database with hash indexing
db = IRODB('hash_demo.irodb', auto_create=True)

db.create_table('documents', {
    'title': str,
    'content': str,
    'author': str
}, enable_hash_index=True)

# Insert documents with hash
doc_id, doc_hash = db.insert('documents', {
    'title': 'Introduction',
    'content': 'This is the first document.',
    'author': 'John Doe'
}, return_hash=True)

print(f"Document hash: {doc_hash}")

# Find document by hash
found = db.find_by_hash('documents', doc_hash)
print(f"Found: {found[0]['title']}")

# Check integrity
integrity = db.verify_hash_integrity('documents')
print(f"Integrity check: {integrity}")

db.close()

Transaction Example

from irodb.core import IRODB
from irodb.transaction import Transaction

db = IRODB('data.irodb', auto_create=True)

# Start a transaction
with Transaction(db) as tx:
    tx.insert('users', {'name': 'Alice', 'age': 30})
    tx.insert('users', {'name': 'Bob', 'age': 25})
    # Auto-commit on exit

# Manual transaction
tx = Transaction(db)
try:
    tx.insert('users', {'name': 'Charlie', 'age': 35})
    tx.commit()
except Exception as e:
    tx.rollback()
    print(f"Transaction failed: {e}")

Test Suite Example

# tests/test_core.py
import unittest
import os
import tempfile
import sys
import pickle

# Add parent directory to path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from irodb.core import IRODB
from irodb.exceptions import *

class TestDatabaseCreation(unittest.TestCase):
    """Test database creation and initialization"""
    
    def setUp(self):
        self.temp_dir = tempfile.mkdtemp()
        self.db_path = os.path.join(self.temp_dir, 'test.irodb')
    
    def tearDown(self):
        try:
            if os.path.exists(self.db_path):
                os.remove(self.db_path)
        except:
            pass
        try:
            os.rmdir(self.temp_dir)
        except:
            pass
    
    def test_create_new_database(self):
        """Test creating a new database"""
        db = IRODB(self.db_path, auto_create=True)
        self.assertTrue(os.path.exists(self.db_path))
        self.assertEqual(len(db.tables), 0)
        db.close()

class TestCRUDOperations(unittest.TestCase):
    """Test basic CRUD operations"""
    
    def setUp(self):
        self.temp_dir = tempfile.mkdtemp()
        self.db_path = os.path.join(self.temp_dir, 'test.irodb')
        self.db = IRODB(self.db_path, auto_create=True)
        self.db.create_table("users", {
            "name": str,
            "age": int,
            "email": str,
            "active": bool
        })
    
    def tearDown(self):
        self.db.close()
        try:
            os.remove(self.db_path)
        except:
            pass
        try:
            os.rmdir(self.temp_dir)
        except:
            pass
    
    def test_insert_single_row(self):
        """Test inserting a single row"""
        row_id = self.db.insert("users", {
            "name": "Alice",
            "age": 30,
            "email": "alice@example.com",
            "active": True
        })
        self.assertEqual(row_id, 1)
        
        # Verify
        results = self.db.select("users")
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0]["name"], "Alice")

class TestHashFeatures(unittest.TestCase):
    """Test hash-based features"""
    
    def setUp(self):
        self.temp_dir = tempfile.mkdtemp()
        self.db_path = os.path.join(self.temp_dir, 'test_hash.irodb')
        self.db = IRODB(self.db_path, auto_create=True)
        self.db.create_table("users", {
            "name": str,
            "age": int,
            "email": str
        }, enable_hash_index=True)
    
    def tearDown(self):
        self.db.close()
        try:
            os.remove(self.db_path)
        except:
            pass
        try:
            os.rmdir(self.temp_dir)
        except:
            pass
    
    def test_insert_with_hash_generation(self):
        """Test hash generation on insert"""
        row_id, row_hash = self.db.insert("users", {
            "name": "Alice",
            "age": 30,
            "email": "alice@example.com"
        }, return_hash=True)
        
        self.assertEqual(row_id, 1)
        self.assertIsNotNone(row_hash)
        self.assertEqual(len(row_hash), 64)  # SHA-256 hex length
        
        # Verify hash is stored
        results = self.db.select("users", {"name": "Alice"})
        self.assertEqual(results[0]["hash"], row_hash)

if __name__ == "__main__":
    unittest.main()

โš ๏ธ Error Handling

Common Exceptions

from irodb.exceptions import *

try:
    db.insert('users', {'name': 'Alice'})  # Missing required fields
except ValueError as e:
    print(f"Validation error: {e}")

try:
    db.select('nonexistent_table')
except TableError as e:
    print(f"Table error: {e}")

try:
    db.insert('users', {'name': 'Alice', 'age': 'thirty'})  # Wrong type
except TypeError as e:
    print(f"Type error: {e}")

๐Ÿ”ง Configuration

Database Settings

# Database options
db = IRODB(
    'data.irodb',
    auto_create=True,
    page_size=4096,  # Custom page size
    hash_algorithm='sha256'  # Hash algorithm
)

๐Ÿค Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

# Clone your fork
git clone https://github.com/IROTECHLAB/irodb.git

# Install development dependencies
pip install -e .[dev]

# Run tests
pytest tests/

# Check code style
black irodb/
flake8 irodb/

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ‘ฅ Authors

  • IROTECHLAB - Initial work - GitHub

๐Ÿ™ Acknowledgments

  • Built with Python's built-in libraries
  • Inspired by simplicity and data integrity
  • Community contributions welcome

๐Ÿ“ž Contact

๐Ÿ”ฎ Roadmap

  • SQL-like query support
  • Encryption at rest
  • Replication support
  • Backup and restore utilities
  • Web admin interface
  • Migration tools
  • Performance optimizations

Made with โค๏ธ by IROTECHLAB

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

irotechlab_irodb-0.1.0.tar.gz (23.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

irotechlab_irodb-0.1.0-py3-none-any.whl (18.5 kB view details)

Uploaded Python 3

File details

Details for the file irotechlab_irodb-0.1.0.tar.gz.

File metadata

  • Download URL: irotechlab_irodb-0.1.0.tar.gz
  • Upload date:
  • Size: 23.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for irotechlab_irodb-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3e096859980e4b94ef540c0ef9a9f3849de8934f83151fdbb9a69a5ce73c4ab3
MD5 933ce879b10cbac2cf7edc84a2f8099a
BLAKE2b-256 fd215894c0ac751f50765e7ef9686dd61594649480711a5f33786dc0e925c66c

See more details on using hashes here.

Provenance

The following attestation bundles were made for irotechlab_irodb-0.1.0.tar.gz:

Publisher: python-publish.yml on IROTECHLAB/IRODB

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file irotechlab_irodb-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for irotechlab_irodb-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8995cd8dc8ec92c6052531e9552203ed81afe14b61a7e1d428d3a0a2948902ee
MD5 17c2260b90d97aa935ba4b1e82c866f0
BLAKE2b-256 00ae23d759c4ee956347670433ef35b86dc23937a83fdc1445538f41b0d24741

See more details on using hashes here.

Provenance

The following attestation bundles were made for irotechlab_irodb-0.1.0-py3-none-any.whl:

Publisher: python-publish.yml on IROTECHLAB/IRODB

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page