2026-05-03 01:16:25 -03:00
|
|
|
import * as SQLite from "expo-sqlite";
|
|
|
|
|
|
|
|
|
|
const db = SQLite.openDatabaseSync("toptran.db");
|
|
|
|
|
|
|
|
|
|
export type UsuarioDB = {
|
|
|
|
|
id: string;
|
|
|
|
|
email: string;
|
|
|
|
|
name: string;
|
|
|
|
|
token: string;
|
|
|
|
|
created_at: string;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export type CorridaDB = {
|
|
|
|
|
id: string;
|
|
|
|
|
usuario_id: string;
|
|
|
|
|
empresa: string;
|
|
|
|
|
km: number;
|
|
|
|
|
custo_por_km: number;
|
|
|
|
|
total: number;
|
|
|
|
|
data: string;
|
|
|
|
|
sincronizado: 0 | 1;
|
|
|
|
|
created_at: string;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const initDB = async () => {
|
|
|
|
|
try {
|
2026-05-03 02:47:00 -03:00
|
|
|
await db.execAsync(
|
|
|
|
|
`CREATE TABLE IF NOT EXISTS usuarios (
|
2026-05-03 01:16:25 -03:00
|
|
|
id TEXT PRIMARY KEY,
|
|
|
|
|
email TEXT UNIQUE NOT NULL,
|
|
|
|
|
name TEXT NOT NULL,
|
|
|
|
|
token TEXT NOT NULL,
|
|
|
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP
|
2026-05-03 02:47:00 -03:00
|
|
|
);`,
|
|
|
|
|
);
|
|
|
|
|
await db.execAsync(
|
|
|
|
|
`CREATE TABLE IF NOT EXISTS corridas (
|
2026-05-03 01:16:25 -03:00
|
|
|
id TEXT PRIMARY KEY,
|
|
|
|
|
usuario_id TEXT NOT NULL,
|
|
|
|
|
empresa TEXT NOT NULL,
|
|
|
|
|
km REAL NOT NULL,
|
|
|
|
|
custo_por_km REAL NOT NULL,
|
|
|
|
|
total REAL NOT NULL,
|
|
|
|
|
data TEXT NOT NULL,
|
|
|
|
|
sincronizado INTEGER DEFAULT 0,
|
|
|
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
|
FOREIGN KEY (usuario_id) REFERENCES usuarios(id)
|
2026-05-03 02:47:00 -03:00
|
|
|
);`,
|
|
|
|
|
);
|
|
|
|
|
await db.execAsync(
|
|
|
|
|
`CREATE TABLE IF NOT EXISTS settings (
|
2026-05-03 01:16:25 -03:00
|
|
|
key TEXT PRIMARY KEY,
|
|
|
|
|
value TEXT NOT NULL
|
2026-05-03 02:47:00 -03:00
|
|
|
);`,
|
|
|
|
|
);
|
|
|
|
|
await db.execAsync(
|
|
|
|
|
`CREATE TABLE IF NOT EXISTS empresas (
|
|
|
|
|
id TEXT PRIMARY KEY,
|
|
|
|
|
nome TEXT NOT NULL,
|
|
|
|
|
custo_por_km REAL NOT NULL,
|
|
|
|
|
observacoes TEXT DEFAULT '',
|
|
|
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
|
|
|
);`,
|
|
|
|
|
);
|
2026-05-03 01:16:25 -03:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Failed to initialize database:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// SETTINGS (key-value store)
|
|
|
|
|
export const getSetting = async (key: string): Promise<string | null> => {
|
|
|
|
|
try {
|
|
|
|
|
const row = await db.getFirstAsync<{ value: string }>(
|
|
|
|
|
`SELECT value FROM settings WHERE key = ?`,
|
|
|
|
|
[key],
|
|
|
|
|
);
|
|
|
|
|
return row?.value ?? null;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error reading setting:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const setSetting = async (key: string, value: string): Promise<void> => {
|
|
|
|
|
try {
|
|
|
|
|
await db.runAsync(
|
|
|
|
|
`INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)`,
|
|
|
|
|
[key, value],
|
|
|
|
|
);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error writing setting:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const deleteSetting = async (key: string): Promise<void> => {
|
|
|
|
|
try {
|
|
|
|
|
await db.runAsync(`DELETE FROM settings WHERE key = ?`, [key]);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error deleting setting:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// USUÁRIOS
|
2026-05-03 02:47:00 -03:00
|
|
|
export const salvarUsuario = async (
|
|
|
|
|
usuario: Omit<UsuarioDB, "created_at">,
|
|
|
|
|
): Promise<string> => {
|
2026-05-03 01:16:25 -03:00
|
|
|
try {
|
2026-05-03 02:47:00 -03:00
|
|
|
const existing = await db.getFirstAsync<{ id: string }>(
|
|
|
|
|
`SELECT id FROM usuarios WHERE email = ?`,
|
|
|
|
|
[usuario.email],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (existing) {
|
|
|
|
|
// Preserva o ID original — apenas atualiza nome e token
|
|
|
|
|
await db.runAsync(
|
|
|
|
|
`UPDATE usuarios SET name = ?, token = ? WHERE email = ?`,
|
|
|
|
|
[usuario.name, usuario.token, usuario.email],
|
|
|
|
|
);
|
|
|
|
|
return existing.id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await db.runAsync(
|
|
|
|
|
`INSERT INTO usuarios (id, email, name, token) VALUES (?, ?, ?, ?)`,
|
2026-05-03 01:16:25 -03:00
|
|
|
[usuario.id, usuario.email, usuario.name, usuario.token],
|
|
|
|
|
);
|
2026-05-03 02:47:00 -03:00
|
|
|
return usuario.id;
|
2026-05-03 01:16:25 -03:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error saving user:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const obterUsuario = async (
|
|
|
|
|
usuarioId: string,
|
|
|
|
|
): Promise<UsuarioDB | null> => {
|
|
|
|
|
try {
|
|
|
|
|
const result = await db.getFirstAsync<UsuarioDB>(
|
|
|
|
|
`SELECT * FROM usuarios WHERE id = ?`,
|
|
|
|
|
[usuarioId],
|
|
|
|
|
);
|
|
|
|
|
return result || null;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error fetching user:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// CORRIDAS
|
|
|
|
|
export const salvarCorrida = async (corrida: Omit<CorridaDB, "created_at">) => {
|
|
|
|
|
try {
|
|
|
|
|
const result = await db.runAsync(
|
|
|
|
|
`INSERT INTO corridas (id, usuario_id, empresa, km, custo_por_km, total, data, sincronizado)
|
|
|
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
|
|
|
[
|
|
|
|
|
corrida.id,
|
|
|
|
|
corrida.usuario_id,
|
|
|
|
|
corrida.empresa,
|
|
|
|
|
corrida.km,
|
|
|
|
|
corrida.custo_por_km,
|
|
|
|
|
corrida.total,
|
|
|
|
|
corrida.data,
|
|
|
|
|
corrida.sincronizado,
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
return result;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error saving corrida:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const obterCorridas = async (
|
|
|
|
|
usuarioId: string,
|
|
|
|
|
): Promise<CorridaDB[]> => {
|
|
|
|
|
try {
|
|
|
|
|
const result = await db.getAllAsync<CorridaDB>(
|
|
|
|
|
`SELECT * FROM corridas WHERE usuario_id = ? ORDER BY created_at DESC`,
|
|
|
|
|
[usuarioId],
|
|
|
|
|
);
|
|
|
|
|
return result || [];
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error fetching corridas:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const obterCorridasNaoSincronizadas = async (
|
|
|
|
|
usuarioId: string,
|
|
|
|
|
): Promise<CorridaDB[]> => {
|
|
|
|
|
try {
|
|
|
|
|
const result = await db.getAllAsync<CorridaDB>(
|
|
|
|
|
`SELECT * FROM corridas WHERE usuario_id = ? AND sincronizado = 0`,
|
|
|
|
|
[usuarioId],
|
|
|
|
|
);
|
|
|
|
|
return result || [];
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error fetching unsync corridas:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const marcarCorridaComoSincronizada = async (corridaId: string) => {
|
|
|
|
|
try {
|
|
|
|
|
await db.runAsync(`UPDATE corridas SET sincronizado = 1 WHERE id = ?`, [
|
|
|
|
|
corridaId,
|
|
|
|
|
]);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error marking corrida as synced:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const deletarCorrida = async (corridaId: string) => {
|
|
|
|
|
try {
|
|
|
|
|
await db.runAsync(`DELETE FROM corridas WHERE id = ?`, [corridaId]);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error deleting corrida:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const limparBancoDados = async () => {
|
|
|
|
|
try {
|
|
|
|
|
await db.execAsync(`DELETE FROM corridas; DELETE FROM usuarios;`);
|
|
|
|
|
console.log("Database cleared");
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error clearing database:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
2026-05-03 02:47:00 -03:00
|
|
|
|
|
|
|
|
// EMPRESAS
|
|
|
|
|
export type EmpresaDB = {
|
|
|
|
|
id: string;
|
|
|
|
|
nome: string;
|
|
|
|
|
custo_por_km: number;
|
|
|
|
|
observacoes: string;
|
|
|
|
|
created_at: string;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const obterEmpresas = async (): Promise<EmpresaDB[]> => {
|
|
|
|
|
try {
|
|
|
|
|
return (
|
|
|
|
|
(await db.getAllAsync<EmpresaDB>(
|
|
|
|
|
`SELECT * FROM empresas ORDER BY nome ASC`,
|
|
|
|
|
)) ?? []
|
|
|
|
|
);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error fetching empresas:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const salvarEmpresa = async (
|
|
|
|
|
empresa: Omit<EmpresaDB, "created_at">,
|
|
|
|
|
): Promise<void> => {
|
|
|
|
|
try {
|
|
|
|
|
await db.runAsync(
|
|
|
|
|
`INSERT INTO empresas (id, nome, custo_por_km, observacoes) VALUES (?, ?, ?, ?)`,
|
|
|
|
|
[empresa.id, empresa.nome, empresa.custo_por_km, empresa.observacoes],
|
|
|
|
|
);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error saving empresa:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const atualizarEmpresa = async (
|
|
|
|
|
empresa: Omit<EmpresaDB, "created_at">,
|
|
|
|
|
): Promise<void> => {
|
|
|
|
|
try {
|
|
|
|
|
await db.runAsync(
|
|
|
|
|
`UPDATE empresas SET nome = ?, custo_por_km = ?, observacoes = ? WHERE id = ?`,
|
|
|
|
|
[empresa.nome, empresa.custo_por_km, empresa.observacoes, empresa.id],
|
|
|
|
|
);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error updating empresa:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const deletarEmpresa = async (id: string): Promise<void> => {
|
|
|
|
|
try {
|
|
|
|
|
await db.runAsync(`DELETE FROM empresas WHERE id = ?`, [id]);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error deleting empresa:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|