149 lines
3.8 KiB
TypeScript
149 lines
3.8 KiB
TypeScript
import { Database } from "bun:sqlite";
|
|
|
|
export interface Deployment {
|
|
id?: number;
|
|
created_at?: string;
|
|
repository: string;
|
|
branch?: string;
|
|
commit_hash?: string;
|
|
status: string;
|
|
}
|
|
|
|
export interface Command {
|
|
id?: number;
|
|
deployment_id: number;
|
|
command: string;
|
|
stdout?: string;
|
|
stderr?: string;
|
|
exit_code?: number;
|
|
success: boolean;
|
|
}
|
|
|
|
let db: Database;
|
|
|
|
/**
|
|
* Initialize SQLite database with schema
|
|
*/
|
|
export function initializeDatabase(dbPath?: string): Database {
|
|
db = new Database(dbPath || "deployments.db");
|
|
|
|
// Create deployments table
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS deployments (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
repository TEXT NOT NULL,
|
|
branch TEXT,
|
|
commit_hash TEXT,
|
|
status TEXT NOT NULL
|
|
)
|
|
`);
|
|
|
|
// Create commands table
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS commands (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
deployment_id INTEGER,
|
|
command TEXT,
|
|
stdout TEXT,
|
|
stderr TEXT,
|
|
exit_code INTEGER,
|
|
success BOOLEAN,
|
|
FOREIGN KEY(deployment_id) REFERENCES deployments(id)
|
|
)
|
|
`);
|
|
|
|
console.log("✅ Database initialized successfully");
|
|
return db;
|
|
}
|
|
|
|
/**
|
|
* Get database instance
|
|
*/
|
|
export function getDb(): Database {
|
|
if (!db) {
|
|
throw new Error("Database not initialized. Call initializeDatabase first.");
|
|
}
|
|
return db;
|
|
}
|
|
|
|
/**
|
|
* Create a deployment record in the database
|
|
*/
|
|
export function createDeployment(
|
|
repository: string,
|
|
branch?: string,
|
|
commitHash?: string,
|
|
status: string = "in_progress"
|
|
): number {
|
|
const insertDeployment = getDb().prepare(`
|
|
INSERT INTO deployments (repository, branch, commit_hash, status)
|
|
VALUES (?, ?, ?, ?)
|
|
`);
|
|
const result = insertDeployment.run(repository, branch || null, commitHash || null, status);
|
|
return result.lastInsertRowid as number;
|
|
}
|
|
|
|
/**
|
|
* Update deployment status
|
|
*/
|
|
export function updateDeploymentStatus(deploymentId: number, status: string): void {
|
|
const updateDeployment = getDb().prepare(`
|
|
UPDATE deployments SET status = ? WHERE id = ?
|
|
`);
|
|
updateDeployment.run(status, deploymentId);
|
|
}
|
|
|
|
/**
|
|
* Insert a command record
|
|
*/
|
|
export function insertCommand(
|
|
deploymentId: number,
|
|
command: string,
|
|
stdout: string,
|
|
stderr: string | null,
|
|
exitCode: number,
|
|
success: boolean
|
|
): void {
|
|
const insertCmd = getDb().prepare(`
|
|
INSERT INTO commands (deployment_id, command, stdout, stderr, exit_code, success)
|
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
`);
|
|
insertCmd.run(deploymentId, command, stdout, stderr, exitCode, success ? 1 : 0);
|
|
}
|
|
|
|
/**
|
|
* Get deployments with optional filtering
|
|
*/
|
|
export function getDeployments(limit: number = 50, repository?: string): Deployment[] {
|
|
let query = "SELECT * FROM deployments";
|
|
const params: any[] = [];
|
|
|
|
if (repository) {
|
|
query += " WHERE repository = ?";
|
|
params.push(repository);
|
|
}
|
|
|
|
query += " ORDER BY created_at DESC LIMIT ?";
|
|
params.push(limit);
|
|
|
|
const stmt = getDb().prepare(query);
|
|
return stmt.all(...params) as Deployment[];
|
|
}
|
|
|
|
/**
|
|
* Get deployment by ID
|
|
*/
|
|
export function getDeploymentById(deploymentId: number): Deployment | undefined {
|
|
const stmt = getDb().prepare("SELECT * FROM deployments WHERE id = ?");
|
|
return stmt.get(deploymentId) as Deployment | undefined;
|
|
}
|
|
|
|
/**
|
|
* Get commands for a deployment
|
|
*/
|
|
export function getCommandsByDeploymentId(deploymentId: number): Command[] {
|
|
const stmt = getDb().prepare("SELECT * FROM commands WHERE deployment_id = ? ORDER BY id ASC");
|
|
return stmt.all(deploymentId) as Command[];
|
|
}
|