153 lines
4.8 KiB
C++
153 lines
4.8 KiB
C++
#include <db_ops.h>
|
||
#include <string>
|
||
#include <cstring>
|
||
#include <tools.h>
|
||
using namespace std;
|
||
|
||
sqlite3 *create_db(const char *db_path, bool overwrite_file)
|
||
{
|
||
if (overwrite_file)
|
||
{
|
||
if (remove(db_path) != 0 && errno != ENOENT)
|
||
{
|
||
fprintf(stderr, "Failed to remove old DB file: %s\n", strerror(errno));
|
||
return NULL;
|
||
}
|
||
}
|
||
|
||
sqlite3 *db = NULL;
|
||
int result_code = sqlite3_open(db_path, &db);
|
||
if (result_code != SQLITE_OK)
|
||
{
|
||
fprintf(stderr, "Failed to open DB: %s[%d]\n", sqlite3_errmsg(db), result_code);
|
||
sqlite3_close(db);
|
||
return NULL;
|
||
}
|
||
return db;
|
||
}
|
||
|
||
void create_tables(sqlite3 *db)
|
||
{
|
||
const char *sql_meshes = R"(
|
||
CREATE TABLE IF NOT EXISTS meshes (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
name TEXT NOT NULL,
|
||
vertex_count INTEGER NOT NULL,
|
||
index_count INTEGER NOT NULL,
|
||
fbx_id TEXT UNIQUE NOT NULL
|
||
);
|
||
)";
|
||
|
||
const char *sql_materials = R"(
|
||
CREATE TABLE IF NOT EXISTS materials (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
name TEXT NOT NULL,
|
||
shader_name TEXT,
|
||
fbx_id TEXT UNIQUE NOT NULL,
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
)";
|
||
|
||
const char *sql_vertices = R"(
|
||
CREATE TABLE IF NOT EXISTS vertices (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
mesh_id INTEGER NOT NULL,
|
||
position_x REAL NOT NULL,
|
||
position_y REAL NOT NULL,
|
||
position_z REAL NOT NULL,
|
||
normal_x REAL,
|
||
normal_y REAL,
|
||
normal_z REAL,
|
||
uv_u REAL,
|
||
uv_v REAL,
|
||
FOREIGN KEY(mesh_id) REFERENCES meshes(id) ON DELETE CASCADE
|
||
);
|
||
)";
|
||
|
||
const char *sql_indices = R"(
|
||
CREATE TABLE IF NOT EXISTS indices (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
mesh_id INTEGER NOT NULL,
|
||
value INTEGER NOT NULL,
|
||
FOREIGN KEY(mesh_id) REFERENCES meshes(id) ON DELETE CASCADE
|
||
);
|
||
)";
|
||
|
||
const char *sql_material_props = R"(
|
||
CREATE TABLE IF NOT EXISTS material_properties (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
material_id INTEGER NOT NULL,
|
||
key TEXT NOT NULL,
|
||
value TEXT NOT NULL,
|
||
type TEXT NOT NULL,
|
||
FOREIGN KEY(material_id) REFERENCES materials(id) ON DELETE CASCADE,
|
||
UNIQUE(material_id, key)
|
||
);
|
||
)";
|
||
|
||
const char *sql[] = {sql_meshes, sql_materials, sql_vertices, sql_indices, sql_material_props};
|
||
for (int i = 0; i < sizeof(sql) / sizeof(sql[0]); ++i)
|
||
{
|
||
printf("开始执行:%s", sql[i]);
|
||
// 检查前置条件:数据库连接和SQL语句必须有效
|
||
if (!db)
|
||
{
|
||
printf("db 是空的");
|
||
// 处理空连接错误(如log.Fatalf("db connection is NULL"))
|
||
return; // 或抛异常终止
|
||
}
|
||
if (!sql[i] || strlen(sql[i]) == 0)
|
||
{
|
||
printf("SQL Query 是空的");
|
||
// 处理空SQL错误(如log.Errorf("sql[%d] is NULL/empty", i))
|
||
continue; // 或终止
|
||
}
|
||
|
||
char *err_msg = nullptr;
|
||
int ret = sqlite3_exec(db, sql[i], nullptr, nullptr, &err_msg);
|
||
printf("db ret: %d, err_msg: %s\n", ret, err_msg);
|
||
if (ret != SQLITE_OK)
|
||
{
|
||
// 必须处理错误:记录具体SQL和错误信息
|
||
// log.Criticalf("SQL error (i=%d): %s, SQL: %s", i, err_msg ? err_msg : "unknown", sql[i]);
|
||
sqlite3_free(err_msg); // 释放错误信息
|
||
return; // 或根据场景决定是否继续
|
||
}
|
||
// 成功执行无需释放err_msg(sqlite3_exec成功时err_msg为NULL)
|
||
}
|
||
}
|
||
|
||
|
||
// 函数定义
|
||
int save_mesh_to_table(FttContext* ctx,
|
||
sqlite3* db,
|
||
uint id,
|
||
const std::string& name,
|
||
int vertex_count, int index_count,
|
||
const std::string& fbx_id)
|
||
{
|
||
|
||
if (!db || name.empty() || fbx_id.empty()) return -1;
|
||
|
||
sqlite3_stmt* stmt = nullptr;
|
||
const char* sql = "INSERT OR IGNORE INTO meshes (id, name, vertex_count, index_count, fbx_id) VALUES (?, ?, ?, ?, ?);";
|
||
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr);
|
||
if (rc != SQLITE_OK) {
|
||
fprintf(stderr, "SQL prepare failed: %s\n", sqlite3_errmsg(db));
|
||
return rc;
|
||
}
|
||
|
||
sqlite3_bind_int64(stmt, 1, id);
|
||
sqlite3_bind_text(stmt, 2, name.c_str(), -1, SQLITE_STATIC);
|
||
sqlite3_bind_int(stmt, 3, vertex_count);
|
||
sqlite3_bind_int(stmt, 4, index_count);
|
||
sqlite3_bind_text(stmt, 5, fbx_id.c_str(), -1, SQLITE_STATIC);
|
||
|
||
rc = sqlite3_step(stmt);
|
||
if (rc != SQLITE_DONE && rc != SQLITE_CONSTRAINT) {
|
||
fprintf(stderr, "SQL step failed: %s\n", sqlite3_errmsg(db));
|
||
}
|
||
|
||
sqlite3_finalize(stmt);
|
||
return rc == SQLITE_DONE ? 0 : -1;
|
||
} |