Skip to content

Commit

Permalink
metadb: Add support for schema upgrades
Browse files Browse the repository at this point in the history
  • Loading branch information
andoma committed Sep 18, 2011
1 parent 7fab3ac commit aa2dad4
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 64 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ endif

SRCS-${CONFIG_EMU_THREAD_SPECIFICS} += src/arch/emu_thread_specifics.c

BUNDLES += resources/metadb

#
# Misc support
#
Expand Down
42 changes: 1 addition & 41 deletions metadb/001.sql → resources/metadb/001.sql
Original file line number Diff line number Diff line change
@@ -1,18 +1,3 @@

PRAGMA foreign_keys = ON;

BEGIN;

DROP TABLE itemtype;
DROP TABLE item;
DROP TABLE stream;
DROP TABLE audioitem;
DROP TABLE videoitem;
DROP TABLE artist;
DROP TABLE album;

DROP INDEX item_url_idx;

CREATE TABLE itemtype (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
Expand Down Expand Up @@ -83,30 +68,5 @@ CREATE TABLE stream (
codec TEXT,
mediatype TEXT
);
CREATE INDEX stream_item_id_idx ON stream(item_id);


COMMIT;




INSERT INTO item (url) values ('foo');

BEGIN;
INSERT OR IGNORE INTO item(url, contenttype, playcount) VALUES('bar3', 5,1);
UPDATE item SET playcount = playcount + (1 - changes()) WHERE url = 'bar3';
COMMIT;


INSERT INTO item(url, contenttype) VALUES('video', 5);
INSERT INTO item(url, contenttype) VALUES('audio', 4);

INSERT INTO videoitem values (1, 1337);

INSERT INTO audioitem values (2, 1, 1);

insert into album (title) values ('dark side of the moon');
insert into artist (title) values ('pink floyd');


CREATE INDEX stream_item_id_idx ON stream(item_id);
3 changes: 3 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,9 @@ main(int argc, char **argv)
/* Initialize htsmsg_store() */
htsmsg_store_init();

/* Metadata init */
metadb_init();

/* Initialize keyring */
keyring_init();

Expand Down
194 changes: 171 additions & 23 deletions src/metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
#include "api/lastfm.h"

#include "metadata.h"
#include "fileaccess/fileaccess.h"

// If not set to true by metadb_init() no metadb actions will occur
static int metadb_valid;

/**
*
Expand Down Expand Up @@ -213,10 +217,167 @@ one_statement(sqlite3 *db, const char *sql)
}


/**
*
*/
static int
db_get_int_from_query(sqlite3 *db, const char *query, int *v)
{
int rc;
int64_t rval = -1;
sqlite3_stmt *stmt;

rc = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
if(rc)
return -1;

rc = sqlite3_step(stmt);

if(rc == SQLITE_ROW) {
*v = sqlite3_column_int(stmt, 0);
rval = 0;
} else {
rval = -1;
}

sqlite3_finalize(stmt);
return rval;
}



static int
begin(sqlite3 *db)
{
return one_statement(db, "BEGIN;");
}


static int
commit(sqlite3 *db)
{
return one_statement(db, "COMMIT;");
}


static int
rollback(sqlite3 *db)
{
return one_statement(db, "ROLLBACK;");
}


#define METADB_SCHEMA_DIR "bundle:https://resources/metadb"

/**
*
*/
static void
metadb_upgrade(sqlite3 *db)
{
int ver, tgtver = 0;
char path[256];
char buf[256];
if(db_get_int_from_query(db, "pragma user_version", &ver)) {
TRACE(TRACE_ERROR, "METADB", "Unable to query db version");
return;
}

fa_dir_t *fd;
fa_dir_entry_t *fde;

fd = fa_scandir(METADB_SCHEMA_DIR, buf, sizeof(buf));

if(fd == NULL) {
TRACE(TRACE_ERROR, "METADB",
"Unable to scan schema dir %s -- %s", METADB_SCHEMA_DIR , buf);
return;
}

TAILQ_FOREACH(fde, &fd->fd_entries, fde_link) {
if(fde->fde_type != CONTENT_FILE || strchr(fde->fde_filename, '~'))
continue;
tgtver = MAX(tgtver, atoi(fde->fde_filename));
}

fa_dir_free(fd);

while(1) {

if(ver == tgtver) {
TRACE(TRACE_DEBUG, "METADB", "At current version %d", ver);
metadb_valid = 1;
return;
}

ver++;
snprintf(path, sizeof(path), METADB_SCHEMA_DIR"/%03d.sql", ver);

struct fa_stat fs;
char *sql = fa_quickload(path, &fs, NULL, buf, sizeof(buf));
if(sql == NULL) {
TRACE(TRACE_ERROR, "METADB",
"Unable to upgrade db schema to version %d using %s -- %s",
ver, path, buf);
return;
}

begin(db);
snprintf(buf, sizeof(buf), "PRAGMA user_version=%d", ver);
if(one_statement(db, buf)) {
free(sql);
break;
}

const char *s = sql;

while(strchr(s, ';') != NULL) {
sqlite3_stmt *stmt;

int rc = sqlite3_prepare_v2(db, s, -1, &stmt, &s);
if(rc != SQLITE_OK) {
TRACE(TRACE_ERROR, "METADB",
"Unable to prepare statement in upgrade %d\n%s", ver, s);
goto fail;
}

rc = sqlite3_step(stmt);
if(rc != SQLITE_DONE) {
TRACE(TRACE_ERROR, "METADB",
"Unable to execute statement error %d\n%s", rc,
sqlite3_sql(stmt));
goto fail;
}
sqlite3_finalize(stmt);
}

commit(db);
TRACE(TRACE_INFO, "METADB", "Upgraded to version %d", ver);
free(sql);
}
fail:
rollback(db);
}


/**
*
*/
void
metadb_init(void)
{
sqlite3 *db;

db = metadb_get();
metadb_upgrade(db);
metadb_close(db);
}



/**
*
*/
void *
metadb_get(void)
{
Expand All @@ -236,8 +397,6 @@ metadb_get(void)
return NULL;
}

sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, 1, NULL);

rc = sqlite3_exec(db, "PRAGMA synchronous = normal;", NULL, NULL, &errmsg);
if(rc) {
TRACE(TRACE_ERROR,
Expand Down Expand Up @@ -267,6 +426,9 @@ metadb_playcount_incr(void *db, const char *url)
int rc;
sqlite3_stmt *stmt;

if(!metadb_valid)
return;

rc = sqlite3_prepare_v2(db,
"UPDATE item SET playcount=playcount+1 WHERE URL=?1;",
-1, &stmt, NULL);
Expand All @@ -283,26 +445,6 @@ metadb_playcount_incr(void *db, const char *url)



static int
begin(sqlite3 *db)
{
return one_statement(db, "BEGIN;");
}


static int
commit(sqlite3 *db)
{
return one_statement(db, "COMMIT;");
}


static int
rollback(sqlite3 *db)
{
return one_statement(db, "ROLLBACK;");
}


/**
*
Expand Down Expand Up @@ -682,6 +824,9 @@ metadb_metadata_write(void *db, const char *url, time_t mtime,
int rc;
sqlite3_stmt *stmt;

if(!metadb_valid)
return;

if(begin(db))
return;

Expand Down Expand Up @@ -866,14 +1011,17 @@ metadb_metadata_get_streams(sqlite3 *db, metadata_t *md, int64_t item_id)


/**
* Perhaps this should be merged into one SELECT
*
*/
metadata_t *
metadb_metadata_get(void *db, const char *url, time_t mtime)
{
int rc;
sqlite3_stmt *sel;

if(!metadb_valid)
return NULL;

if(begin(db))
return NULL;

Expand Down
2 changes: 2 additions & 0 deletions src/metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ void metadata_to_proptree(const metadata_t *md, struct prop *proproot,



void metadb_init(void);

void *metadb_get(void);

void metadb_close(void *db);
Expand Down

0 comments on commit aa2dad4

Please sign in to comment.