Browse Source

Actually create a database

master
Peter J. Jones 8 years ago
parent
commit
c766a045db

+ 11
- 2
Rakefile View File

@@ -16,8 +16,8 @@ DEPEND_MF = 'source/depend.mf'

################################################################################
CXX = 'g++'
CXXFLAGS = '-Wall -Iinclude'
LINKLIBS = LIBORGFU_A
CXXFLAGS = '-Wall -Iinclude -Idepend'
LINKLIBS = "-lcrypto #{LIBORGFU_A} depend/sqlcipher/.libs/libsqlite3.a"

################################################################################
rule('.o' => '.cxx') do |t|
@@ -36,11 +36,20 @@ TEST_EXECS.each do |t|
end
end

################################################################################
def unlink_test_db
test_file = 'test/test.db'
File.unlink(test_file) if File.exist?(test_file)
end

################################################################################
task(:test => TEST_EXECS) do
TEST_EXECS.each do |test|
unlink_test_db
sh(test)
end
unlink_test_db
end

################################################################################

+ 33
- 4
include/orgfu/config.h View File

@@ -37,6 +37,9 @@
#ifndef _orgfu_config_h_
#define _orgfu_config_h_

#include <orgfu/errors.h>
#include <string>

//! The OrgFu namespace
namespace OrgFu {
@@ -47,16 +50,19 @@ namespace OrgFu {
//==========================================================================
class Config {
public:
//========================================================================
typedef const char* (*password_callback_type) (void);
typedef void (*database_error_callback_type) (database_error_type);

//========================================================================
/*!
* The constructor.
*
* @param database_filename The name of the file for the database.
*/
//========================================================================
Config (void);
explicit Config (const char *database_filename);

//========================================================================
/*!
@@ -67,6 +73,20 @@ namespace OrgFu {
*/
//========================================================================
void set_password_callback (password_callback_type callback);
//========================================================================
/*!
* Sets the callback to use when there are database errors.
*/
//========================================================================
void set_database_error_callback (database_error_callback_type callback);
//========================================================================
/*!
* Get the file name for the database.
*/
//========================================================================
const std::string& get_database_filename (void) const;

//========================================================================
/*!
@@ -75,10 +95,19 @@ namespace OrgFu {
* @return The password.
*/
//========================================================================
const char* get_password (void);
const char* get_password (void) const;
//========================================================================
/*!
* Report an database error.
*/
//========================================================================
void send_database_error (database_error_type error) const;

private:
password_callback_type password_callback_;
std::string database_filename_;
password_callback_type password_callback_;
database_error_callback_type database_callback_;
};
}


+ 81
- 0
include/orgfu/database.h View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2011 pmade inc. (Peter Jones <pjones@pmade.com>)
* All Rights Reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of the Author nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

/*! @file
* This file contains the OrgFu::Database class.
*/

#ifndef _orgfu_database_h_
#define _orgfu_database_h_

#include <orgfu/config.h>

// Forward declarations
struct sqlite3;

//! The OrgFu namespace
namespace OrgFu {

class Database {
public:
//========================================================================
/*!
* The constructor.
*/
//========================================================================
explicit Database (const Config &config);
//========================================================================
/*!
* dtor.
*/
//========================================================================
~Database (void);
//========================================================================
/*!
* Open the connection to the database, creating the database if
* necessary. Returns true if the database was opened. Usually
* if the database can't be opened it's because the password given
* was incorrect. Prompt the user then call open again.
*/
//========================================================================
bool open (void);
private:
const Config &config_;
sqlite3 *db_;
};
}

#endif

+ 55
- 0
include/orgfu/errors.h View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2011 pmade inc. (Peter Jones <pjones@pmade.com>)
* All Rights Reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of the Author nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

/*! @file
* This file contains the classes/enums for OrgFu errors.
*/

#ifndef _orgfu_errors_h_
#define _orgfu_errors_h_

//! The OrgFu namespace
namespace OrgFu {

//========================================================================
/*!
* Database errors that can be reported to the callback given to the
* OrgFu::Config class.
*/
//==========================================================================
enum database_error_type {
database_error_open_failed,
database_error_password_failed
};
}

#endif

+ 4
- 0
include/orgfu/orgfu.h View File

@@ -31,4 +31,8 @@
*/
#ifndef _orgfu_h_
#define _orgfu_h_

#include <orgfu/config.h>
#include <orgfu/database.h>

#endif

+ 3
- 5
script/depend.rb View File

@@ -117,20 +117,18 @@ class Command
##############################################################################
def compile_sqlcipher
libcrypto = `find / -name libcrypto.a -type f 2> /dev/null`.split(/\n/).first
raise("missing libcrypto.a, install OpenSSL") if libcrypto.nil?
if File.exist?('Makefile')
system('make', 'distclean')
%w(Makefile.orig config.h).each {|f| File.unlink(f) if File.exist?(f)}
end

configure = ['sh', 'configure']
configure << '--enable-static'
configure << '--disable-shared'
configure << '--enable-tempstore=yes'
configure << '--enable-threadsafe' # FIXME: do we really want this?
configure << '--disable-amalgamation'
configure << '--disable-readline'
configure << '--disable-threadsafe'
configure << 'CFLAGS=-DSQLITE_HAS_CODEC -DSQLITE_TEMP_STORE=2'

$stdout.puts(configure.join(' ')) if options.verbose
@@ -139,7 +137,7 @@ class Command
# Have to hack the Makefile :(
system('sed -i.orig -e \'s/^TLIBS *= */TLIBS ?= /\' Makefile')
system('make', 'libsqlite3.la') || raise("make failed")
system('make', "TLIBS=#{libcrypto} -ldl -lpthread")
system('make', "TLIBS=-lcrypto -ldl")
end
end


+ 18
- 3
source/config.cxx View File

@@ -32,8 +32,8 @@
#include "orgfu/config.h"

//============================================================================
OrgFu::Config::Config (void)
: password_callback_(0)
OrgFu::Config::Config (const char *database_filename)
: database_filename_(database_filename), password_callback_(0)
{ }

//============================================================================
@@ -42,6 +42,21 @@ void OrgFu::Config::set_password_callback (password_callback_type callback) {
}

//============================================================================
const char* OrgFu::Config::get_password (void) {
void OrgFu::Config::set_database_error_callback (database_error_callback_type callback) {
database_callback_ = callback;
}

//============================================================================
const std::string& OrgFu::Config::get_database_filename (void) const {
return database_filename_;
}

//============================================================================
const char* OrgFu::Config::get_password (void) const {
return password_callback_ ? password_callback_() : 0;
}

//============================================================================
void OrgFu::Config::send_database_error (database_error_type error) const {
if (database_callback_) database_callback_(error);
}

+ 73
- 0
source/database.cxx View File

@@ -0,0 +1,73 @@
/*
* Copyright (C) 2011 pmade inc. (Peter Jones <pjones@pmade.com>)
* All Rights Reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of the Author nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

//============================================================================
#include "orgfu/database.h"
#include "orgfu/errors.h"
#include <cstring>

//============================================================================
#define SQLITE_HAS_CODEC
#define SQLITE_TEMP_STORE 2
#include <sqlcipher/sqlite3.h>

//============================================================================
OrgFu::Database::Database (const Config &config)
: config_(config), db_(0)
{ }

//============================================================================
OrgFu::Database::~Database (void) {
if (db_) sqlite3_close(db_);
}

//============================================================================
bool OrgFu::Database::open (void) {
const char *password = config_.get_password();
if (password == 0) return false;
int rc = sqlite3_open(config_.get_database_filename().c_str(), &db_);
if (db_ == 0 || rc != SQLITE_OK) {
sqlite3_close(db_);
config_.send_database_error(database_error_open_failed);
return false;
}
if ( (rc = sqlite3_key(db_, password, std::strlen(password))) != SQLITE_OK) {
sqlite3_close(db_);
config_.send_database_error(database_error_password_failed);
return false;
}

return true;
}

+ 11
- 0
test/assertions.h View File

@@ -0,0 +1,11 @@
#ifndef _orgfu_test_assertions_h_
#define _orgfu_test_assertions_h_

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

// Assert that a file exists. Pass in a char*.
#define assert_file_exists(f) {struct stat b; assert(stat(f, &b) == 0);}

#endif

+ 4
- 4
test/test_config.cxx View File

@@ -1,4 +1,4 @@
#include <orgfu/config.h>
#include <orgfu/orgfu.h>
#include <cassert>
#include <string>

@@ -9,8 +9,8 @@ const char* password_foobar (void) {

//============================================================================
int main (void) {
OrgFu::Config cfg;
OrgFu::Config cfg("test/test.db");
assert(cfg.get_database_filename() == "test/test.db");
assert(cfg.get_password() == 0);

cfg.set_password_callback(password_foobar);
@@ -18,6 +18,6 @@ int main (void) {

std::string pass(cfg.get_password());
assert(pass == "foobar");
return 0;
}

+ 20
- 0
test/test_database.cxx View File

@@ -0,0 +1,20 @@
#include <orgfu/orgfu.h>
#include <cassert>
#include "assertions.h"

//============================================================================
const char* password_foobar (void) {
return "foobar";
}

//============================================================================
int main (void) {
OrgFu::Config cfg("test/test.db");
cfg.set_password_callback(password_foobar);
OrgFu::Database db(cfg);
assert(db.open() == true);
assert_file_exists(cfg.get_database_filename().c_str());
return 0;
}

Loading…
Cancel
Save