UNPKG

@vishwaraviraaj/galaxydb

Version:

a local database library

223 lines (171 loc) 7.7 kB
const fs = require('fs'); const path = require('path'); class GalaxyUtility { constructor() { this.databaseDir = path.join(__dirname, 'database'); } readTable(tableName) { try { const filePath = path.join(this.databaseDir, `${tableName}.csv`); if (!fs.existsSync(filePath)) { console.log(`Table '${tableName}' does not exist.`); return null; } const data = fs.readFileSync(filePath, 'utf-8').trim().split('\n'); const headers = data.shift().split(','); const records = data.map(row => { const values = row.split(','); return Object.fromEntries(headers.map((field, i) => [field, values[i] || null])); }); console.log(`Successfully read table '${tableName}'.`); return { headers, records }; } catch (error) { console.log(`Error reading table '${tableName}': ${error.message}`); return null; } } innerJoin(table1, table2, key1, key2) { const t1 = this.readTable(table1); const t2 = this.readTable(table2); if (!t1 || !t2) return []; const result = t1.records .map(row1 => { const match = t2.records.find(row2 => row1[key1] === row2[key2]); return match ? { ...row1, ...match } : null; }) .filter(result => result !== null); console.log(`Inner Join between '${table1}' and '${table2}' completed.`); return result; } leftJoin(table1, table2, key1, key2) { const t1 = this.readTable(table1); const t2 = this.readTable(table2); if (!t1 || !t2) return []; const result = t1.records.map(row1 => { const match = t2.records.find(row2 => row1[key1] === row2[key2]); return { ...row1, ...(match || Object.fromEntries(t2.headers.map(field => [field, null]))) }; }); console.log(`Left Join between '${table1}' and '${table2}' completed.`); return result; } rightJoin(table1, table2, key1, key2) { return this.leftJoin(table2, table1, key2, key1); } fullJoin(table1, table2, key1, key2) { const left = this.leftJoin(table1, table2, key1, key2); const right = this.rightJoin(table1, table2, key1, key2); const result = [...left, ...right.filter(row => !left.some(leftRow => leftRow[key1] === row[key1]))]; console.log(`Full Join between '${table1}' and '${table2}' completed.`); return result; } naturalJoin(table1, table2) { const t1 = this.readTable(table1); const t2 = this.readTable(table2); if (!t1 || !t2) return []; const commonKeys = t1.headers.filter(key => t2.headers.includes(key)); const result = t1.records .map(row1 => { const match = t2.records.find(row2 => commonKeys.every(k => row1[k] === row2[k])); return match ? { ...row1, ...match } : null; }) .filter(result => result !== null); console.log(`Natural Join between '${table1}' and '${table2}' completed.`); return result; } rangeQuery(tableName, column, minValue, maxValue) { const table = this.readTable(tableName); if (!table) return []; const result = table.records.filter(row => row[column] >= minValue && row[column] <= maxValue); console.log(`Range Query on '${tableName}' completed.`); return result; } sortBy(tableName, column, order = 'asc') { const table = this.readTable(tableName); if (!table) return []; const result = table.records.sort((a, b) => (order === 'asc' ? a[column] - b[column] : b[column] - a[column])); console.log(`Sort operation on '${tableName}' by column '${column}' (${order}).`); return result; } groupBy(tableName, column) { const table = this.readTable(tableName); if (!table) return {}; const result = table.records.reduce((groups, row) => { const key = row[column]; if (!groups[key]) groups[key] = []; groups[key].push(row); return groups; }, {}); console.log(`Group By '${column}' on '${tableName}' completed.`); return result; } count(tableName, column, value) { const table = this.readTable(tableName); if (!table) return 0; const result = table.records.filter(row => row[column] === value).length; console.log(`Count operation: ${result} records found in '${tableName}' with '${column}' = '${value}'.`); return result; } sum(tableName, column) { const table = this.readTable(tableName); if (!table) return 0; const result = table.records.reduce((sum, row) => sum + (parseFloat(row[column]) || 0), 0); console.log(`Sum operation on '${tableName}', column '${column}' completed.`); return result; } avg(tableName, column) { const table = this.readTable(tableName); if (!table) return 0; const sum = this.sum(tableName, column); const result = sum / table.records.length; console.log(`Average operation on '${tableName}', column '${column}' completed.`); return result; } max(tableName, column) { const table = this.readTable(tableName); if (!table) return null; const result = Math.max(...table.records.map(row => parseFloat(row[column]) || 0)); console.log(`Max operation on '${tableName}', column '${column}' completed.`); return result; } min(tableName, column) { const table = this.readTable(tableName); if (!table) return null; const result = Math.min(...table.records.map(row => parseFloat(row[column]) || 0)); console.log(`Min operation on '${tableName}', column '${column}' completed.`); return result; } firstNRecords(tableName, N) { const table = this.readTable(tableName); if (!table) return []; const result = table.records.slice(0, N); console.log(`First ${N} records fetched from '${tableName}'.`); return result; } countUnique(tableName, column) { const table = this.readTable(tableName); if (!table) return {}; const uniqueCounts = {}; table.records.forEach(row => { const key = row[column] || "NULL"; if (!uniqueCounts[key]) { uniqueCounts[key] = { count: 0, data: [] }; } uniqueCounts[key].count++; uniqueCounts[key].data.push(row); }); console.log(`Count Unique operation completed on '${tableName}', column '${column}'.`); return uniqueCounts; } exists(tableName, conditionFn) { const table = this.readTable(tableName); if (!table) return { count: 0, data: [] }; if (typeof conditionFn !== 'function') { console.log(`Error: Condition must be a function.`); return { count: 0, data: [] }; } const matchingRecords = table.records.filter(conditionFn); console.log(`Found ${matchingRecords.length} matching record(s) in '${tableName}'.`); return { count: matchingRecords.length, data: matchingRecords }; } } module.exports = { GalaxyUtility };