1
0
mirror of https://git.code.sf.net/p/minidlna/git synced 2025-04-20 12:10:22 +00:00
Files
minidlna/sql.c
2011-03-30 22:31:39 +00:00

201 lines
4.2 KiB
C

/* MiniDLNA media server
* Copyright (C) 2008-2009 Justin Maggard
*
* This file is part of MiniDLNA.
*
* MiniDLNA is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* MiniDLNA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MiniDLNA. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "sql.h"
#include "log.h"
int
sql_exec(sqlite3 *db, const char *fmt, ...)
{
int ret;
char *errMsg = NULL;
char *sql;
va_list ap;
//DPRINTF(E_DEBUG, L_DB_SQL, "SQL: %s\n", sql);
va_start(ap, fmt);
sql = sqlite3_vmprintf(fmt, ap);
ret = sqlite3_exec(db, sql, 0, 0, &errMsg);
if( ret != SQLITE_OK )
{
DPRINTF(E_ERROR, L_DB_SQL, "SQL ERROR %d [%s]\n%s\n", ret, errMsg, sql);
if (errMsg)
sqlite3_free(errMsg);
}
sqlite3_free(sql);
return ret;
}
int
sql_get_table(sqlite3 *db, const char *sql, char ***pazResult, int *pnRow, int *pnColumn)
{
int ret;
char *errMsg = NULL;
//DPRINTF(E_DEBUG, L_DB_SQL, "SQL: %s\n", sql);
ret = sqlite3_get_table(db, sql, pazResult, pnRow, pnColumn, &errMsg);
if( ret != SQLITE_OK )
{
DPRINTF(E_ERROR, L_DB_SQL, "SQL ERROR %d [%s]\n%s\n", ret, errMsg, sql);
if (errMsg)
sqlite3_free(errMsg);
}
return ret;
}
int
sql_get_int_field(sqlite3 *db, const char *fmt, ...)
{
va_list ap;
int counter, result;
char *sql;
int ret;
sqlite3_stmt *stmt;
va_start(ap, fmt);
sql = sqlite3_vmprintf(fmt, ap);
//DPRINTF(E_DEBUG, L_DB_SQL, "sql: %s\n", sql);
switch (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL))
{
case SQLITE_OK:
break;
default:
DPRINTF(E_ERROR, L_DB_SQL, "prepare failed: %s\n%s\n", sqlite3_errmsg(db), sql);
sqlite3_free(sql);
return -1;
}
sqlite3_free(sql);
for (counter = 0;
((result = sqlite3_step(stmt)) == SQLITE_BUSY || result == SQLITE_LOCKED) && counter < 2;
counter++) {
/* While SQLITE_BUSY has a built in timeout,
SQLITE_LOCKED does not, so sleep */
if (result == SQLITE_LOCKED)
sleep(1);
}
switch (result)
{
case SQLITE_DONE:
/* no rows returned */
ret = 0;
break;
case SQLITE_ROW:
if (sqlite3_column_type(stmt, 0) == SQLITE_NULL)
{
ret = 0;
break;
}
ret = sqlite3_column_int(stmt, 0);
break;
default:
DPRINTF(E_WARN, L_DB_SQL, "%s: step failed: %s\n", __func__, sqlite3_errmsg(db));
ret = -1;
break;
}
sqlite3_finalize(stmt);
return ret;
}
char *
sql_get_text_field(void *db, const char *fmt, ...)
{
va_list ap;
int counter, result, len;
char *sql;
char *str;
sqlite3_stmt *stmt;
va_start(ap, fmt);
if (db == NULL)
{
DPRINTF(E_WARN, L_DB_SQL, "db is NULL\n");
return NULL;
}
sql = sqlite3_vmprintf(fmt, ap);
//DPRINTF(E_DEBUG, L_DB_SQL, "sql: %s\n", sql);
switch (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL))
{
case SQLITE_OK:
break;
default:
DPRINTF(E_ERROR, L_DB_SQL, "prepare failed: %s\n%s\n", sqlite3_errmsg(db), sql);
sqlite3_free(sql);
return NULL;
}
sqlite3_free(sql);
for (counter = 0;
((result = sqlite3_step(stmt)) == SQLITE_BUSY || result == SQLITE_LOCKED) && counter < 2;
counter++)
{
/* While SQLITE_BUSY has a built in timeout,
* SQLITE_LOCKED does not, so sleep */
if (result == SQLITE_LOCKED)
sleep(1);
}
switch (result)
{
case SQLITE_DONE:
/* no rows returned */
str = NULL;
break;
case SQLITE_ROW:
if (sqlite3_column_type(stmt, 0) == SQLITE_NULL)
{
str = NULL;
break;
}
len = sqlite3_column_bytes(stmt, 0);
if ((str = sqlite3_malloc(len + 1)) == NULL)
{
DPRINTF(E_ERROR, L_DB_SQL, "malloc failed\n");
break;
}
strncpy(str, (char *)sqlite3_column_text(stmt, 0), len + 1);
break;
default:
DPRINTF(E_WARN, L_DB_SQL, "SQL step failed: %s\n", sqlite3_errmsg(db));
str = NULL;
break;
}
sqlite3_finalize(stmt);
return str;
}