UNPKG

react-native-sst-storage-db

Version:

A powerful file-based MongoDB-like database for React Native. Single JSON file storage with collections, advanced querying, indexing, and atomic operations. No AsyncStorage dependency.

188 lines (161 loc) 5.51 kB
/** * Collection Indexing Methods * Provides indexing functionality for improved query performance */ class CollectionIndexing { /** * Update indexes when inserting a document */ static updateIndexesForInsert(collection, document) { const indexes = collection._getCollectionIndexes(); for (const [field, index] of Object.entries(indexes)) { const value = collection.queryEngine.getNestedValue(document, field); if (value !== undefined) { if (!index[value]) { index[value] = []; } index[value].push(document._id); } } } /** * Update indexes when updating a document */ static updateIndexesForUpdate(collection, oldDocument, newDocument) { const indexes = collection._getCollectionIndexes(); for (const [field, index] of Object.entries(indexes)) { const oldValue = collection.queryEngine.getNestedValue(oldDocument, field); const newValue = collection.queryEngine.getNestedValue(newDocument, field); // Remove old value from index if (oldValue !== undefined && index[oldValue]) { const idIndex = index[oldValue].indexOf(oldDocument._id); if (idIndex !== -1) { index[oldValue].splice(idIndex, 1); if (index[oldValue].length === 0) { delete index[oldValue]; } } } // Add new value to index if (newValue !== undefined) { if (!index[newValue]) { index[newValue] = []; } if (!index[newValue].includes(newDocument._id)) { index[newValue].push(newDocument._id); } } } } /** * Update indexes when deleting a document */ static updateIndexesForDelete(collection, document) { const indexes = collection._getCollectionIndexes(); for (const [field, index] of Object.entries(indexes)) { const value = collection.queryEngine.getNestedValue(document, field); if (value !== undefined && index[value]) { const idIndex = index[value].indexOf(document._id); if (idIndex !== -1) { index[value].splice(idIndex, 1); if (index[value].length === 0) { delete index[value]; } } } } } /** * Create an index on a field */ static createIndex(collection, field) { const indexes = collection._getCollectionIndexes(); if (indexes[field]) { return; // Index already exists } // Create new index indexes[field] = {}; const collectionData = collection._getCollectionData(); // Build index from existing documents for (const document of collectionData) { const value = collection.queryEngine.getNestedValue(document, field); if (value !== undefined) { if (!indexes[field][value]) { indexes[field][value] = []; } indexes[field][value].push(document._id); } } collection.storage.log(`✓ Index created on field: ${field}`); } /** * Drop an index */ static dropIndex(collection, field) { const indexes = collection._getCollectionIndexes(); if (indexes[field]) { delete indexes[field]; collection.storage.log(`✓ Index dropped on field: ${field}`); } } /** * Get index statistics */ static getIndexStats(collection) { const indexes = collection._getCollectionIndexes(); const stats = {}; for (const [field, index] of Object.entries(indexes)) { stats[field] = { keyCount: Object.keys(index).length, totalDocuments: Object.values(index).reduce((sum, ids) => sum + ids.length, 0) }; } return stats; } /** * Rebuild all indexes */ static rebuildIndexes(collection) { const indexes = collection._getCollectionIndexes(); const fields = Object.keys(indexes); // Clear existing indexes for (const field of fields) { indexes[field] = {}; } // Rebuild from collection data const collectionData = collection._getCollectionData(); for (const document of collectionData) { for (const field of fields) { const value = collection.queryEngine.getNestedValue(document, field); if (value !== undefined) { if (!indexes[field][value]) { indexes[field][value] = []; } indexes[field][value].push(document._id); } } } collection.storage.log(`✓ Rebuilt ${fields.length} indexes`); } /** * Use index to optimize queries (basic implementation) */ static optimizeQuery(collection, query) { const indexes = collection._getCollectionIndexes(); const collectionData = collection._getCollectionData(); // Check if query can use an index for (const [field, condition] of Object.entries(query)) { if (indexes[field] && typeof condition !== 'object') { // Simple equality query can use index const ids = indexes[field][condition] || []; const results = ids.map(id => collectionData.find(doc => doc._id === id) ).filter(doc => doc !== undefined); return results; } } // No index optimization possible return null; } } module.exports = CollectionIndexing;