/* $Id$ */ /* * Copyright (c) 2016 Kristaps Dzonsons * * 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 #include #include #include #include #include #include #include #include #include "ksql.h" #include "extern.h" enum stmt { STMT_BOOK, STMT_BOOKS, STMT__MAX }; static const char *const stmts[STMT__MAX] = { /* STMT_BOOK */ "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 = ?", /* STMT_BOOKS */ "SELECT books.id AS id,title FROM books LIMIT ?", }; void db_book_free(Book *b) { if (NULL == b) return; free(b->title); //TODO free series free(b->s.name); free(b); } int db_books_load(struct kreq *r, Book **books, int limit) { 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)) { books[i] = kcalloc(1, sizeof(Book)); books[i]->id = ksql_stmt_int(stmt, 0); books[i]->title = kstrdup(ksql_stmt_str(stmt, 1)); i++; } ksql_stmt_free(stmt); return i; } Book * db_book_load(struct kreq *r, int64_t id) { struct ksqlstmt *stmt; Book *book; 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); } book = kcalloc(1, sizeof(Book)); book->id = ksql_stmt_int(stmt, 0); book->title = kstrdup(ksql_stmt_str(stmt, 1)); book->s_idx = ksql_stmt_int(stmt, 2); book->s.name = kstrdup(ksql_stmt_str(stmt, 3)); book->s.id = ksql_stmt_int(stmt, 4); ksql_stmt_free(stmt); return book; } /* * Open the database and stash the resulting handle in the d */ int db_open(struct kreq *r, const char *file) { struct ksqlcfg cfg; struct ksql *sql; /* 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); } /* * Close the database stashed in the kreq's argument. */ void db_close(struct kreq *r) { ksql_free(r->arg); r->arg = NULL; }