/* db-database-connection.c generated by valac 0.56.3, the Vala compiler
 * generated from db-database-connection.vala, do not modify */

/*
 * Copyright © 2016 Software Freedom Conservancy Inc.
 * Copyright © 2020 Michael Gratton <mike@vee.net>
 *
 * This software is licensed under the GNU Lesser General Public License
 * (version 2.1 or later). See the COPYING file in this distribution.
 */

#include "geary-engine.h"
#include <glib.h>
#include <sqlite3.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#include <glib/gstdio.h>
#include <glib-object.h>

enum  {
	GEARY_DB_DATABASE_CONNECTION_0_PROPERTY,
	GEARY_DB_DATABASE_CONNECTION_BUSY_TIMEOUT_PROPERTY,
	GEARY_DB_DATABASE_CONNECTION_DATABASE_PROPERTY,
	GEARY_DB_DATABASE_CONNECTION_LOGGING_PARENT_PROPERTY,
	GEARY_DB_DATABASE_CONNECTION_DB_PROPERTY,
	GEARY_DB_DATABASE_CONNECTION_NUM_PROPERTIES
};
static GParamSpec* geary_db_database_connection_properties[GEARY_DB_DATABASE_CONNECTION_NUM_PROPERTIES];
#define _sqlite3_close0(var) ((var == NULL) ? NULL : (var = (sqlite3_close (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_timer_destroy0(var) ((var == NULL) ? NULL : (var = (g_timer_destroy (var), NULL)))

#define GEARY_DB_TYPE_TRANSACTION_CONNECTION (geary_db_transaction_connection_get_type ())
#define GEARY_DB_TRANSACTION_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEARY_DB_TYPE_TRANSACTION_CONNECTION, GearyDbTransactionConnection))
#define GEARY_DB_TRANSACTION_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEARY_DB_TYPE_TRANSACTION_CONNECTION, GearyDbTransactionConnectionClass))
#define GEARY_DB_IS_TRANSACTION_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEARY_DB_TYPE_TRANSACTION_CONNECTION))
#define GEARY_DB_IS_TRANSACTION_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEARY_DB_TYPE_TRANSACTION_CONNECTION))
#define GEARY_DB_TRANSACTION_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEARY_DB_TYPE_TRANSACTION_CONNECTION, GearyDbTransactionConnectionClass))

typedef struct _GearyDbTransactionConnection GearyDbTransactionConnection;
typedef struct _GearyDbTransactionConnectionClass GearyDbTransactionConnectionClass;
typedef struct _GearyDbTransactionConnectionPrivate GearyDbTransactionConnectionPrivate;

#define GEARY_DB_TYPE_TRANSACTION_ASYNC_JOB (geary_db_transaction_async_job_get_type ())
#define GEARY_DB_TRANSACTION_ASYNC_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEARY_DB_TYPE_TRANSACTION_ASYNC_JOB, GearyDbTransactionAsyncJob))
#define GEARY_DB_TRANSACTION_ASYNC_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEARY_DB_TYPE_TRANSACTION_ASYNC_JOB, GearyDbTransactionAsyncJobClass))
#define GEARY_DB_IS_TRANSACTION_ASYNC_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEARY_DB_TYPE_TRANSACTION_ASYNC_JOB))
#define GEARY_DB_IS_TRANSACTION_ASYNC_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEARY_DB_TYPE_TRANSACTION_ASYNC_JOB))
#define GEARY_DB_TRANSACTION_ASYNC_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEARY_DB_TYPE_TRANSACTION_ASYNC_JOB, GearyDbTransactionAsyncJobClass))

typedef struct _GearyDbTransactionAsyncJob GearyDbTransactionAsyncJob;
typedef struct _GearyDbTransactionAsyncJobClass GearyDbTransactionAsyncJobClass;
typedef struct _GearyDbDatabaseConnectionExecTransactionAsyncData GearyDbDatabaseConnectionExecTransactionAsyncData;

struct _GearyDbDatabaseConnectionPrivate {
	gint _busy_timeout;
	GearyDbDatabase* _database;
	sqlite3* _db;
	guint cx_number;
};

struct _GearyDbTransactionConnection {
	GearyBaseObject parent_instance;
	gchar** transaction_log;
	gint transaction_log_length1;
	gint _transaction_log_size_;
	GearyDbTransactionConnectionPrivate * priv;
};

struct _GearyDbTransactionConnectionClass {
	GearyBaseObjectClass parent_class;
};

struct _GearyDbDatabaseConnectionExecTransactionAsyncData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	GearyDbDatabaseConnection* self;
	GearyDbTransactionType type;
	GearyDbTransactionMethod cb;
	gpointer cb_target;
	GCancellable* cancellable;
	GearyDbTransactionOutcome result;
	GearyDbTransactionAsyncJob* job;
	GearyDbTransactionAsyncJob* _tmp0_;
	GearyDbDatabase* _tmp1_;
	GearyDbDatabase* _tmp2_;
	GearyDbTransactionAsyncJob* _tmp3_;
	GearyDbTransactionOutcome _tmp4_;
	GearyDbTransactionAsyncJob* _tmp5_;
	GError* _inner_error0_;
};

static gint GearyDbDatabaseConnection_private_offset;
static gpointer geary_db_database_connection_parent_class = NULL;
static guint geary_db_database_connection_next_cx_number;
static GRecMutex __lock_geary_db_database_connection_geary_db_database_connection_next_cx_number = {0};
static guint geary_db_database_connection_next_cx_number = (guint) 0;
static GearyDbConnectionIface * geary_db_database_connection_geary_db_connection_parent_iface = NULL;

VALA_EXTERN GearyDbDatabaseConnection* geary_db_context_get_connection (GearyDbContext* self);
static void geary_db_database_connection_set_busy_timeout (GearyDbDatabaseConnection* self,
                                                    gint value);
VALA_EXTERN GearyDbDatabaseConnection* geary_db_database_connection_new (GearyDbDatabase* database,
                                                             gint sqlite_flags,
                                                             GCancellable* cancellable,
                                                             GError** error);
VALA_EXTERN GearyDbDatabaseConnection* geary_db_database_connection_construct (GType object_type,
                                                                   GearyDbDatabase* database,
                                                                   gint sqlite_flags,
                                                                   GCancellable* cancellable,
                                                                   GError** error);
VALA_EXTERN void geary_db_check_cancelled (const gchar* method,
                               GCancellable* cancellable,
                               GError** error);
VALA_EXTERN sqlite3* geary_db_connection_get_db (GearyDbConnection* self);
static GearyDbStatement* geary_db_database_connection_real_prepare (GearyDbConnection* base,
                                                             const gchar* sql,
                                                             GError** error);
VALA_EXTERN GearyDbStatement* geary_db_statement_new (GearyDbDatabaseConnection* connection,
                                          const gchar* sql,
                                          GError** error);
VALA_EXTERN GearyDbStatement* geary_db_statement_construct (GType object_type,
                                                GearyDbDatabaseConnection* connection,
                                                const gchar* sql,
                                                GError** error);
static GearyDbResult* geary_db_database_connection_real_query (GearyDbConnection* base,
                                                        const gchar* sql,
                                                        GCancellable* cancellable,
                                                        GError** error);
static void geary_db_database_connection_real_exec (GearyDbConnection* base,
                                             const gchar* sql,
                                             GCancellable* cancellable,
                                             GError** error);
static void geary_db_database_connection_real_exec_file (GearyDbConnection* base,
                                                  GFile* file,
                                                  GCancellable* cancellable,
                                                  GError** error);
VALA_EXTERN GType geary_db_transaction_connection_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GearyDbTransactionConnection* geary_db_transaction_connection_new (GearyDbDatabaseConnection* db_cx);
VALA_EXTERN GearyDbTransactionConnection* geary_db_transaction_connection_construct (GType object_type,
                                                                         GearyDbDatabaseConnection* db_cx);
static void geary_db_database_connection_exec_transaction_async_data_free (gpointer _data);
static gboolean geary_db_database_connection_exec_transaction_async_co (GearyDbDatabaseConnectionExecTransactionAsyncData* _data_);
VALA_EXTERN GType geary_db_transaction_async_job_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GearyDbTransactionAsyncJob* geary_db_transaction_async_job_new (GearyDbDatabaseConnection* default_cx,
                                                                GearyDbTransactionType type,
                                                                GearyDbTransactionMethod cb,
                                                                gpointer cb_target,
                                                                GCancellable* cancellable);
VALA_EXTERN GearyDbTransactionAsyncJob* geary_db_transaction_async_job_construct (GType object_type,
                                                                      GearyDbDatabaseConnection* default_cx,
                                                                      GearyDbTransactionType type,
                                                                      GearyDbTransactionMethod cb,
                                                                      gpointer cb_target,
                                                                      GCancellable* cancellable);
VALA_EXTERN void geary_db_database_add_async_job (GearyDbDatabase* self,
                                      GearyDbTransactionAsyncJob* new_job,
                                      GError** error);
VALA_EXTERN void geary_db_transaction_async_job_wait_for_completion_async (GearyDbTransactionAsyncJob* self,
                                                               GAsyncReadyCallback _callback_,
                                                               gpointer _user_data_);
VALA_EXTERN GearyDbTransactionOutcome geary_db_transaction_async_job_wait_for_completion_finish (GearyDbTransactionAsyncJob* self,
                                                                                     GAsyncResult* _res_,
                                                                                     GError** error);
static void geary_db_database_connection_exec_transaction_async_ready (GObject* source_object,
                                                                GAsyncResult* _res_,
                                                                gpointer _user_data_);
static GearyLoggingState* geary_db_database_connection_real_to_logging_state (GearyDbContext* base);
static GearyDbDatabaseConnection* geary_db_database_connection_real_get_connection (GearyDbContext* base);
static void geary_db_database_connection_finalize (GObject * obj);
static GType geary_db_database_connection_get_type_once (void);
static void _vala_geary_db_database_connection_get_property (GObject * object,
                                                      guint property_id,
                                                      GValue * value,
                                                      GParamSpec * pspec);
static void _vala_geary_db_database_connection_set_property (GObject * object,
                                                      guint property_id,
                                                      const GValue * value,
                                                      GParamSpec * pspec);

static inline gpointer
geary_db_database_connection_get_instance_private (GearyDbDatabaseConnection* self)
{
	return G_STRUCT_MEMBER_P (self, GearyDbDatabaseConnection_private_offset);
}

gint
geary_db_database_connection_get_busy_timeout (GearyDbDatabaseConnection* self)
{
	gint result;
	g_return_val_if_fail (GEARY_DB_IS_DATABASE_CONNECTION (self), 0);
	result = self->priv->_busy_timeout;
	return result;
}

static void
geary_db_database_connection_set_busy_timeout (GearyDbDatabaseConnection* self,
                                               gint value)
{
	gint old_value;
	g_return_if_fail (GEARY_DB_IS_DATABASE_CONNECTION (self));
	old_value = geary_db_database_connection_get_busy_timeout (self);
	if (old_value != value) {
		self->priv->_busy_timeout = value;
		g_object_notify_by_pspec ((GObject *) self, geary_db_database_connection_properties[GEARY_DB_DATABASE_CONNECTION_BUSY_TIMEOUT_PROPERTY]);
	}
}

static GearyDbDatabase*
geary_db_database_connection_real_get_database (GearyDbConnection* base)
{
	GearyDbDatabase* result;
	GearyDbDatabaseConnection* self;
	GearyDbDatabase* _tmp0_;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_DB_TYPE_DATABASE_CONNECTION, GearyDbDatabaseConnection);
	_tmp0_ = self->priv->_database;
	result = _tmp0_;
	return result;
}

static GearyLoggingSource*
geary_db_database_connection_real_get_logging_parent (GearyDbContext* base)
{
	GearyLoggingSource* result;
	GearyDbDatabaseConnection* self;
	GearyDbDatabase* _tmp0_;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_DB_TYPE_DATABASE_CONNECTION, GearyDbDatabaseConnection);
	_tmp0_ = self->priv->_database;
	result = G_TYPE_CHECK_INSTANCE_CAST (_tmp0_, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource);
	return result;
}

static sqlite3*
geary_db_database_connection_real_get_db (GearyDbConnection* base)
{
	sqlite3* result;
	GearyDbDatabaseConnection* self;
	sqlite3* _tmp0_;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_DB_TYPE_DATABASE_CONNECTION, GearyDbDatabaseConnection);
	_tmp0_ = self->priv->_db;
	result = _tmp0_;
	return result;
}

static gpointer
_g_error_copy0 (gpointer self)
{
	return self ? g_error_copy (self) : NULL;
}

GearyDbDatabaseConnection*
geary_db_database_connection_construct (GType object_type,
                                        GearyDbDatabase* database,
                                        gint sqlite_flags,
                                        GCancellable* cancellable,
                                        GError** error)
{
	GearyDbDatabaseConnection * self = NULL;
	GError* _inner_error0_ = NULL;
	g_return_val_if_fail (GEARY_DB_IS_DATABASE (database), NULL);
	g_return_val_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()), NULL);
	self = (GearyDbDatabaseConnection*) geary_db_context_construct (object_type);
	self->priv->_database = database;
	{
		g_rec_mutex_lock (&__lock_geary_db_database_connection_geary_db_database_connection_next_cx_number);
		{
			guint _tmp0_;
			_tmp0_ = geary_db_database_connection_next_cx_number;
			geary_db_database_connection_next_cx_number = _tmp0_ + 1;
			self->priv->cx_number = _tmp0_;
		}
		__finally0:
		{
			g_rec_mutex_unlock (&__lock_geary_db_database_connection_geary_db_database_connection_next_cx_number);
		}
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			g_propagate_error (error, _inner_error0_);
			_g_object_unref0 (self);
			return NULL;
		}
	}
	geary_db_check_cancelled ("Connection.ctor", cancellable, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (self);
		return NULL;
	}
	{
		const gchar* _tmp1_;
		const gchar* _tmp2_;
		sqlite3* _tmp3_ = NULL;
		gint _tmp4_;
		_tmp1_ = geary_db_database_get_path (database);
		_tmp2_ = _tmp1_;
		_tmp4_ = sqlite3_open_v2 (_tmp2_, &_tmp3_, sqlite_flags, NULL);
		_sqlite3_close0 (self->priv->_db);
		self->priv->_db = _tmp3_;
		geary_db_context_throw_on_error (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_DB_TYPE_CONTEXT, GearyDbContext), "Connection.ctor", _tmp4_, NULL, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == GEARY_DATABASE_ERROR) {
				goto __catch1_geary_database_error;
			}
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
	}
	goto __finally1;
	__catch1_geary_database_error:
	{
		GError* derr = NULL;
		gboolean _tmp5_ = FALSE;
		GError* _tmp6_;
		derr = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp6_ = derr;
		if (!g_error_matches (_tmp6_, GEARY_DATABASE_ERROR, GEARY_DATABASE_ERROR_BUSY)) {
			_tmp5_ = TRUE;
		} else {
			sqlite3* _tmp7_;
			sqlite3* _tmp8_;
			_tmp7_ = geary_db_connection_get_db (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_DB_TYPE_CONNECTION, GearyDbConnection));
			_tmp8_ = _tmp7_;
			_tmp5_ = _tmp8_ == NULL;
		}
		if (_tmp5_) {
			GError* _tmp9_;
			GError* _tmp10_;
			_tmp9_ = derr;
			_tmp10_ = _g_error_copy0 (_tmp9_);
			_inner_error0_ = _tmp10_;
			_g_error_free0 (derr);
			goto __finally1;
		}
		_g_error_free0 (derr);
	}
	__finally1:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (self);
		return NULL;
	}
	return self;
}

GearyDbDatabaseConnection*
geary_db_database_connection_new (GearyDbDatabase* database,
                                  gint sqlite_flags,
                                  GCancellable* cancellable,
                                  GError** error)
{
	return geary_db_database_connection_construct (GEARY_DB_TYPE_DATABASE_CONNECTION, database, sqlite_flags, cancellable, error);
}

/**
     * Sets the connection's busy timeout in milliseconds.
     *
     * @see busy_timeout
     */
void
geary_db_database_connection_set_busy_timeout_msec (GearyDbDatabaseConnection* self,
                                                    gint timeout_msec,
                                                    GError** error)
{
	gint _tmp0_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (GEARY_DB_IS_DATABASE_CONNECTION (self));
	_tmp0_ = self->priv->_busy_timeout;
	if (_tmp0_ != timeout_msec) {
		sqlite3* _tmp1_;
		sqlite3* _tmp2_;
		_tmp1_ = geary_db_connection_get_db (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_DB_TYPE_CONNECTION, GearyDbConnection));
		_tmp2_ = _tmp1_;
		geary_db_context_throw_on_error (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_DB_TYPE_CONTEXT, GearyDbContext), "Database.set_busy_timeout", sqlite3_busy_timeout (_tmp2_, timeout_msec), NULL, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			g_propagate_error (error, _inner_error0_);
			return;
		}
		geary_db_database_connection_set_busy_timeout (self, timeout_msec);
	}
}

/** {@inheritDoc} */
static GearyDbStatement*
geary_db_database_connection_real_prepare (GearyDbConnection* base,
                                           const gchar* sql,
                                           GError** error)
{
	GearyDbDatabaseConnection * self;
	GearyDbStatement* _tmp0_ = NULL;
	GearyDbStatement* _tmp1_;
	GearyDbStatement* _tmp2_;
	GError* _inner_error0_ = NULL;
	GearyDbStatement* result;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_DB_TYPE_DATABASE_CONNECTION, GearyDbDatabaseConnection);
	g_return_val_if_fail (sql != NULL, NULL);
	_tmp1_ = geary_db_statement_new (self, sql, &_inner_error0_);
	_tmp0_ = _tmp1_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		if (_inner_error0_->domain == GEARY_DATABASE_ERROR) {
			g_propagate_error (error, _inner_error0_);
			return NULL;
		} else {
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
	}
	_tmp2_ = _tmp0_;
	_tmp0_ = NULL;
	result = _tmp2_;
	_g_object_unref0 (_tmp0_);
	return result;
}

/** {@inheritDoc} */
static GearyDbResult*
geary_db_database_connection_real_query (GearyDbConnection* base,
                                         const gchar* sql,
                                         GCancellable* cancellable,
                                         GError** error)
{
	GearyDbDatabaseConnection * self;
	GearyDbStatement* _tmp0_ = NULL;
	GearyDbStatement* _tmp1_;
	GearyDbResult* _tmp2_ = NULL;
	GearyDbResult* _tmp3_;
	GearyDbResult* _tmp4_;
	GError* _inner_error0_ = NULL;
	GearyDbResult* result;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_DB_TYPE_DATABASE_CONNECTION, GearyDbDatabaseConnection);
	g_return_val_if_fail (sql != NULL, NULL);
	g_return_val_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()), NULL);
	_tmp1_ = geary_db_connection_prepare (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_DB_TYPE_CONNECTION, GearyDbConnection), sql, &_inner_error0_);
	_tmp0_ = _tmp1_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return NULL;
	}
	_tmp3_ = geary_db_statement_exec (_tmp0_, cancellable, &_inner_error0_);
	_tmp2_ = _tmp3_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (_tmp0_);
		return NULL;
	}
	_tmp4_ = _tmp2_;
	_tmp2_ = NULL;
	result = _tmp4_;
	_g_object_unref0 (_tmp2_);
	_g_object_unref0 (_tmp0_);
	return result;
}

/** {@inheritDoc} */
static gint
_sqlite3_exec (sqlite3* self,
               const gchar* sql,
               sqlite3_callback callback,
               gpointer callback_target,
               gchar** errmsg)
{
	gchar* _vala_errmsg = NULL;
	const gchar* sqlite_errmsg = NULL;
	gint ec = 0;
	const gchar* _tmp0_ = NULL;
	gint _tmp1_;
	const gchar* _tmp4_;
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	g_return_val_if_fail (sql != NULL, 0);
	_tmp1_ = sqlite3_exec (self, sql, callback, callback_target, (char**) (&_tmp0_));
	sqlite_errmsg = _tmp0_;
	ec = _tmp1_;
	if ((&_vala_errmsg) != NULL) {
		const gchar* _tmp2_;
		gchar* _tmp3_;
		_tmp2_ = sqlite_errmsg;
		_tmp3_ = g_strdup (_tmp2_);
		_g_free0 (_vala_errmsg);
		_vala_errmsg = _tmp3_;
	} else {
		_g_free0 (_vala_errmsg);
		_vala_errmsg = NULL;
	}
	_tmp4_ = sqlite_errmsg;
	sqlite3_free ((void*) _tmp4_);
	result = ec;
	if (errmsg) {
		*errmsg = _vala_errmsg;
	} else {
		_g_free0 (_vala_errmsg);
	}
	return result;
}

static void
geary_db_database_connection_real_exec (GearyDbConnection* base,
                                        const gchar* sql,
                                        GCancellable* cancellable,
                                        GError** error)
{
	GearyDbDatabaseConnection * self;
	GTimer* timer = NULL;
	GTimer* _tmp0_;
	sqlite3* _tmp1_;
	sqlite3* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	GTimer* _tmp5_;
	GError* _inner_error0_ = NULL;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_DB_TYPE_DATABASE_CONNECTION, GearyDbDatabaseConnection);
	g_return_if_fail (sql != NULL);
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	geary_db_check_cancelled ("Connection.exec", cancellable, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
	if (geary_db_context_enable_sql_logging) {
		geary_logging_source_debug (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), "%s", sql);
	}
	_tmp0_ = g_timer_new ();
	timer = _tmp0_;
	_tmp1_ = geary_db_connection_get_db (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_DB_TYPE_CONNECTION, GearyDbConnection));
	_tmp2_ = _tmp1_;
	geary_db_context_throw_on_error (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_DB_TYPE_CONTEXT, GearyDbContext), "Connection.exec_file", _sqlite3_exec (_tmp2_, sql, NULL, NULL, NULL), sql, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_timer_destroy0 (timer);
		return;
	}
	_tmp3_ = g_strdup_printf ("Query \"%s\"", sql);
	_tmp4_ = _tmp3_;
	_tmp5_ = timer;
	geary_db_context_check_elapsed (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_DB_TYPE_CONTEXT, GearyDbContext), _tmp4_, _tmp5_, &_inner_error0_);
	_g_free0 (_tmp4_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_timer_destroy0 (timer);
		return;
	}
	_g_timer_destroy0 (timer);
}

/** {@inheritDoc} */
static void
geary_db_database_connection_real_exec_file (GearyDbConnection* base,
                                             GFile* file,
                                             GCancellable* cancellable,
                                             GError** error)
{
	GearyDbDatabaseConnection * self;
	gchar* sql = NULL;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_ = NULL;
	GTimer* timer = NULL;
	GTimer* _tmp5_;
	sqlite3* _tmp6_;
	sqlite3* _tmp7_;
	const gchar* _tmp8_;
	const gchar* _tmp9_;
	gchar* _tmp10_;
	gchar* _tmp11_;
	GTimer* _tmp12_;
	GError* _inner_error0_ = NULL;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_DB_TYPE_DATABASE_CONNECTION, GearyDbDatabaseConnection);
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (file, g_file_get_type ()));
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	geary_db_check_cancelled ("Connection.exec_file", cancellable, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return;
	}
	if (geary_db_context_enable_sql_logging) {
		gchar* _tmp0_;
		gchar* _tmp1_;
		_tmp0_ = g_file_get_path (file);
		_tmp1_ = _tmp0_;
		geary_logging_source_debug (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), "%s", _tmp1_);
		_g_free0 (_tmp1_);
	}
	_tmp2_ = g_file_get_path (file);
	_tmp3_ = _tmp2_;
	g_file_get_contents (_tmp3_, &_tmp4_, NULL, &_inner_error0_);
	_g_free0 (sql);
	sql = _tmp4_;
	_g_free0 (_tmp3_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_free0 (sql);
		return;
	}
	_tmp5_ = g_timer_new ();
	timer = _tmp5_;
	_tmp6_ = geary_db_connection_get_db (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_DB_TYPE_CONNECTION, GearyDbConnection));
	_tmp7_ = _tmp6_;
	_tmp8_ = sql;
	_tmp9_ = sql;
	geary_db_context_throw_on_error (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_DB_TYPE_CONTEXT, GearyDbContext), "Connection.exec_file", _sqlite3_exec (_tmp7_, _tmp8_, NULL, NULL, NULL), _tmp9_, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_timer_destroy0 (timer);
		_g_free0 (sql);
		return;
	}
	_tmp10_ = g_file_get_path (file);
	_tmp11_ = _tmp10_;
	_tmp12_ = timer;
	geary_db_context_check_elapsed (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_DB_TYPE_CONTEXT, GearyDbContext), _tmp11_, _tmp12_, &_inner_error0_);
	_g_free0 (_tmp11_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_timer_destroy0 (timer);
		_g_free0 (sql);
		return;
	}
	_g_timer_destroy0 (timer);
	_g_free0 (sql);
}

/**
     * Executes a transaction using this connection.
     *
     * Executes one or more queries inside an SQLite transaction.
     * This call will initiate a transaction according to the
     * TransactionType specified (although this is merely an
     * optimization -- no matter the transaction type, SQLite
     * guarantees the subsequent operations to be atomic).  The
     * commands executed inside the TransactionMethod against the
     * supplied Db.Connection will be in the context of the
     * transaction.  If the TransactionMethod returns
     * TransactionOutcome.COMMIT, the transaction will be committed to
     * the database, otherwise it will be rolled back and the database
     * left unchanged.
     *
     * See [[http://www.sqlite.org/lang_transaction.html]]
     */
GearyDbTransactionOutcome
geary_db_database_connection_exec_transaction (GearyDbDatabaseConnection* self,
                                               GearyDbTransactionType type,
                                               GearyDbTransactionMethod cb,
                                               gpointer cb_target,
                                               GCancellable* cancellable,
                                               GError** error)
{
	GearyDbTransactionConnection* txn_cx = NULL;
	GearyDbTransactionConnection* _tmp0_;
	GearyDbTransactionOutcome outcome = 0;
	GError* caught_err = NULL;
	GError* _tmp31_;
	GError* _inner_error0_ = NULL;
	GearyDbTransactionOutcome result;
	g_return_val_if_fail (GEARY_DB_IS_DATABASE_CONNECTION (self), 0);
	g_return_val_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()), 0);
	_tmp0_ = geary_db_transaction_connection_new (self);
	txn_cx = _tmp0_;
	{
		GearyDbTransactionConnection* _tmp1_;
		const gchar* _tmp2_;
		_tmp1_ = txn_cx;
		_tmp2_ = geary_db_transaction_type_sql (type);
		geary_db_connection_exec (G_TYPE_CHECK_INSTANCE_CAST (_tmp1_, GEARY_DB_TYPE_CONNECTION, GearyDbConnection), _tmp2_, cancellable, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* err = NULL;
		GError* _tmp3_;
		GError* _tmp7_;
		GError* _tmp8_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp3_ = err;
		if (!g_error_matches (_tmp3_, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
			const gchar* _tmp4_;
			GError* _tmp5_;
			const gchar* _tmp6_;
			_tmp4_ = geary_db_transaction_type_sql (type);
			_tmp5_ = err;
			_tmp6_ = _tmp5_->message;
			geary_logging_source_debug (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), "Connection.exec_transaction: unable to %s: %s", _tmp4_, _tmp6_);
		}
		_tmp7_ = err;
		_tmp8_ = _g_error_copy0 (_tmp7_);
		_inner_error0_ = _tmp8_;
		_g_error_free0 (err);
		goto __finally0;
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (txn_cx);
		return 0;
	}
	outcome = GEARY_DB_TRANSACTION_OUTCOME_ROLLBACK;
	caught_err = NULL;
	{
		GearyDbTransactionOutcome _tmp9_ = 0;
		GearyDbTransactionConnection* _tmp10_;
		_tmp10_ = txn_cx;
		_tmp9_ = cb (G_TYPE_CHECK_INSTANCE_CAST (_tmp10_, GEARY_DB_TYPE_CONNECTION, GearyDbConnection), cancellable, cb_target, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch1_g_error;
		}
		outcome = _tmp9_;
	}
	goto __finally1;
	__catch1_g_error:
	{
		GError* err = NULL;
		GError* _tmp11_;
		GError* _tmp18_;
		GError* _tmp19_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp11_ = err;
		if (!g_error_matches (_tmp11_, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
			GError* _tmp12_;
			const gchar* _tmp13_;
			GearyDbTransactionConnection* _tmp14_;
			gchar** _tmp15_;
			gint _tmp15__length1;
			_tmp12_ = err;
			_tmp13_ = _tmp12_->message;
			geary_logging_source_debug (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), "Connection.exec_transaction: transaction threw error: %s", _tmp13_);
			_tmp14_ = txn_cx;
			_tmp15_ = _tmp14_->transaction_log;
			_tmp15__length1 = _tmp14_->transaction_log_length1;
			{
				gchar** statement_collection = NULL;
				gint statement_collection_length1 = 0;
				gint _statement_collection_size_ = 0;
				gint statement_it = 0;
				statement_collection = _tmp15_;
				statement_collection_length1 = _tmp15__length1;
				for (statement_it = 0; statement_it < statement_collection_length1; statement_it = statement_it + 1) {
					gchar* _tmp16_;
					gchar* statement = NULL;
					_tmp16_ = g_strdup (statement_collection[statement_it]);
					statement = _tmp16_;
					{
						const gchar* _tmp17_;
						_tmp17_ = statement;
						geary_logging_source_debug (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), " - %s", _tmp17_);
						_g_free0 (statement);
					}
				}
			}
		}
		_tmp18_ = err;
		_tmp19_ = _g_error_copy0 (_tmp18_);
		_g_error_free0 (caught_err);
		caught_err = _tmp19_;
		_g_error_free0 (err);
	}
	__finally1:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_error_free0 (caught_err);
		_g_object_unref0 (txn_cx);
		return 0;
	}
	{
		GearyDbTransactionConnection* _tmp20_;
		const gchar* _tmp21_;
		_tmp20_ = txn_cx;
		_tmp21_ = geary_db_transaction_outcome_sql (outcome);
		geary_db_connection_exec (G_TYPE_CHECK_INSTANCE_CAST (_tmp20_, GEARY_DB_TYPE_CONNECTION, GearyDbConnection), _tmp21_, NULL, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch2_g_error;
		}
	}
	goto __finally2;
	__catch2_g_error:
	{
		GError* err = NULL;
		gchar* _tmp22_;
		gchar* _tmp23_;
		GError* _tmp24_;
		const gchar* _tmp25_;
		GError* _tmp26_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp22_ = geary_db_transaction_outcome_to_string (outcome);
		_tmp23_ = _tmp22_;
		_tmp24_ = err;
		_tmp25_ = _tmp24_->message;
		geary_logging_source_debug (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), "Connection.exec_transaction: Unable to %s transaction: %s", _tmp23_, _tmp25_);
		_g_free0 (_tmp23_);
		_tmp26_ = caught_err;
		if (_tmp26_ == NULL) {
			GearyDbTransactionConnection* _tmp27_;
			gchar** _tmp28_;
			gint _tmp28__length1;
			_tmp27_ = txn_cx;
			_tmp28_ = _tmp27_->transaction_log;
			_tmp28__length1 = _tmp27_->transaction_log_length1;
			{
				gchar** statement_collection = NULL;
				gint statement_collection_length1 = 0;
				gint _statement_collection_size_ = 0;
				gint statement_it = 0;
				statement_collection = _tmp28_;
				statement_collection_length1 = _tmp28__length1;
				for (statement_it = 0; statement_it < statement_collection_length1; statement_it = statement_it + 1) {
					gchar* _tmp29_;
					gchar* statement = NULL;
					_tmp29_ = g_strdup (statement_collection[statement_it]);
					statement = _tmp29_;
					{
						const gchar* _tmp30_;
						_tmp30_ = statement;
						geary_logging_source_debug (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), " - %s", _tmp30_);
						_g_free0 (statement);
					}
				}
			}
		}
		_g_error_free0 (err);
	}
	__finally2:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_error_free0 (caught_err);
		_g_object_unref0 (txn_cx);
		return 0;
	}
	_tmp31_ = caught_err;
	if (_tmp31_ != NULL) {
		GError* _tmp32_;
		GError* _tmp33_;
		_tmp32_ = caught_err;
		_tmp33_ = _g_error_copy0 (_tmp32_);
		_inner_error0_ = _tmp33_;
		g_propagate_error (error, _inner_error0_);
		_g_error_free0 (caught_err);
		_g_object_unref0 (txn_cx);
		return 0;
	}
	result = outcome;
	_g_error_free0 (caught_err);
	_g_object_unref0 (txn_cx);
	return result;
}

static void
geary_db_database_connection_exec_transaction_async_data_free (gpointer _data)
{
	GearyDbDatabaseConnectionExecTransactionAsyncData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->cancellable);
	_g_object_unref0 (_data_->self);
	g_slice_free (GearyDbDatabaseConnectionExecTransactionAsyncData, _data_);
}

static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

void
geary_db_database_connection_exec_transaction_async (GearyDbDatabaseConnection* self,
                                                     GearyDbTransactionType type,
                                                     GearyDbTransactionMethod cb,
                                                     gpointer cb_target,
                                                     GCancellable* cancellable,
                                                     GAsyncReadyCallback _callback_,
                                                     gpointer _user_data_)
{
	GearyDbDatabaseConnectionExecTransactionAsyncData* _data_;
	GearyDbDatabaseConnection* _tmp0_;
	GCancellable* _tmp1_;
	g_return_if_fail (GEARY_DB_IS_DATABASE_CONNECTION (self));
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	_data_ = g_slice_new0 (GearyDbDatabaseConnectionExecTransactionAsyncData);
	_data_->_async_result = g_task_new (G_OBJECT (self), cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, geary_db_database_connection_exec_transaction_async_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_data_->type = type;
	_data_->cb = cb;
	_data_->cb_target = cb_target;
	_tmp1_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp1_;
	geary_db_database_connection_exec_transaction_async_co (_data_);
}

GearyDbTransactionOutcome
geary_db_database_connection_exec_transaction_finish (GearyDbDatabaseConnection* self,
                                                      GAsyncResult* _res_,
                                                      GError** error)
{
	GearyDbTransactionOutcome result;
	GearyDbDatabaseConnectionExecTransactionAsyncData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return 0;
	}
	result = _data_->result;
	return result;
}

/**
     * Executes an asynchronous transaction using this connection.
     *
     * Asynchronous transactions are handled via background
     * threads. The background thread calls {@link exec_transaction};
     * see that method for more information about coding a
     * transaction. The only caveat is that the {@link
     * TransactionMethod} passed to it must be thread-safe.
     *
     * Throws {@link DatabaseError.OPEN_REQUIRED} if not open.
     */
static void
geary_db_database_connection_exec_transaction_async_ready (GObject* source_object,
                                                           GAsyncResult* _res_,
                                                           gpointer _user_data_)
{
	GearyDbDatabaseConnectionExecTransactionAsyncData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	geary_db_database_connection_exec_transaction_async_co (_data_);
}

static gboolean
geary_db_database_connection_exec_transaction_async_co (GearyDbDatabaseConnectionExecTransactionAsyncData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = geary_db_transaction_async_job_new (_data_->self, _data_->type, _data_->cb, _data_->cb_target, _data_->cancellable);
	_data_->job = _data_->_tmp0_;
	_data_->_tmp1_ = geary_db_connection_get_database (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, GEARY_DB_TYPE_CONNECTION, GearyDbConnection));
	_data_->_tmp2_ = _data_->_tmp1_;
	_data_->_tmp3_ = _data_->job;
	geary_db_database_add_async_job (_data_->_tmp2_, _data_->_tmp3_, &_data_->_inner_error0_);
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		_g_object_unref0 (_data_->job);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->_tmp5_ = _data_->job;
	_data_->_state_ = 1;
	geary_db_transaction_async_job_wait_for_completion_async (_data_->_tmp5_, geary_db_database_connection_exec_transaction_async_ready, _data_);
	return FALSE;
	_state_1:
	_data_->_tmp4_ = geary_db_transaction_async_job_wait_for_completion_finish (_data_->_tmp5_, _data_->_res_, &_data_->_inner_error0_);
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		_g_object_unref0 (_data_->job);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->result = _data_->_tmp4_;
	_g_object_unref0 (_data_->job);
	g_task_return_pointer (_data_->_async_result, _data_, NULL);
	if (_data_->_state_ != 0) {
		while (!g_task_get_completed (_data_->_async_result)) {
			g_main_context_iteration (g_task_get_context (_data_->_async_result), TRUE);
		}
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}

/** {@inheritDoc} */
static GearyLoggingState*
geary_db_database_connection_real_to_logging_state (GearyDbContext* base)
{
	GearyDbDatabaseConnection * self;
	GearyLoggingState* _tmp0_;
	GearyLoggingState* result;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_DB_TYPE_DATABASE_CONNECTION, GearyDbDatabaseConnection);
	_tmp0_ = geary_logging_state_new (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), "%u", self->priv->cx_number);
	result = _tmp0_;
	return result;
}

static GearyDbDatabaseConnection*
geary_db_database_connection_real_get_connection (GearyDbContext* base)
{
	GearyDbDatabaseConnection * self;
	GearyDbDatabaseConnection* _tmp0_;
	GearyDbDatabaseConnection* result;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_DB_TYPE_DATABASE_CONNECTION, GearyDbDatabaseConnection);
	_tmp0_ = _g_object_ref0 (self);
	result = _tmp0_;
	return result;
}

static void
geary_db_database_connection_class_init (GearyDbDatabaseConnectionClass * klass,
                                         gpointer klass_data)
{
	geary_db_database_connection_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GearyDbDatabaseConnection_private_offset);
	((GearyDbContextClass *) klass)->to_logging_state = (GearyLoggingState* (*) (GearyDbContext*)) geary_db_database_connection_real_to_logging_state;
	((GearyDbContextClass *) klass)->get_connection = (GearyDbDatabaseConnection* (*) (GearyDbContext*)) geary_db_database_connection_real_get_connection;
	GEARY_DB_CONTEXT_CLASS (klass)->get_logging_parent = geary_db_database_connection_real_get_logging_parent;
	G_OBJECT_CLASS (klass)->get_property = _vala_geary_db_database_connection_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_geary_db_database_connection_set_property;
	G_OBJECT_CLASS (klass)->finalize = geary_db_database_connection_finalize;
	/**
	     * The busy timeout for this connection.
	     *
	     * A non-zero, positive value indicates that all operations that
	     * SQLite returns BUSY will be retried until they complete with
	     * success or error. Only after the given amount of time has
	     * transpired will a {@link DatabaseError.BUSY} will be thrown. If
	     * zero or negative, a {@link DatabaseError.BUSY} will be
	     * immediately if the database is already locked when a new lock
	     * is required.
	     *
	     * Setting a positive value imperative for transactions, otherwise
	     * those calls will throw a {@link DatabaseError.BUSY} error
	     * immediately if another transaction has acquired the reserved or
	     * exclusive locks.
	     *
	     * @see DEFAULT_BUSY_TIMEOUT_MSEC
	     * @see RECOMMENDED_BUSY_TIMEOUT_MSEC
	     * @see set_busy_timeout_msec
	     */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_DB_DATABASE_CONNECTION_BUSY_TIMEOUT_PROPERTY, geary_db_database_connection_properties[GEARY_DB_DATABASE_CONNECTION_BUSY_TIMEOUT_PROPERTY] = g_param_spec_int ("busy-timeout", "busy-timeout", "busy-timeout", G_MININT, G_MAXINT, GEARY_DB_DATABASE_CONNECTION_DEFAULT_BUSY_TIMEOUT_MSEC, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/** {@inheritDoc} */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_DB_DATABASE_CONNECTION_DATABASE_PROPERTY, geary_db_database_connection_properties[GEARY_DB_DATABASE_CONNECTION_DATABASE_PROPERTY] = g_param_spec_object ("database", "database", "database", GEARY_DB_TYPE_DATABASE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/** {@inheritDoc} */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_DB_DATABASE_CONNECTION_LOGGING_PARENT_PROPERTY, geary_db_database_connection_properties[GEARY_DB_DATABASE_CONNECTION_LOGGING_PARENT_PROPERTY] = g_param_spec_object ("logging-parent", "logging-parent", "logging-parent", GEARY_LOGGING_TYPE_SOURCE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/** {@inheritDoc} */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_DB_DATABASE_CONNECTION_DB_PROPERTY, geary_db_database_connection_properties[GEARY_DB_DATABASE_CONNECTION_DB_PROPERTY] = g_param_spec_pointer ("db", "db", "db", G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_rec_mutex_init (&__lock_geary_db_database_connection_geary_db_database_connection_next_cx_number);
}

static void
geary_db_database_connection_geary_db_connection_interface_init (GearyDbConnectionIface * iface,
                                                                 gpointer iface_data)
{
	geary_db_database_connection_geary_db_connection_parent_iface = g_type_interface_peek_parent (iface);
	iface->prepare = (GearyDbStatement* (*) (GearyDbConnection*, const gchar*, GError**)) geary_db_database_connection_real_prepare;
	iface->query = (GearyDbResult* (*) (GearyDbConnection*, const gchar*, GCancellable*, GError**)) geary_db_database_connection_real_query;
	iface->exec = (void (*) (GearyDbConnection*, const gchar*, GCancellable*, GError**)) geary_db_database_connection_real_exec;
	iface->exec_file = (void (*) (GearyDbConnection*, GFile*, GCancellable*, GError**)) geary_db_database_connection_real_exec_file;
	iface->get_database = geary_db_database_connection_real_get_database;
	iface->get_db = geary_db_database_connection_real_get_db;
}

static void
geary_db_database_connection_instance_init (GearyDbDatabaseConnection * self,
                                            gpointer klass)
{
	self->priv = geary_db_database_connection_get_instance_private (self);
	self->priv->_busy_timeout = GEARY_DB_DATABASE_CONNECTION_DEFAULT_BUSY_TIMEOUT_MSEC;
}

static void
geary_db_database_connection_finalize (GObject * obj)
{
	GearyDbDatabaseConnection * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEARY_DB_TYPE_DATABASE_CONNECTION, GearyDbDatabaseConnection);
	_sqlite3_close0 (self->priv->_db);
	G_OBJECT_CLASS (geary_db_database_connection_parent_class)->finalize (obj);
}

/**
 * A primary connection to the database.
 */
 G_GNUC_NO_INLINE static GType
geary_db_database_connection_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GearyDbDatabaseConnectionClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) geary_db_database_connection_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GearyDbDatabaseConnection), 0, (GInstanceInitFunc) geary_db_database_connection_instance_init, NULL };
	static const GInterfaceInfo geary_db_connection_info = { (GInterfaceInitFunc) geary_db_database_connection_geary_db_connection_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	GType geary_db_database_connection_type_id;
	geary_db_database_connection_type_id = g_type_register_static (GEARY_DB_TYPE_CONTEXT, "GearyDbDatabaseConnection", &g_define_type_info, 0);
	g_type_add_interface_static (geary_db_database_connection_type_id, GEARY_DB_TYPE_CONNECTION, &geary_db_connection_info);
	GearyDbDatabaseConnection_private_offset = g_type_add_instance_private (geary_db_database_connection_type_id, sizeof (GearyDbDatabaseConnectionPrivate));
	return geary_db_database_connection_type_id;
}

GType
geary_db_database_connection_get_type (void)
{
	static gsize geary_db_database_connection_type_id__once = 0;
	if (g_once_init_enter (&geary_db_database_connection_type_id__once)) {
		GType geary_db_database_connection_type_id;
		geary_db_database_connection_type_id = geary_db_database_connection_get_type_once ();
		g_once_init_leave (&geary_db_database_connection_type_id__once, geary_db_database_connection_type_id);
	}
	return geary_db_database_connection_type_id__once;
}

static void
_vala_geary_db_database_connection_get_property (GObject * object,
                                                 guint property_id,
                                                 GValue * value,
                                                 GParamSpec * pspec)
{
	GearyDbDatabaseConnection * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEARY_DB_TYPE_DATABASE_CONNECTION, GearyDbDatabaseConnection);
	switch (property_id) {
		case GEARY_DB_DATABASE_CONNECTION_BUSY_TIMEOUT_PROPERTY:
		g_value_set_int (value, geary_db_database_connection_get_busy_timeout (self));
		break;
		case GEARY_DB_DATABASE_CONNECTION_DATABASE_PROPERTY:
		g_value_set_object (value, geary_db_connection_get_database (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_DB_TYPE_CONNECTION, GearyDbConnection)));
		break;
		case GEARY_DB_DATABASE_CONNECTION_LOGGING_PARENT_PROPERTY:
		g_value_set_object (value, geary_db_context_get_logging_parent (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_DB_TYPE_CONTEXT, GearyDbContext)));
		break;
		case GEARY_DB_DATABASE_CONNECTION_DB_PROPERTY:
		g_value_set_pointer (value, geary_db_connection_get_db (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_DB_TYPE_CONNECTION, GearyDbConnection)));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_geary_db_database_connection_set_property (GObject * object,
                                                 guint property_id,
                                                 const GValue * value,
                                                 GParamSpec * pspec)
{
	GearyDbDatabaseConnection * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEARY_DB_TYPE_DATABASE_CONNECTION, GearyDbDatabaseConnection);
	switch (property_id) {
		case GEARY_DB_DATABASE_CONNECTION_BUSY_TIMEOUT_PROPERTY:
		geary_db_database_connection_set_busy_timeout (self, g_value_get_int (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

