blob: d56adf2d9c65b1e8cb1a6e078f16202195f7f030 [file] [log] [blame]
/*
** -------------------------------------------------------------
** Copyright 2004-2008 Synopsys, Inc.
** All Rights Reserved Worldwide
**
** Licensed under the Apache License, Version 2.0 (the
** "License"); you may not use this file except in
** compliance with the License. You may obtain a copy of
** the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in
** writing, software distributed under the License is
** distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
** CONDITIONS OF ANY KIND, either express or implied. See
** the License for the specific language governing
** permissions and limitations under the License.
** -------------------------------------------------------------
*/
#include "vmm_sql_sys_info.c"
#define VMM_SQL_DEBUG 0
#define VMM_SQL_DYNLOAD 1
#include <stdio.h>
#include <dlfcn.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "sqlite3.h"
/**************************************************************/
/* User defined types */
/**************************************************************/
typedef enum {VMM_SQL_PASS = 0, VMM_SQL_FAIL} vmm_sqlite_status_e;
typedef struct vmm_sqlite_db_entry_s {
char *name;
sqlite3* db;
struct vmm_sqlite_db_entry_s *next;
} vmm_sqlite_db_entry_t;
/**************************************************************/
/* Protos */
/**************************************************************/
vmm_sqlite_status_e vmm_sqlite_execute(sqlite3 *db, const char *stmt);
vmm_sqlite_status_e vmm_sqlite_dynload_get_function(void **p, const char* fn);
vmm_sqlite_status_e vmm_sqlite_dynload_sqlib();
void vmm_sqlite_delete_db(const char *name);
sqlite3* vmm_sqlite_get_db(const char *name);
vmm_sqlite_status_e vmm_sqlite_add_db(const char *name);
int vmm_sqlite_file_exists(const char *filename);
/**************************************************************/
/* Globals */
/**************************************************************/
char vmm_sqlite_err_str[100] = "";
struct {
vmm_sqlite_db_entry_t *entry;
} vmm_sqlite_db_q = { NULL };
sqlite3 *db;
void *sqlib_handle;
int (*sqlite3_open_p) (
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
int (*sqlite3_close_p) (
sqlite3 *
);
const char * (*sqlite3_errmsg_p)(
sqlite3*
);
void (*sqlite3_free_p) (
void*
);
int (*sqlite3_exec_p) (
sqlite3*, /* An open database */
const char *sql, /* SQL to be executed */
sqlite3_callback, /* Callback function */
void *, /* 1st argument to callback function */
char **errmsg /* Error msg written here */
);
int (*sqlite3_complete_p) (
const char *sql
);
/*************************************************
* DPI interface function
* Execute an sql statement on an OPEN database.
* Return 0 on Success
*************************************************/
int vmm_sqlite_execute_dpi(const char *dbname, const char * sql_stmt)
{
#if VMM_SQL_DEBUG
printf("*DEBUG* SQL cmd %s\n", sql_stmt);
#endif /* VMM_SQL_DEBUG */
if(vmm_sqlite_execute( vmm_sqlite_get_db(dbname), sql_stmt) == VMM_SQL_FAIL)
{
return(1);
}
return(0);
}
/*************************************************
* DPI interface function
* Closes an SQL database, indexed by name, and
* removes from the active database list.
*************************************************/
void vmm_sqlite_close_db_dpi(const char* dbname)
{
vmm_sqlite_delete_db(dbname);
}
/*************************************************
* DPI interface function
* Create a SQLite database with a name
* Return 0 on success
*************************************************/
int vmm_sqlite_create_db_dpi(const char* dbname)
{
if (vmm_sqlite_add_db(dbname) == VMM_SQL_FAIL)
{
return(1);
}
else
{
return(0);
}
}
/*************************************************
* DPI interface function
* Initialize / load the dynamic library.
* Return 0 on success
*************************************************/
static int vmm_sqlite_lib_loaded = 0;
int vmm_sqlite_init_dpi()
{
if (!vmm_sqlite_lib_loaded)
{
if (vmm_sqlite_dynload_sqlib() == VMM_SQL_FAIL)
{
return(1);
}
vmm_sqlite_lib_loaded = 1;
}
return(0);
}
/*************************************************
* DPI interface function
* Return the last error message.
* may be garbage is the last operation was a
* success, so caller must test operation failure
* before using.
*************************************************/
char *vmm_sqlite_error_dpi()
{
return(vmm_sqlite_err_str);
}
/*************************************************
* DPI interface function
* Return a DB-wide unique number
*************************************************/
int vmm_sqlite_unique_id_dpi(const char* dbname)
{
struct stat st;
if (stat(dbname, &st)) return 0;
return st.st_size;
}
/*************************************************
* Dynamical loading of SQLITE shared library
* Return VMM_SQL_PASS on success
*************************************************/
vmm_sqlite_status_e vmm_sqlite_dynload_sqlib()
{
const char *lib_err_msg;
const char *sqlite3_libname = "libsqlite3.so";
char *sqlite3_home_path;
char sqlite3_lib[300];
vmm_sqlite_status_e errint;
#if VMM_SQL_DEBUG
printf("***** SQLITE3_HOME: %s *****\n", getenv("SQLITE3_HOME"));
printf("***** LD_LIBRARY_PATH: %s *****\n", getenv("LD_LIBRARY_PATH"));
#endif /* VMM_SQL_DEBUG */
#if VMM_SQL_DYNLOAD
/* Check if SQLITE3_HOME is defined, if so, load from "SQLITE3_HOME/bin/.." */
if (sqlite3_home_path = getenv("SQLITE3_HOME"))
{
sprintf(sqlite3_lib, "%s/bin/%s", sqlite3_home_path, sqlite3_libname);
sqlib_handle = dlopen(sqlite3_lib, RTLD_NOW);
if (!sqlib_handle) {
sprintf(sqlite3_lib, "%s/lib/%s", sqlite3_home_path, sqlite3_libname);
sqlib_handle = dlopen(sqlite3_lib, RTLD_NOW);
if (!sqlib_handle) {
sprintf(sqlite3_lib, "%s/%s", sqlite3_home_path, sqlite3_libname);
sqlib_handle = dlopen(sqlite3_lib, RTLD_NOW);
}
}
#if VMM_SQL_DEBUG
printf("***** Library loaded from SQLITE3_HOME: %s ******", sqlite3_lib);
#endif
}
else
{
/* Attempt to load from LD_LIBRARY_PATH */
sqlib_handle = dlopen(sqlite3_libname, RTLD_NOW);
}
if (!sqlib_handle)
{
#if VMM_SQL_DEBUG
fprintf(stderr, "Error during dlopen(): %s\n", dlerror());
#endif /* VMM_SQL_DEBUG */
sprintf(vmm_sqlite_err_str,
"*VMM_SQL_ERROR* during dlopen(): %s\n",
dlerror());
return(VMM_SQL_FAIL);
}
/* get all the pointers required from sqlite3 library */
errint = vmm_sqlite_dynload_get_function((void **) &sqlite3_open_p, "sqlite3_open");
errint = vmm_sqlite_dynload_get_function((void **) &sqlite3_close_p, "sqlite3_close");
errint = vmm_sqlite_dynload_get_function((void **) &sqlite3_free_p, "sqlite3_free");
errint = vmm_sqlite_dynload_get_function((void **) &sqlite3_exec_p, "sqlite3_exec");
errint = vmm_sqlite_dynload_get_function((void **) &sqlite3_errmsg_p, "sqlite3_errmsg");
errint = vmm_sqlite_dynload_get_function((void **) &sqlite3_complete_p, "sqlite3_complete");
#else
/* Static linking: just point to the actual functions.. */
sqlite3_open_p = sqlite3_open;
sqlite3_close_p = sqlite3_close;
sqlite3_free_p = sqlite3_free;
sqlite3_exec_p = sqlite3_exec;
sqlite3_errmsg_p = sqlite3_errmsg;
sqlite3_complete_p = sqlite3_complete;
errint = VMM_SQL_PASS;
#endif /* VMM_SQL_DYNLOAD */
return (errint);
}
/*************************************************
* get function pointer from library
* Return VMM_SQL_PASS on success
*************************************************/
vmm_sqlite_status_e vmm_sqlite_dynload_get_function(void **p, const char* fn)
{
const char *lib_err_msg;
*p = dlsym(sqlib_handle, fn);
lib_err_msg = dlerror();
if (lib_err_msg)
{
#if VMM_SQL_DEBUG
fprintf(stderr, "*ERROR* %s\n", lib_err_msg);
#endif /* VMM_SQL_DEBUG */
sprintf(vmm_sqlite_err_str, "*VMM_SQL_ERROR* %s\n", lib_err_msg);
return(VMM_SQL_FAIL);
}
return(VMM_SQL_PASS);
}
/*************************************************
* execute without callbacks
* Return VMM_SQL_PASS on success
*************************************************/
vmm_sqlite_status_e vmm_sqlite_execute(sqlite3 *db, const char *stmt)
{
char *errmsg;
if((db == NULL) ||
((*sqlite3_exec_p)(
db,
stmt,
NULL,
NULL,
&errmsg) != SQLITE_OK)
)
{
#if VMM_SQL_DEBUG
fprintf(stderr, "STMT: %s\n", stmt);
fprintf(stderr, " *FATAL* %s\n", errmsg);
#endif /* VMM_SQL_DEBUG */
sprintf(vmm_sqlite_err_str, "*VMM_SQL_ERROR* %s\n", errmsg);
(*sqlite3_free_p)(errmsg);
return(VMM_SQL_FAIL);
}
return(VMM_SQL_PASS);
}
/*************************************************
* add entry to dblist
* Return VMM_SQL_PASS on success
*************************************************/
vmm_sqlite_status_e vmm_sqlite_add_db(const char *name)
{
vmm_sqlite_db_entry_t *entry;
sqlite3 *db;
if ((*sqlite3_open_p)(name, &db) != SQLITE_OK)
{
#if VMM_SQL_DEBUG
fprintf(stderr, "*FATAL* Failed to open %s\n", name);
#endif /* VMM_SQL_DEBUG */
sprintf(vmm_sqlite_err_str, "Failed to open SQLITE db: %s", name);
return(VMM_SQL_FAIL);
}
/* create and add entry at the head of the dblist */
entry = (vmm_sqlite_db_entry_t *) malloc(sizeof(vmm_sqlite_db_entry_t));
entry->db = db;
entry->name = strdup(name);
entry->next = vmm_sqlite_db_q.entry;
vmm_sqlite_db_q.entry = entry;
return(VMM_SQL_PASS);
}
/*************************************************
* lookup and return a db pointer from db list
* NULL if does not exist
*************************************************/
sqlite3* vmm_sqlite_get_db(const char *name)
{
vmm_sqlite_db_entry_t *entry;
for (entry = vmm_sqlite_db_q.entry; entry != NULL; entry = entry->next)
{
if (strcmp(name, entry->name) == 0)
{
return (entry->db);
}
}
return (NULL);
}
/*************************************************
* delete entry in dblist
*************************************************/
void vmm_sqlite_delete_db(const char *name)
{
vmm_sqlite_db_entry_t *entry, *last_entry;
last_entry = vmm_sqlite_db_q.entry;
for (entry = vmm_sqlite_db_q.entry; entry != NULL; entry = entry->next)
{
if (strcmp(name, entry->name) == 0)
{
last_entry->next = entry->next;
(*sqlite3_close_p)(entry->db);
free(entry->name);
free(entry);
return;
}
last_entry = entry;
}
return;
}
/*************************************************
* File exists ? Return 1.
*************************************************/
int vmm_sqlite_file_exists(const char *filename)
{
if( access (filename, F_OK) == 0)
{
return 1;
}
return 0;
}