From ba5f38bc6d3de97092dc7966d7fc13dc655dd243 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 15 Oct 2009 10:28:03 +0200 Subject: [PATCH] Add IMDb SQLite storage class --- src/imdb/imdb-sqlite.vala | 157 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 src/imdb/imdb-sqlite.vala diff --git a/src/imdb/imdb-sqlite.vala b/src/imdb/imdb-sqlite.vala new file mode 100644 index 0000000..c8e6cbc --- /dev/null +++ b/src/imdb/imdb-sqlite.vala @@ -0,0 +1,157 @@ +/* This file is part of Cinaest. + * + * Copyright (C) 2009 Philipp Zabel + * + * Cinaest is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Cinaest 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 Cinaest. If not, see . + */ + +using Sqlite; + +class IMDbSqlite : Object { + Database db; + List genres; + + public IMDbSqlite (string filename) { + int rc; + + genres = new List (); + + rc = Database.open (filename, out db); + if (rc != Sqlite.OK) { + stderr.printf ("Can't open database: %d, %s\n", rc, db.errmsg ()); + return; + } + + rc = db.exec ("PRAGMA journal_mode = OFF;", callback, null); + if (rc != Sqlite.OK) { + stderr.printf ("Can't turn off journal mode: %d, %s\n", rc, db.errmsg ()); + return; + } + + rc = db.exec ("PRAGMA locking_mode = EXCLUSIVE;", callback, null); + if (rc != Sqlite.OK) { + stderr.printf ("Can't get exclusive lock: %d, %s\n", rc, db.errmsg ()); + return; + } + + rc = db.exec ("PRAGMA synchronous = OFF;", callback, null); + if (rc != Sqlite.OK) + stderr.printf ("Can't turn off synchronous access: %d, %s\n", rc, db.errmsg ()); + + } + + public static int callback (int n_columns, string[] values, + string[] column_names) { + for (int i = 0; i < n_columns; i++) { + stdout.printf ("%s = %s\n", column_names[i], values[i]); + } + stdout.printf ("\n"); + + return 0; + } + + public int add_movie (string _title, int year) { + string md5 = Checksum.compute_for_string (ChecksumType.MD5, _title); + uint64 half_md5 = (md5.ndup (16)).to_uint64 (null, 16); + + string title = strip_year (_title, year); + + string sql = "INSERT INTO Movies(ID, Title, Year) VALUES (%lld, \"%s\", %d);".printf ((int64) half_md5, title, year); + int rc; + + rc = db.exec (sql, callback, null); + if (rc != Sqlite.OK) { + stderr.printf ("Failed to insert movie \"%s\" (%d): %d, %s\n", title, year, rc, db.errmsg ()); + return 1; + } + + return 0; + } + + private string strip_year (string title, int year) { + string year_suffix = " (%d)".printf (year); + if (title.has_suffix (year_suffix)) { + return title.substring (0, title.length - year_suffix.length); + } else { + return title.dup (); + } + } + + public int movie_set_rating (string title, int rating) { + string md5 = Checksum.compute_for_string (ChecksumType.MD5, title); + uint64 half_md5 = (md5.ndup (16)).to_uint64 (null, 16); + + var sql = "UPDATE Movies SET Rating=%d WHERE ID=%lld;".printf (rating, (int64) half_md5); + int rc; + + rc = db.exec (sql, callback, null); + if (rc != Sqlite.OK) { + stderr.printf ("SQL error: %d, %s\n", rc, db.errmsg ()); + return 1; + } + + return 0; + } + + public int movie_add_genre (string title, string genre) { + string md5 = Checksum.compute_for_string (ChecksumType.MD5, title); + uint64 half_md5 = (md5.ndup (16)).to_uint64 (null, 16); + string sql; + int bit; + int rc; + + bit = genre_bit (genre); + if (bit == 0) { + genres.append (genre); + bit = genre_bit (genre); + + sql = "INSERT INTO Genres(Bit, Genre) VALUES (%d, \"%s\");".printf (bit, genre); + + rc = db.exec (sql, callback, null); + if (rc != Sqlite.OK) { + stderr.printf ("SQL error: %d, %s\n", rc, db.errmsg ()); + return 1; + } + } + + sql = "UPDATE Movies SET Genres=Genres|%d WHERE ID=%lld;".printf (bit, (int64) half_md5); + rc = db.exec (sql, callback, null); + if (rc != Sqlite.OK) { + stderr.printf ("SQL error: %d, %s\n", rc, db.errmsg ()); + return 1; + } + + return 0; + } + + int genre_bit (string genre) { + for (int i = 0; i < genres.length (); i++) { + if (genres.nth_data (i) == genre) + return 1 << i; + } + return 0; + } + + public int clear () { + int rc; + + rc = db.exec ("DROP TABLE IF EXISTS Movies; CREATE TABLE Movies (ID INTEGER PRIMARY KEY, Title TEXT NOT NULL, Year INTEGER, Rating INTEGER, Genres INTEGER NOT NULL DEFAULT 0); DROP TABLE IF EXISTS Genres; CREATE TABLE Genres (Bit INTEGER PRIMARY KEY, Genre TEXT NOT NULL);", callback, null); + if (rc != Sqlite.OK) { + stderr.printf ("SQL error: %d, %s\n", rc, db.errmsg ()); + return 1; + } + + return 0; + } +} -- 1.7.9.5