// The MIT License (MIT)
//
// Copyright (C) 2026 Scott Duensing
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

// dvxSql.h -- DVX SQL database interface
//
// High-level wrapper around SQLite3. Manages database connections
// and result set cursors via integer handles so BASIC code never
// touches raw pointers. Thread-safe is not a concern (DOS is
// single-threaded).

#ifndef DVX_SQL_H
#define DVX_SQL_H

#include <stdint.h>
#include <stdbool.h>

// ============================================================
// Database operations
// ============================================================

// Open a database file. Returns a handle > 0 on success, 0 on error.
int32_t dvxSqlOpen(const char *path);

// Close a database and free its resources.
void dvxSqlClose(int32_t db);

// Execute a SQL statement that returns no results (DDL, INSERT, UPDATE, DELETE).
// Returns true on success, false on error.
bool dvxSqlExec(int32_t db, const char *sql);

// Return the last error message for a database handle.
const char *dvxSqlError(int32_t db);

// Return the number of rows affected by the last INSERT/UPDATE/DELETE.
int32_t dvxSqlAffectedRows(int32_t db);

// ============================================================
// Result set (cursor) operations
// ============================================================

// Execute a SELECT query. Returns a cursor handle > 0, or 0 on error.
// The cursor is positioned BEFORE the first row; call dvxSqlNext to
// advance to the first row.
int32_t dvxSqlQuery(int32_t db, const char *sql);

// Advance to the next row. Returns true if a row is available.
bool dvxSqlNext(int32_t rs);

// Return true if the cursor is past the last row.
bool dvxSqlEof(int32_t rs);

// Return the number of columns in the result set.
int32_t dvxSqlFieldCount(int32_t rs);

// Return the name of column N (0-based).
const char *dvxSqlFieldName(int32_t rs, int32_t col);

// Return the value of column N as a string.
const char *dvxSqlFieldText(int32_t rs, int32_t col);

// Return the value of the named column as a string.
const char *dvxSqlFieldByName(int32_t rs, const char *name);

// Return the value of column N as an integer.
int32_t dvxSqlFieldInt(int32_t rs, int32_t col);

// Return the value of column N as a double.
double dvxSqlFieldDbl(int32_t rs, int32_t col);

// Close a result set cursor and free its resources.
void dvxSqlFreeResult(int32_t rs);

// ============================================================
// Utility
// ============================================================

// Escape a string for safe use in SQL string literals. Doubles single
// quotes so that "O'Brien" becomes "O''Brien". Writes the result to
// dst (up to dstSize-1 chars + null terminator). Returns the length
// of the escaped string, or -1 if the buffer was too small.
int32_t dvxSqlEscape(const char *src, char *dst, int32_t dstSize);

#endif // DVX_SQL_H
