2016-12-18 15:50:56 +00:00
/* $Id$ */
/*
* Copyright ( c ) 2016 Kristaps Dzonsons < kristaps @ bsd . lv >
*
* Permission to use , copy , modify , and distribute this software for any
* purpose with or without fee is hereby granted , provided that the above
* copyright notice and this permission notice appear in all copies .
*
* THE SOFTWARE IS PROVIDED " AS IS " AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS . IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL , DIRECT , INDIRECT , OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE , DATA OR PROFITS , WHETHER IN AN
* ACTION OF CONTRACT , NEGLIGENCE OR OTHER TORTIOUS ACTION , ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE .
*/
# include <stdarg.h>
# include <stdint.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <time.h>
# include <unistd.h>
# include <kcgi.h>
# include <kcgijson.h>
2016-12-29 19:41:31 +00:00
# include "ksql.h"
2016-12-18 15:50:56 +00:00
# include "extern.h"
2016-12-29 20:02:58 +00:00
enum stmt {
2016-12-30 09:10:55 +00:00
STMT_BOOK ,
STMT_BOOKS ,
STMT__MAX
2016-12-29 20:02:58 +00:00
} ;
static const char * const stmts [ STMT__MAX ] = {
/* STMT_BOOK */
2016-12-30 09:10:55 +00:00
" SELECT books.id AS id,title,series_index,name as series_name,series.id AS series_id FROM books LEFT OUTER JOIN books_series_link ON books.id = books_series_link.book LEFT OUTER JOIN series ON series.id = books_series_link.series WHERE books.id = ? " ,
2016-12-29 23:38:31 +00:00
/* STMT_BOOKS */
2016-12-30 10:19:23 +00:00
" SELECT books.id AS id,title,series_index,name as series_name,series.id AS series_id FROM books LEFT OUTER JOIN books_series_link ON books.id = books_series_link.book LEFT OUTER JOIN series ON series.id = books_series_link.series LIMIT ? " ,
2016-12-29 20:02:58 +00:00
} ;
2016-12-30 10:19:23 +00:00
static void
db_series_unfill ( Series * p )
{
if ( NULL = = p )
return ;
free ( p - > name ) ;
}
2016-12-29 23:45:20 +00:00
void
2016-12-30 10:19:23 +00:00
db_series_free ( Series * p )
2016-12-29 23:45:20 +00:00
{
2016-12-30 10:19:23 +00:00
db_series_unfill ( p ) ;
free ( p ) ;
}
static void
db_book_unfill ( Book * p )
{
if ( NULL = = p )
2016-12-29 23:45:20 +00:00
return ;
2016-12-30 10:19:23 +00:00
free ( p - > title ) ;
db_series_unfill ( & p - > s ) ;
}
void
db_book_free ( Book * p )
{
db_book_unfill ( p ) ;
free ( p ) ;
}
void
db_book_adv_free ( BookAdv * p )
{
db_book_unfill ( & p - > b ) ;
//TODO free authors
free ( p ) ;
2016-12-29 23:45:20 +00:00
}
2016-12-29 23:38:31 +00:00
int
2016-12-30 10:19:23 +00:00
db_books_load ( struct kreq * r , BookAdv * * books , int limit )
2016-12-29 23:38:31 +00:00
{
if ( limit < 0 ) {
return 0 ;
}
struct ksqlstmt * stmt ;
int i = 0 ;
ksql_stmt_alloc ( r - > arg , & stmt ,
stmts [ STMT_BOOKS ] ,
STMT_BOOKS ) ;
ksql_bind_int ( stmt , 0 , limit ) ;
while ( KSQL_ROW = = ksql_stmt_step ( stmt ) ) {
2016-12-30 10:19:23 +00:00
books [ i ] = kcalloc ( 1 , sizeof ( BookAdv ) ) ;
books [ i ] - > b . id = ksql_stmt_int ( stmt , 0 ) ;
books [ i ] - > b . title = kstrdup ( ksql_stmt_str ( stmt , 1 ) ) ;
if ( ksql_stmt_isnull ( stmt , 4 ) ) {
books [ i ] - > b . s . id = - 1 ;
} else {
2016-12-30 10:26:26 +00:00
books [ i ] - > b . s_idx = ksql_stmt_double ( stmt , 2 ) ;
2016-12-30 10:19:23 +00:00
books [ i ] - > b . s . name = kstrdup ( ksql_stmt_str ( stmt , 3 ) ) ;
books [ i ] - > b . s . id = ksql_stmt_int ( stmt , 4 ) ;
}
2016-12-29 23:38:31 +00:00
i + + ;
}
ksql_stmt_free ( stmt ) ;
return i ;
}
2016-12-30 09:10:55 +00:00
Book *
2016-12-29 20:02:58 +00:00
db_book_load ( struct kreq * r , int64_t id )
{
struct ksqlstmt * stmt ;
2016-12-30 09:10:55 +00:00
Book * book ;
2016-12-30 09:15:14 +00:00
2016-12-29 20:02:58 +00:00
ksql_stmt_alloc ( r - > arg , & stmt ,
stmts [ STMT_BOOK ] ,
STMT_BOOK ) ;
ksql_bind_int ( stmt , 0 , id ) ;
if ( KSQL_ROW ! = ksql_stmt_step ( stmt ) ) {
ksql_stmt_free ( stmt ) ;
return ( NULL ) ;
}
2016-12-30 09:10:55 +00:00
book = kcalloc ( 1 , sizeof ( Book ) ) ;
2016-12-29 23:38:31 +00:00
book - > id = ksql_stmt_int ( stmt , 0 ) ;
book - > title = kstrdup ( ksql_stmt_str ( stmt , 1 ) ) ;
2016-12-30 10:19:23 +00:00
if ( ksql_stmt_isnull ( stmt , 4 ) ) {
book - > s . id = - 1 ;
} else {
2016-12-30 10:26:26 +00:00
book - > s_idx = ksql_stmt_double ( stmt , 2 ) ;
2016-12-30 10:19:23 +00:00
book - > s . name = kstrdup ( ksql_stmt_str ( stmt , 3 ) ) ;
book - > s . id = ksql_stmt_int ( stmt , 4 ) ;
}
2016-12-29 20:02:58 +00:00
ksql_stmt_free ( stmt ) ;
return book ;
}
2016-12-18 15:50:56 +00:00
/*
2016-12-29 19:41:31 +00:00
* Open the database and stash the resulting handle in the d
2016-12-18 15:50:56 +00:00
*/
int
db_open ( struct kreq * r , const char * file )
{
2016-12-29 19:41:31 +00:00
struct ksqlcfg cfg ;
struct ksql * sql ;
2016-12-18 15:50:56 +00:00
2016-12-29 19:41:31 +00:00
/* Configure normal database except with foreign keys. */
memset ( & cfg , 0 , sizeof ( struct ksqlcfg ) ) ;
cfg . flags = KSQL_EXIT_ON_ERR |
KSQL_FOREIGN_KEYS |
KSQL_SAFE_EXIT ;
cfg . err = ksqlitemsg ;
cfg . dberr = ksqlitedbmsg ;
/* Allocate database. */
if ( NULL = = ( sql = ksql_alloc ( & cfg ) ) )
return ( 0 ) ;
ksql_open ( sql , file ) ;
r - > arg = sql ;
return ( 1 ) ;
2016-12-18 15:50:56 +00:00
}
/*
* Close the database stashed in the kreq ' s argument .
*/
void
db_close ( struct kreq * r )
{
2016-12-29 19:41:31 +00:00
ksql_free ( r - > arg ) ;
r - > arg = NULL ;
2016-12-18 15:50:56 +00:00
}