This guide shows you how to view and interact with your SQLite database, both locally and on Railway.
- Database file:
typing_game.db - Total users: 2 (bijoux, testuser)
- Total game sessions: 68+
Visit this URL in your browser or use curl:
https://YOUR-RAILWAY-URL/api/db-overviewThis returns a complete JSON overview with:
- Total counts for all tables
- Recent users (last 10)
- Recent game sessions (last 20)
- Full leaderboard with stats
- Sentence attempts count
# View all users
https://YOUR-RAILWAY-URL/api/users
# View leaderboard
https://YOUR-RAILWAY-URL/api/leaderboard
# View specific user stats (replace 2 with user ID)
https://YOUR-RAILWAY-URL/api/users/2/stats
# View user sessions
https://YOUR-RAILWAY-URL/api/users/2/sessionsTip: You can use these URLs in your browser or with curl:
curl https://YOUR-RAILWAY-URL/api/db-overview
curl https://YOUR-RAILWAY-URL/api/leaderboardRun the interactive database viewer:
./view-db.shThis will show you a menu with options to view:
- All Users
- All Game Sessions
- Leaderboard
- Recent Sessions
- Sessions by User
- Database Schema
- Custom SQL Query
While your server is running (npm run dev), you can use these endpoints:
curl http://localhost:3001/api/userscurl http://localhost:3001/api/leaderboardcurl http://localhost:3001/api/users/2/statscurl http://localhost:3001/api/users/2/sessionssqlite3 -header -column typing_game.db "SELECT id, username, created_at FROM users;"sqlite3 -header -column typing_game.db "SELECT u.username, MAX(s.score) as best_score, ROUND(AVG(s.wpm), 2) as avg_wpm, COUNT(s.id) as sessions_played FROM users u LEFT JOIN game_sessions s ON u.id = s.user_id GROUP BY u.id ORDER BY best_score DESC;"sqlite3 -header -column typing_game.db "SELECT s.id, u.username, s.score, s.sentences_completed, s.wpm, s.created_at FROM game_sessions s LEFT JOIN users u ON s.user_id = u.id ORDER BY s.created_at DESC LIMIT 10;"sqlite3 -header -column typing_game.db "SELECT * FROM game_sessions WHERE user_id = 2 ORDER BY created_at DESC LIMIT 10;"sqlite3 typing_game.db ".schema"sqlite3 typing_game.db "SELECT COUNT(*) as total_sessions FROM game_sessions;"Open the database in interactive mode:
sqlite3 typing_game.dbOnce inside, you can run SQL queries:
-- View all tables
.tables
-- View schema
.schema users
.schema game_sessions
-- Query data
SELECT * FROM users;
SELECT * FROM game_sessions LIMIT 10;
-- Exit
.quitCREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
email TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE game_sessions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER,
score INTEGER,
time_left INTEGER,
sentences_completed INTEGER,
accuracy REAL,
wpm REAL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);CREATE TABLE sentence_attempts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id INTEGER,
sentence TEXT,
user_input TEXT,
is_correct INTEGER,
time_taken REAL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (session_id) REFERENCES game_sessions(id)
);SELECT u.username, MAX(s.score) as highest_score
FROM users u
JOIN game_sessions s ON u.id = s.user_id
GROUP BY u.username
ORDER BY highest_score DESC
LIMIT 1;SELECT u.username, ROUND(AVG(s.wpm), 2) as avg_wpm
FROM users u
JOIN game_sessions s ON u.id = s.user_id
GROUP BY u.username
ORDER BY avg_wpm DESC;SELECT u.username, COUNT(s.id) as total_sessions
FROM users u
LEFT JOIN game_sessions s ON u.id = s.user_id
GROUP BY u.username
ORDER BY total_sessions DESC;SELECT s.id, u.username, s.score, s.sentences_completed, s.accuracy, s.created_at
FROM game_sessions s
JOIN users u ON s.user_id = u.id
WHERE s.accuracy = 100.0
ORDER BY s.created_at DESC;- Format output nicely: Use
-header -columnflags with sqlite3 for readable output - Limit results: Add
LIMIT 10to queries that might return many rows - Save queries: Create shell aliases or scripts for frequently used queries
- Backup database: Regularly backup your
typing_game.dbfile - Use the script: The
view-db.shscript is the easiest way to explore your data!
Run these commands to see your current data:
# User count
sqlite3 typing_game.db "SELECT COUNT(*) as total_users FROM users;"
# Session count
sqlite3 typing_game.db "SELECT COUNT(*) as total_sessions FROM game_sessions;"
# Leaderboard
sqlite3 -header -column typing_game.db "SELECT u.username, MAX(s.score) as best_score, ROUND(AVG(s.wpm), 2) as avg_wpm, COUNT(s.id) as sessions FROM users u LEFT JOIN game_sessions s ON u.id = s.user_id GROUP BY u.id ORDER BY best_score DESC;"