feat: Add mining statistics, turtle groups, and session tracking to database schema

This commit is contained in:
MayaTheShy
2026-02-19 22:47:30 -05:00
parent c5e980f5ec
commit c7315aa3de

View File

@@ -88,6 +88,51 @@ export function initializeDatabase() {
)
`);
// Mining statistics table
db.exec(`
CREATE TABLE IF NOT EXISTS mining_stats (
id INTEGER PRIMARY KEY AUTOINCREMENT,
turtle_id INTEGER NOT NULL,
block_type TEXT NOT NULL,
count INTEGER DEFAULT 1,
session_start INTEGER NOT NULL,
last_mined INTEGER NOT NULL
)
`);
// Turtle groups/teams table
db.exec(`
CREATE TABLE IF NOT EXISTS turtle_groups (
id INTEGER PRIMARY KEY AUTOINCREMENT,
group_name TEXT NOT NULL UNIQUE,
color TEXT DEFAULT '#3b82f6',
created_at INTEGER NOT NULL
)
`);
// Turtle group membership table
db.exec(`
CREATE TABLE IF NOT EXISTS turtle_group_members (
turtle_id INTEGER NOT NULL,
group_id INTEGER NOT NULL,
joined_at INTEGER NOT NULL,
PRIMARY KEY (turtle_id, group_id),
FOREIGN KEY (group_id) REFERENCES turtle_groups(id) ON DELETE CASCADE
)
`);
// Session tracking table (for time-based statistics)
db.exec(`
CREATE TABLE IF NOT EXISTS turtle_sessions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
turtle_id INTEGER NOT NULL,
started_at INTEGER NOT NULL,
ended_at INTEGER,
blocks_mined INTEGER DEFAULT 0,
distance_traveled INTEGER DEFAULT 0
)
`);
// Create indexes for better performance
db.exec(`
CREATE INDEX IF NOT EXISTS idx_world_blocks_discovered
@@ -278,6 +323,138 @@ export function closeMiningArea(areaId) {
stmt.run(Date.now(), areaId);
}
// Mining Statistics
export function recordBlockMined(turtleId, blockType) {
const stmt = db.prepare(`
INSERT INTO mining_stats (turtle_id, block_type, count, session_start, last_mined)
VALUES (?, ?, 1, ?, ?)
ON CONFLICT(turtle_id, block_type, session_start)
DO UPDATE SET count = count + 1, last_mined = ?
`);
const now = Date.now();
const sessionStart = now - (now % (24 * 60 * 60 * 1000)); // Start of day
stmt.run(turtleId, blockType, sessionStart, now, now);
}
export function getMiningStats(turtleId = null, days = 7) {
const cutoff = Date.now() - (days * 24 * 60 * 60 * 1000);
if (turtleId) {
const stmt = db.prepare(`
SELECT block_type, SUM(count) as total_count
FROM mining_stats
WHERE turtle_id = ? AND session_start >= ?
GROUP BY block_type
ORDER BY total_count DESC
`);
return stmt.all(turtleId, cutoff);
} else {
const stmt = db.prepare(`
SELECT turtle_id, block_type, SUM(count) as total_count
FROM mining_stats
WHERE session_start >= ?
GROUP BY turtle_id, block_type
ORDER BY turtle_id, total_count DESC
`);
return stmt.all(cutoff);
}
}
export function getTopMiners(limit = 10) {
const stmt = db.prepare(`
SELECT turtle_id, SUM(count) as total_blocks
FROM mining_stats
GROUP BY turtle_id
ORDER BY total_blocks DESC
LIMIT ?
`);
return stmt.all(limit);
}
// Turtle Groups/Teams
export function createGroup(groupName, color = '#3b82f6') {
const stmt = db.prepare(`
INSERT INTO turtle_groups (group_name, color, created_at)
VALUES (?, ?, ?)
`);
const result = stmt.run(groupName, color, Date.now());
return result.lastInsertRowid;
}
export function getAllGroups() {
const stmt = db.prepare('SELECT * FROM turtle_groups ORDER BY created_at DESC');
return stmt.all();
}
export function deleteGroup(groupId) {
const stmt = db.prepare('DELETE FROM turtle_groups WHERE id = ?');
stmt.run(groupId);
}
export function addTurtleToGroup(turtleId, groupId) {
const stmt = db.prepare(`
INSERT OR IGNORE INTO turtle_group_members (turtle_id, group_id, joined_at)
VALUES (?, ?, ?)
`);
stmt.run(turtleId, groupId, Date.now());
}
export function removeTurtleFromGroup(turtleId, groupId) {
const stmt = db.prepare(`
DELETE FROM turtle_group_members
WHERE turtle_id = ? AND group_id = ?
`);
stmt.run(turtleId, groupId);
}
export function getGroupMembers(groupId) {
const stmt = db.prepare(`
SELECT turtle_id, joined_at
FROM turtle_group_members
WHERE group_id = ?
`);
return stmt.all(groupId);
}
export function getTurtleGroups(turtleId) {
const stmt = db.prepare(`
SELECT g.*, m.joined_at
FROM turtle_groups g
JOIN turtle_group_members m ON g.id = m.group_id
WHERE m.turtle_id = ?
`);
return stmt.all(turtleId);
}
// Session Tracking
export function startSession(turtleId) {
const stmt = db.prepare(`
INSERT INTO turtle_sessions (turtle_id, started_at)
VALUES (?, ?)
`);
const result = stmt.run(turtleId, Date.now());
return result.lastInsertRowid;
}
export function endSession(sessionId, blocksMined, distanceTraveled) {
const stmt = db.prepare(`
UPDATE turtle_sessions
SET ended_at = ?, blocks_mined = ?, distance_traveled = ?
WHERE id = ?
`);
stmt.run(Date.now(), blocksMined, distanceTraveled, sessionId);
}
export function getSessionStats(turtleId, limit = 10) {
const stmt = db.prepare(`
SELECT * FROM turtle_sessions
WHERE turtle_id = ?
ORDER BY started_at DESC
LIMIT ?
`);
return stmt.all(turtleId, limit);
}
// Cleanup function
export function closeDatabase() {
db.close();