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

/*
 * Copyright 2016 Software Freedom Conservancy Inc.
 * Copyright 2018 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 <gio/gio.h>
#include <glib.h>
#include <stdlib.h>
#include <string.h>

enum  {
	GEARY_DB_VERSIONED_DATABASE_0_PROPERTY,
	GEARY_DB_VERSIONED_DATABASE_SCHEMA_DIR_PROPERTY,
	GEARY_DB_VERSIONED_DATABASE_NUM_PROPERTIES
};
static GParamSpec* geary_db_versioned_database_properties[GEARY_DB_VERSIONED_DATABASE_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef struct _GearyDbVersionedDatabasePreUpgradeData GearyDbVersionedDatabasePreUpgradeData;
typedef struct _GearyDbVersionedDatabasePostUpgradeData GearyDbVersionedDatabasePostUpgradeData;
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _GearyDbVersionedDatabaseOpenData GearyDbVersionedDatabaseOpenData;
typedef struct _Block24Data Block24Data;
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _GearyDbVersionedDatabaseExecuteUpgradeData GearyDbVersionedDatabaseExecuteUpgradeData;
typedef struct _GearyDbVersionedDatabaseExistsData GearyDbVersionedDatabaseExistsData;

struct _GearyDbVersionedDatabasePrivate {
	GFile* _schema_dir;
};

struct _GearyDbVersionedDatabasePreUpgradeData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	GearyDbVersionedDatabase* self;
	gint version;
	GCancellable* cancellable;
};

struct _GearyDbVersionedDatabasePostUpgradeData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	GearyDbVersionedDatabase* self;
	gint version;
	GCancellable* cancellable;
};

struct _GearyDbVersionedDatabaseOpenData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	GearyDbVersionedDatabase* self;
	GearyDbDatabaseFlags flags;
	GCancellable* cancellable;
	GearyDbDatabaseConnection* cx;
	GearyDbDatabaseConnection* _tmp0_;
	gint db_version;
	GearyDbDatabaseConnection* _tmp1_;
	const gchar* _tmp2_;
	const gchar* _tmp3_;
	gboolean new_db;
	GFile* _tmp4_;
	GFile* _tmp5_;
	gboolean _tmp6_;
	const gchar* _tmp7_;
	const gchar* _tmp8_;
	GError* _tmp9_;
	gboolean started;
	gboolean _tmp10_;
	GFile* upgrade_script;
	gint _tmp11_;
	GFile* _tmp12_;
	GFile* _tmp13_;
	gint token;
	GearyNonblockingMutex* _tmp14_;
	GError* locked_err;
	GearyDbDatabaseConnection* _tmp15_;
	GFile* _tmp16_;
	GError* err;
	GError* _tmp17_;
	GError* _tmp18_;
	GearyNonblockingMutex* _tmp19_;
	GError* _tmp20_;
	GError* _tmp21_;
	GError* _tmp22_;
	GError* _inner_error0_;
};

struct _Block24Data {
	int _ref_count_;
	GearyDbVersionedDatabase* self;
	gint db_version;
	GFile* upgrade_script;
	GCancellable* cancellable;
	gpointer _async_data_;
};

struct _GearyDbVersionedDatabaseExecuteUpgradeData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	GearyDbVersionedDatabase* self;
	GearyDbDatabaseConnection* cx;
	gint db_version;
	GFile* upgrade_script;
	GCancellable* cancellable;
	Block24Data* _data24_;
	gchar* _tmp0_;
	gchar* _tmp1_;
	GError* err;
	GError* _tmp2_;
	GError* _tmp3_;
	const gchar* _tmp4_;
	GError* _tmp5_;
	GError* _tmp6_;
	GError* _vala1_err;
	GError* _tmp7_;
	GError* _tmp8_;
	const gchar* _tmp9_;
	GError* _tmp10_;
	GError* _tmp11_;
	GError* _vala2_err;
	GError* _tmp12_;
	GError* _tmp13_;
	const gchar* _tmp14_;
	GError* _tmp15_;
	GError* _tmp16_;
	GError* _inner_error0_;
};

struct _GearyDbVersionedDatabaseExistsData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	GearyDbVersionedDatabase* self;
	GFile* target;
	GCancellable* cancellable;
	gboolean result;
	gboolean ret;
	GFileInfo* _tmp0_;
	GFileInfo* _tmp1_;
	GError* _inner_error0_;
};

static gint GearyDbVersionedDatabase_private_offset;
static gpointer geary_db_versioned_database_parent_class = NULL;
static GearyNonblockingMutex* geary_db_versioned_database_upgrade_mutex;
static GearyNonblockingMutex* geary_db_versioned_database_upgrade_mutex = NULL;

static void geary_db_versioned_database_set_schema_dir (GearyDbVersionedDatabase* self,
                                                 GFile* value);
static void geary_db_versioned_database_real_starting_upgrade (GearyDbVersionedDatabase* self,
                                                        gint current_version,
                                                        gboolean new_db);
static void geary_db_versioned_database_real_pre_upgrade_data_free (gpointer _data);
static void geary_db_versioned_database_real_pre_upgrade (GearyDbVersionedDatabase* self,
                                                   gint version,
                                                   GCancellable* cancellable,
                                                   GAsyncReadyCallback _callback_,
                                                   gpointer _user_data_);
static gboolean geary_db_versioned_database_real_pre_upgrade_co (GearyDbVersionedDatabasePreUpgradeData* _data_);
static void geary_db_versioned_database_real_post_upgrade_data_free (gpointer _data);
static void geary_db_versioned_database_real_post_upgrade (GearyDbVersionedDatabase* self,
                                                    gint version,
                                                    GCancellable* cancellable,
                                                    GAsyncReadyCallback _callback_,
                                                    gpointer _user_data_);
static gboolean geary_db_versioned_database_real_post_upgrade_co (GearyDbVersionedDatabasePostUpgradeData* _data_);
static void geary_db_versioned_database_real_completed_upgrade (GearyDbVersionedDatabase* self,
                                                         gint final_version);
static void geary_db_versioned_database_real_open_data_free (gpointer _data);
static void geary_db_versioned_database_real_open (GearyDbDatabase* base,
                                            GearyDbDatabaseFlags flags,
                                            GCancellable* cancellable,
                                            GAsyncReadyCallback _callback_,
                                            gpointer _user_data_);
static gboolean geary_db_versioned_database_real_open_co (GearyDbVersionedDatabaseOpenData* _data_);
static void geary_db_versioned_database_open_ready (GObject* source_object,
                                             GAsyncResult* _res_,
                                             gpointer _user_data_);
static void geary_db_versioned_database_exists (GearyDbVersionedDatabase* self,
                                         GFile* target,
                                         GCancellable* cancellable,
                                         GAsyncReadyCallback _callback_,
                                         gpointer _user_data_);
static gboolean geary_db_versioned_database_exists_finish (GearyDbVersionedDatabase* self,
                                                    GAsyncResult* _res_);
static GFile* geary_db_versioned_database_get_schema_file (GearyDbVersionedDatabase* self,
                                                    gint db_version);
static void geary_db_versioned_database_execute_upgrade (GearyDbVersionedDatabase* self,
                                                  GearyDbDatabaseConnection* cx,
                                                  gint db_version,
                                                  GFile* upgrade_script,
                                                  GCancellable* cancellable,
                                                  GAsyncReadyCallback _callback_,
                                                  gpointer _user_data_);
static void geary_db_versioned_database_execute_upgrade_finish (GearyDbVersionedDatabase* self,
                                                         GAsyncResult* _res_,
                                                         GError** error);
static void geary_db_versioned_database_execute_upgrade_data_free (gpointer _data);
static gboolean geary_db_versioned_database_execute_upgrade_co (GearyDbVersionedDatabaseExecuteUpgradeData* _data_);
static Block24Data* block24_data_ref (Block24Data* _data24_);
static void block24_data_unref (void * _userdata_);
VALA_EXTERN void geary_db_check_cancelled (const gchar* method,
                               GCancellable* cancellable,
                               GError** error);
static void geary_db_versioned_database_execute_upgrade_ready (GObject* source_object,
                                                        GAsyncResult* _res_,
                                                        gpointer _user_data_);
static GearyDbTransactionOutcome ___lambda24_ (Block24Data* _data24_,
                                        GearyDbConnection* cx,
                                        GError** error);
static GearyDbTransactionOutcome ____lambda24__geary_db_transaction_method (GearyDbConnection* cx,
                                                                     GCancellable* cancellable,
                                                                     gpointer self,
                                                                     GError** error);
static void geary_db_versioned_database_exists_data_free (gpointer _data);
static gboolean geary_db_versioned_database_exists_co (GearyDbVersionedDatabaseExistsData* _data_);
static void geary_db_versioned_database_exists_ready (GObject* source_object,
                                               GAsyncResult* _res_,
                                               gpointer _user_data_);
static void geary_db_versioned_database_finalize (GObject * obj);
static GType geary_db_versioned_database_get_type_once (void);
static void _vala_geary_db_versioned_database_get_property (GObject * object,
                                                     guint property_id,
                                                     GValue * value,
                                                     GParamSpec * pspec);
static void _vala_geary_db_versioned_database_set_property (GObject * object,
                                                     guint property_id,
                                                     const GValue * value,
                                                     GParamSpec * pspec);

static inline gpointer
geary_db_versioned_database_get_instance_private (GearyDbVersionedDatabase* self)
{
	return G_STRUCT_MEMBER_P (self, GearyDbVersionedDatabase_private_offset);
}

GFile*
geary_db_versioned_database_get_schema_dir (GearyDbVersionedDatabase* self)
{
	GFile* result;
	GFile* _tmp0_;
	g_return_val_if_fail (GEARY_DB_IS_VERSIONED_DATABASE (self), NULL);
	_tmp0_ = self->priv->_schema_dir;
	result = _tmp0_;
	return result;
}

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

static void
geary_db_versioned_database_set_schema_dir (GearyDbVersionedDatabase* self,
                                            GFile* value)
{
	GFile* old_value;
	g_return_if_fail (GEARY_DB_IS_VERSIONED_DATABASE (self));
	old_value = geary_db_versioned_database_get_schema_dir (self);
	if (old_value != value) {
		GFile* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_schema_dir);
		self->priv->_schema_dir = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, geary_db_versioned_database_properties[GEARY_DB_VERSIONED_DATABASE_SCHEMA_DIR_PROPERTY]);
	}
}

/** {@inheritDoc} */
GearyDbVersionedDatabase*
geary_db_versioned_database_construct_persistent (GType object_type,
                                                  GFile* db_file,
                                                  GFile* schema_dir)
{
	GearyDbVersionedDatabase * self = NULL;
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (db_file, g_file_get_type ()), NULL);
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (schema_dir, g_file_get_type ()), NULL);
	self = (GearyDbVersionedDatabase*) geary_db_database_construct_persistent (object_type, db_file);
	geary_db_versioned_database_set_schema_dir (self, schema_dir);
	return self;
}

GearyDbVersionedDatabase*
geary_db_versioned_database_new_persistent (GFile* db_file,
                                            GFile* schema_dir)
{
	return geary_db_versioned_database_construct_persistent (GEARY_DB_TYPE_VERSIONED_DATABASE, db_file, schema_dir);
}

/** {@inheritDoc} */
GearyDbVersionedDatabase*
geary_db_versioned_database_construct_transient (GType object_type,
                                                 GFile* schema_dir)
{
	GearyDbVersionedDatabase * self = NULL;
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (schema_dir, g_file_get_type ()), NULL);
	self = (GearyDbVersionedDatabase*) geary_db_database_construct_transient (object_type);
	geary_db_versioned_database_set_schema_dir (self, schema_dir);
	return self;
}

GearyDbVersionedDatabase*
geary_db_versioned_database_new_transient (GFile* schema_dir)
{
	return geary_db_versioned_database_construct_transient (GEARY_DB_TYPE_VERSIONED_DATABASE, schema_dir);
}

/** Returns the current schema version number of this database. */
gint
geary_db_versioned_database_get_schema_version (GearyDbVersionedDatabase* self,
                                                GError** error)
{
	GearyDbDatabaseConnection* _tmp0_ = NULL;
	GearyDbDatabaseConnection* _tmp1_;
	gint _tmp3_ = 0;
	GError* _inner_error0_ = NULL;
	gint result;
	g_return_val_if_fail (GEARY_DB_IS_VERSIONED_DATABASE (self), 0);
	_tmp1_ = geary_db_database_get_primary_connection (G_TYPE_CHECK_INSTANCE_CAST (self, GEARY_DB_TYPE_DATABASE, GearyDbDatabase), &_inner_error0_);
	_tmp0_ = _tmp1_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		gint _tmp2_ = -1;
		g_propagate_error (error, _inner_error0_);
		return _tmp2_;
	}
	_tmp3_ = geary_db_connection_get_user_version_number (G_TYPE_CHECK_INSTANCE_CAST (_tmp0_, GEARY_DB_TYPE_CONNECTION, GearyDbConnection), &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		gint _tmp4_ = -1;
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (_tmp0_);
		return _tmp4_;
	}
	result = _tmp3_;
	_g_object_unref0 (_tmp0_);
	return result;
}

/**
     * Called by {@link open} if a schema upgrade is required and beginning.
     *
     * If new_db is set to true, the database is being created from scratch.
     */
static void
geary_db_versioned_database_real_starting_upgrade (GearyDbVersionedDatabase* self,
                                                   gint current_version,
                                                   gboolean new_db)
{
}

void
geary_db_versioned_database_starting_upgrade (GearyDbVersionedDatabase* self,
                                              gint current_version,
                                              gboolean new_db)
{
	GearyDbVersionedDatabaseClass* _klass_;
	g_return_if_fail (GEARY_DB_IS_VERSIONED_DATABASE (self));
	_klass_ = GEARY_DB_VERSIONED_DATABASE_GET_CLASS (self);
	if (_klass_->starting_upgrade) {
		_klass_->starting_upgrade (self, current_version, new_db);
	}
}

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

static void
geary_db_versioned_database_real_pre_upgrade (GearyDbVersionedDatabase* self,
                                              gint version,
                                              GCancellable* cancellable,
                                              GAsyncReadyCallback _callback_,
                                              gpointer _user_data_)
{
	GearyDbVersionedDatabasePreUpgradeData* _data_;
	GearyDbVersionedDatabase* _tmp0_;
	GCancellable* _tmp1_;
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	_data_ = g_slice_new0 (GearyDbVersionedDatabasePreUpgradeData);
	_data_->_async_result = g_task_new (G_OBJECT (self), cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, geary_db_versioned_database_real_pre_upgrade_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_data_->version = version;
	_tmp1_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp1_;
	geary_db_versioned_database_real_pre_upgrade_co (_data_);
}

static void
geary_db_versioned_database_real_pre_upgrade_finish (GearyDbVersionedDatabase* self,
                                                     GAsyncResult* _res_,
                                                     GError** error)
{
	GearyDbVersionedDatabasePreUpgradeData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return;
	}
}

/**
     * Called by {@link open} just before performing a schema upgrade step.
     */
static gboolean
geary_db_versioned_database_real_pre_upgrade_co (GearyDbVersionedDatabasePreUpgradeData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	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;
}

void
geary_db_versioned_database_pre_upgrade (GearyDbVersionedDatabase* self,
                                         gint version,
                                         GCancellable* cancellable,
                                         GAsyncReadyCallback _callback_,
                                         gpointer _user_data_)
{
	GearyDbVersionedDatabaseClass* _klass_;
	_klass_ = GEARY_DB_VERSIONED_DATABASE_GET_CLASS (self);
	if (_klass_->pre_upgrade) {
		_klass_->pre_upgrade (self, version, cancellable, _callback_, _user_data_);
	}
}

void
geary_db_versioned_database_pre_upgrade_finish (GearyDbVersionedDatabase* self,
                                                GAsyncResult* _res_,
                                                GError** error)
{
	GearyDbVersionedDatabaseClass* _klass_;
	_klass_ = GEARY_DB_VERSIONED_DATABASE_GET_CLASS (self);
	if (_klass_->pre_upgrade_finish) {
		_klass_->pre_upgrade_finish (self, _res_, error);
	}
}

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

static void
geary_db_versioned_database_real_post_upgrade (GearyDbVersionedDatabase* self,
                                               gint version,
                                               GCancellable* cancellable,
                                               GAsyncReadyCallback _callback_,
                                               gpointer _user_data_)
{
	GearyDbVersionedDatabasePostUpgradeData* _data_;
	GearyDbVersionedDatabase* _tmp0_;
	GCancellable* _tmp1_;
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	_data_ = g_slice_new0 (GearyDbVersionedDatabasePostUpgradeData);
	_data_->_async_result = g_task_new (G_OBJECT (self), cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, geary_db_versioned_database_real_post_upgrade_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_data_->version = version;
	_tmp1_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp1_;
	geary_db_versioned_database_real_post_upgrade_co (_data_);
}

static void
geary_db_versioned_database_real_post_upgrade_finish (GearyDbVersionedDatabase* self,
                                                      GAsyncResult* _res_,
                                                      GError** error)
{
	GearyDbVersionedDatabasePostUpgradeData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return;
	}
}

/**
     * Called by {@link open} just after performing a schema upgrade step.
     */
static gboolean
geary_db_versioned_database_real_post_upgrade_co (GearyDbVersionedDatabasePostUpgradeData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	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;
}

void
geary_db_versioned_database_post_upgrade (GearyDbVersionedDatabase* self,
                                          gint version,
                                          GCancellable* cancellable,
                                          GAsyncReadyCallback _callback_,
                                          gpointer _user_data_)
{
	GearyDbVersionedDatabaseClass* _klass_;
	_klass_ = GEARY_DB_VERSIONED_DATABASE_GET_CLASS (self);
	if (_klass_->post_upgrade) {
		_klass_->post_upgrade (self, version, cancellable, _callback_, _user_data_);
	}
}

void
geary_db_versioned_database_post_upgrade_finish (GearyDbVersionedDatabase* self,
                                                 GAsyncResult* _res_,
                                                 GError** error)
{
	GearyDbVersionedDatabaseClass* _klass_;
	_klass_ = GEARY_DB_VERSIONED_DATABASE_GET_CLASS (self);
	if (_klass_->post_upgrade_finish) {
		_klass_->post_upgrade_finish (self, _res_, error);
	}
}

/**
     * Called by {@link open} if a schema upgrade was required and has now completed.
     */
static void
geary_db_versioned_database_real_completed_upgrade (GearyDbVersionedDatabase* self,
                                                    gint final_version)
{
}

void
geary_db_versioned_database_completed_upgrade (GearyDbVersionedDatabase* self,
                                               gint final_version)
{
	GearyDbVersionedDatabaseClass* _klass_;
	g_return_if_fail (GEARY_DB_IS_VERSIONED_DATABASE (self));
	_klass_ = GEARY_DB_VERSIONED_DATABASE_GET_CLASS (self);
	if (_klass_->completed_upgrade) {
		_klass_->completed_upgrade (self, final_version);
	}
}

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

static void
geary_db_versioned_database_real_open (GearyDbDatabase* base,
                                       GearyDbDatabaseFlags flags,
                                       GCancellable* cancellable,
                                       GAsyncReadyCallback _callback_,
                                       gpointer _user_data_)
{
	GearyDbVersionedDatabase * self;
	GearyDbVersionedDatabaseOpenData* _data_;
	GearyDbVersionedDatabase* _tmp0_;
	GCancellable* _tmp1_;
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_DB_TYPE_VERSIONED_DATABASE, GearyDbVersionedDatabase);
	_data_ = g_slice_new0 (GearyDbVersionedDatabaseOpenData);
	_data_->_async_result = g_task_new (G_OBJECT (self), cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, geary_db_versioned_database_real_open_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_data_->flags = flags;
	_tmp1_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp1_;
	geary_db_versioned_database_real_open_co (_data_);
}

static void
geary_db_versioned_database_open_finish (GearyDbDatabase* base,
                                         GAsyncResult* _res_,
                                         GError** error)
{
	GearyDbVersionedDatabaseOpenData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return;
	}
}

/**
     * Prepares the database for use, initializing and upgrading the schema.
     *
     * If it's detected that the database has a schema version that's
     * unavailable in the schema directory, throws {@link
     * DatabaseError.SCHEMA_VERSION}.  Generally this indicates the
     * user attempted to load the database with an older version of
     * the application.
     */
static void
geary_db_versioned_database_open_ready (GObject* source_object,
                                        GAsyncResult* _res_,
                                        gpointer _user_data_)
{
	GearyDbVersionedDatabaseOpenData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	geary_db_versioned_database_real_open_co (_data_);
}

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

static gboolean
geary_db_versioned_database_real_open_co (GearyDbVersionedDatabaseOpenData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		case 2:
		goto _state_2;
		case 3:
		goto _state_3;
		case 4:
		goto _state_4;
		case 5:
		goto _state_5;
		case 6:
		goto _state_6;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_state_ = 1;
	GEARY_DB_DATABASE_CLASS (geary_db_versioned_database_parent_class)->open (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, GEARY_DB_TYPE_DATABASE, GearyDbDatabase), _data_->flags, _data_->cancellable, geary_db_versioned_database_open_ready, _data_);
	return FALSE;
	_state_1:
	GEARY_DB_DATABASE_CLASS (geary_db_versioned_database_parent_class)->open_finish (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, GEARY_DB_TYPE_DATABASE, GearyDbDatabase), _data_->_res_, &_data_->_inner_error0_);
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->_state_ = 2;
	geary_db_database_open_connection (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, GEARY_DB_TYPE_DATABASE, GearyDbDatabase), _data_->cancellable, geary_db_versioned_database_open_ready, _data_);
	return FALSE;
	_state_2:
	_data_->_tmp0_ = geary_db_database_open_connection_finish (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, GEARY_DB_TYPE_DATABASE, GearyDbDatabase), _data_->_res_, &_data_->_inner_error0_);
	_data_->cx = _data_->_tmp0_;
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->_tmp1_ = _data_->cx;
	_data_->db_version = geary_db_connection_get_user_version_number (G_TYPE_CHECK_INSTANCE_CAST (_data_->_tmp1_, GEARY_DB_TYPE_CONNECTION, GearyDbConnection), &_data_->_inner_error0_);
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		_g_object_unref0 (_data_->cx);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->_tmp2_ = geary_db_database_get_path (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, GEARY_DB_TYPE_DATABASE, GearyDbDatabase));
	_data_->_tmp3_ = _data_->_tmp2_;
	geary_logging_source_debug (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), "VersionedDatabase.upgrade: current database schema for %s: %d", _data_->_tmp3_, _data_->db_version);
	_data_->new_db = _data_->db_version <= 0;
	if (_data_->db_version < 0) {
		_data_->db_version = 0;
	}
	if (_data_->db_version > 0) {
		_data_->_tmp4_ = geary_db_versioned_database_get_schema_file (_data_->self, _data_->db_version);
		_data_->_tmp5_ = _data_->_tmp4_;
		_data_->_state_ = 3;
		geary_db_versioned_database_exists (_data_->self, _data_->_tmp5_, _data_->cancellable, geary_db_versioned_database_open_ready, _data_);
		return FALSE;
		_state_3:
		_data_->_tmp6_ = !geary_db_versioned_database_exists_finish (_data_->self, _data_->_res_);
		_g_object_unref0 (_data_->_tmp5_);
		if (_data_->_tmp6_) {
			_data_->_tmp7_ = geary_db_database_get_path (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, GEARY_DB_TYPE_DATABASE, GearyDbDatabase));
			_data_->_tmp8_ = _data_->_tmp7_;
			_data_->_tmp9_ = g_error_new (GEARY_DATABASE_ERROR, GEARY_DATABASE_ERROR_SCHEMA_VERSION, "%s schema %d unknown to current schema plan", _data_->_tmp8_, _data_->db_version);
			_data_->_inner_error0_ = _data_->_tmp9_;
			g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
			_g_object_unref0 (_data_->cx);
			g_object_unref (_data_->_async_result);
			return FALSE;
		}
	}
	_data_->started = FALSE;
	{
		_data_->_tmp10_ = TRUE;
		while (TRUE) {
			if (!_data_->_tmp10_) {
			}
			_data_->_tmp10_ = FALSE;
			_data_->db_version = _data_->db_version + 1;
			_data_->_tmp11_ = _data_->db_version;
			_data_->_tmp12_ = geary_db_versioned_database_get_schema_file (_data_->self, _data_->_tmp11_);
			_data_->upgrade_script = _data_->_tmp12_;
			_data_->_tmp13_ = _data_->upgrade_script;
			_data_->_state_ = 4;
			geary_db_versioned_database_exists (_data_->self, _data_->_tmp13_, _data_->cancellable, geary_db_versioned_database_open_ready, _data_);
			return FALSE;
			_state_4:
			if (!geary_db_versioned_database_exists_finish (_data_->self, _data_->_res_)) {
				_g_object_unref0 (_data_->upgrade_script);
				break;
			}
			if (!_data_->started) {
				geary_db_versioned_database_starting_upgrade (_data_->self, _data_->db_version, _data_->new_db);
				_data_->started = TRUE;
			}
			_data_->_tmp14_ = geary_db_versioned_database_upgrade_mutex;
			_data_->_state_ = 5;
			geary_nonblocking_mutex_claim_async (_data_->_tmp14_, _data_->cancellable, geary_db_versioned_database_open_ready, _data_);
			return FALSE;
			_state_5:
			_data_->token = geary_nonblocking_mutex_claim_finish (_data_->_tmp14_, _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_->upgrade_script);
				_g_object_unref0 (_data_->cx);
				g_object_unref (_data_->_async_result);
				return FALSE;
			}
			_data_->locked_err = NULL;
			{
				_data_->_tmp15_ = _data_->cx;
				_data_->_tmp16_ = _data_->upgrade_script;
				_data_->_state_ = 6;
				geary_db_versioned_database_execute_upgrade (_data_->self, _data_->_tmp15_, _data_->db_version, _data_->_tmp16_, _data_->cancellable, geary_db_versioned_database_open_ready, _data_);
				return FALSE;
				_state_6:
				geary_db_versioned_database_execute_upgrade_finish (_data_->self, _data_->_res_, &_data_->_inner_error0_);
				if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
					goto __catch0_g_error;
				}
			}
			goto __finally0;
			__catch0_g_error:
			{
				_data_->err = _data_->_inner_error0_;
				_data_->_inner_error0_ = NULL;
				_data_->_tmp17_ = _data_->err;
				_data_->_tmp18_ = _g_error_copy0 (_data_->_tmp17_);
				_g_error_free0 (_data_->locked_err);
				_data_->locked_err = _data_->_tmp18_;
				_g_error_free0 (_data_->err);
			}
			__finally0:
			if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
				g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
				_g_error_free0 (_data_->locked_err);
				_g_object_unref0 (_data_->upgrade_script);
				_g_object_unref0 (_data_->cx);
				g_object_unref (_data_->_async_result);
				return FALSE;
			}
			_data_->_tmp19_ = geary_db_versioned_database_upgrade_mutex;
			geary_nonblocking_mutex_release (_data_->_tmp19_, &_data_->token, &_data_->_inner_error0_);
			if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
				g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
				_g_error_free0 (_data_->locked_err);
				_g_object_unref0 (_data_->upgrade_script);
				_g_object_unref0 (_data_->cx);
				g_object_unref (_data_->_async_result);
				return FALSE;
			}
			_data_->_tmp20_ = _data_->locked_err;
			if (_data_->_tmp20_ != NULL) {
				_data_->_tmp21_ = _data_->locked_err;
				_data_->_tmp22_ = _g_error_copy0 (_data_->_tmp21_);
				_data_->_inner_error0_ = _data_->_tmp22_;
				g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
				_g_error_free0 (_data_->locked_err);
				_g_object_unref0 (_data_->upgrade_script);
				_g_object_unref0 (_data_->cx);
				g_object_unref (_data_->_async_result);
				return FALSE;
			}
			_g_error_free0 (_data_->locked_err);
			_g_object_unref0 (_data_->upgrade_script);
		}
	}
	if (_data_->started) {
		geary_db_versioned_database_completed_upgrade (_data_->self, _data_->db_version);
	}
	_g_object_unref0 (_data_->cx);
	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;
}

static void
geary_db_versioned_database_execute_upgrade_data_free (gpointer _data)
{
	GearyDbVersionedDatabaseExecuteUpgradeData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->cx);
	_g_object_unref0 (_data_->self);
	g_slice_free (GearyDbVersionedDatabaseExecuteUpgradeData, _data_);
}

static void
geary_db_versioned_database_execute_upgrade (GearyDbVersionedDatabase* self,
                                             GearyDbDatabaseConnection* cx,
                                             gint db_version,
                                             GFile* upgrade_script,
                                             GCancellable* cancellable,
                                             GAsyncReadyCallback _callback_,
                                             gpointer _user_data_)
{
	GearyDbVersionedDatabaseExecuteUpgradeData* _data_;
	GearyDbVersionedDatabase* _tmp0_;
	GearyDbDatabaseConnection* _tmp1_;
	GFile* _tmp2_;
	GCancellable* _tmp3_;
	g_return_if_fail (GEARY_DB_IS_VERSIONED_DATABASE (self));
	g_return_if_fail (GEARY_DB_IS_DATABASE_CONNECTION (cx));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (upgrade_script, g_file_get_type ()));
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	_data_ = g_slice_new0 (GearyDbVersionedDatabaseExecuteUpgradeData);
	_data_->_async_result = g_task_new (G_OBJECT (self), cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, geary_db_versioned_database_execute_upgrade_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = _g_object_ref0 (cx);
	_g_object_unref0 (_data_->cx);
	_data_->cx = _tmp1_;
	_data_->db_version = db_version;
	_tmp2_ = _g_object_ref0 (upgrade_script);
	_g_object_unref0 (_data_->upgrade_script);
	_data_->upgrade_script = _tmp2_;
	_tmp3_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp3_;
	geary_db_versioned_database_execute_upgrade_co (_data_);
}

static void
geary_db_versioned_database_execute_upgrade_finish (GearyDbVersionedDatabase* self,
                                                    GAsyncResult* _res_,
                                                    GError** error)
{
	GearyDbVersionedDatabaseExecuteUpgradeData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return;
	}
}

static Block24Data*
block24_data_ref (Block24Data* _data24_)
{
	g_atomic_int_inc (&_data24_->_ref_count_);
	return _data24_;
}

static void
block24_data_unref (void * _userdata_)
{
	Block24Data* _data24_;
	_data24_ = (Block24Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data24_->_ref_count_)) {
		GearyDbVersionedDatabase* self;
		self = _data24_->self;
		_g_object_unref0 (_data24_->upgrade_script);
		_g_object_unref0 (_data24_->cancellable);
		_g_object_unref0 (self);
		g_slice_free (Block24Data, _data24_);
	}
}

static void
geary_db_versioned_database_execute_upgrade_ready (GObject* source_object,
                                                   GAsyncResult* _res_,
                                                   gpointer _user_data_)
{
	GearyDbVersionedDatabaseExecuteUpgradeData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	geary_db_versioned_database_execute_upgrade_co (_data_);
}

static GearyDbTransactionOutcome
___lambda24_ (Block24Data* _data24_,
              GearyDbConnection* cx,
              GError** error)
{
	GearyDbVersionedDatabase* self;
	GError* _inner_error0_ = NULL;
	GearyDbTransactionOutcome result;
	self = _data24_->self;
	g_return_val_if_fail (GEARY_DB_IS_CONNECTION (cx), 0);
	geary_db_connection_exec_file (cx, _data24_->upgrade_script, _data24_->cancellable, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return 0;
	}
	geary_db_connection_set_user_version_number (cx, _data24_->db_version, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		return 0;
	}
	result = GEARY_DB_TRANSACTION_OUTCOME_COMMIT;
	return result;
}

static GearyDbTransactionOutcome
____lambda24__geary_db_transaction_method (GearyDbConnection* cx,
                                           GCancellable* cancellable,
                                           gpointer self,
                                           GError** error)
{
	GearyDbTransactionOutcome result;
	result = ___lambda24_ (self, cx, error);
	return result;
}

static gboolean
geary_db_versioned_database_execute_upgrade_co (GearyDbVersionedDatabaseExecuteUpgradeData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		case 2:
		goto _state_2;
		case 3:
		goto _state_3;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_data24_ = g_slice_new0 (Block24Data);
	_data_->_data24_->_ref_count_ = 1;
	_data_->_data24_->self = g_object_ref (_data_->self);
	_data_->_data24_->db_version = _data_->db_version;
	_g_object_unref0 (_data_->_data24_->upgrade_script);
	_data_->_data24_->upgrade_script = _data_->upgrade_script;
	_g_object_unref0 (_data_->_data24_->cancellable);
	_data_->_data24_->cancellable = _data_->cancellable;
	_data_->_data24_->_async_data_ = _data_;
	_data_->_tmp0_ = g_file_get_path (_data_->_data24_->upgrade_script);
	_data_->_tmp1_ = _data_->_tmp0_;
	geary_logging_source_debug (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), "Upgrading database to version %d with %s", _data_->_data24_->db_version, _data_->_tmp1_);
	_g_free0 (_data_->_tmp1_);
	geary_db_check_cancelled ("VersionedDatabase.open", _data_->_data24_->cancellable, &_data_->_inner_error0_);
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		block24_data_unref (_data_->_data24_);
		_data_->_data24_ = NULL;
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	{
		_data_->_state_ = 1;
		geary_db_versioned_database_pre_upgrade (_data_->self, _data_->_data24_->db_version, _data_->_data24_->cancellable, geary_db_versioned_database_execute_upgrade_ready, _data_);
		return FALSE;
		_state_1:
		geary_db_versioned_database_pre_upgrade_finish (_data_->self, _data_->_res_, &_data_->_inner_error0_);
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		_data_->err = _data_->_inner_error0_;
		_data_->_inner_error0_ = NULL;
		_data_->_tmp2_ = _data_->err;
		if (!g_error_matches (_data_->_tmp2_, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
			_data_->_tmp3_ = _data_->err;
			_data_->_tmp4_ = _data_->_tmp3_->message;
			geary_logging_source_warning (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), "Error executing pre-upgrade for version %d: %s", _data_->_data24_->db_version, _data_->_tmp4_);
		}
		_data_->_tmp5_ = _data_->err;
		_data_->_tmp6_ = _g_error_copy0 (_data_->_tmp5_);
		_data_->_inner_error0_ = _data_->_tmp6_;
		_g_error_free0 (_data_->err);
		goto __finally0;
	}
	__finally0:
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		block24_data_unref (_data_->_data24_);
		_data_->_data24_ = NULL;
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	geary_db_check_cancelled ("VersionedDatabase.open", _data_->_data24_->cancellable, &_data_->_inner_error0_);
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		block24_data_unref (_data_->_data24_);
		_data_->_data24_ = NULL;
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	{
		_data_->_state_ = 2;
		geary_db_database_connection_exec_transaction_async (_data_->cx, GEARY_DB_TRANSACTION_TYPE_EXCLUSIVE, ____lambda24__geary_db_transaction_method, _data_->_data24_, _data_->_data24_->cancellable, geary_db_versioned_database_execute_upgrade_ready, _data_);
		return FALSE;
		_state_2:
		geary_db_database_connection_exec_transaction_finish (_data_->cx, _data_->_res_, &_data_->_inner_error0_);
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			goto __catch1_g_error;
		}
	}
	goto __finally1;
	__catch1_g_error:
	{
		_data_->_vala1_err = _data_->_inner_error0_;
		_data_->_inner_error0_ = NULL;
		_data_->_tmp7_ = _data_->_vala1_err;
		if (!g_error_matches (_data_->_tmp7_, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
			_data_->_tmp8_ = _data_->_vala1_err;
			_data_->_tmp9_ = _data_->_tmp8_->message;
			geary_logging_source_warning (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), "Error upgrading database to version %d: %s", _data_->_data24_->db_version, _data_->_tmp9_);
		}
		_data_->_tmp10_ = _data_->_vala1_err;
		_data_->_tmp11_ = _g_error_copy0 (_data_->_tmp10_);
		_data_->_inner_error0_ = _data_->_tmp11_;
		_g_error_free0 (_data_->_vala1_err);
		goto __finally1;
	}
	__finally1:
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		block24_data_unref (_data_->_data24_);
		_data_->_data24_ = NULL;
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	geary_db_check_cancelled ("VersionedDatabase.open", _data_->_data24_->cancellable, &_data_->_inner_error0_);
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		block24_data_unref (_data_->_data24_);
		_data_->_data24_ = NULL;
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	{
		_data_->_state_ = 3;
		geary_db_versioned_database_post_upgrade (_data_->self, _data_->_data24_->db_version, _data_->_data24_->cancellable, geary_db_versioned_database_execute_upgrade_ready, _data_);
		return FALSE;
		_state_3:
		geary_db_versioned_database_post_upgrade_finish (_data_->self, _data_->_res_, &_data_->_inner_error0_);
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			goto __catch2_g_error;
		}
	}
	goto __finally2;
	__catch2_g_error:
	{
		_data_->_vala2_err = _data_->_inner_error0_;
		_data_->_inner_error0_ = NULL;
		_data_->_tmp12_ = _data_->_vala2_err;
		if (!g_error_matches (_data_->_tmp12_, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
			_data_->_tmp13_ = _data_->_vala2_err;
			_data_->_tmp14_ = _data_->_tmp13_->message;
			geary_logging_source_warning (G_TYPE_CHECK_INSTANCE_CAST (_data_->self, GEARY_LOGGING_TYPE_SOURCE, GearyLoggingSource), "Error executing post-upgrade for version %d: %s", _data_->_data24_->db_version, _data_->_tmp14_);
		}
		_data_->_tmp15_ = _data_->_vala2_err;
		_data_->_tmp16_ = _g_error_copy0 (_data_->_tmp15_);
		_data_->_inner_error0_ = _data_->_tmp16_;
		_g_error_free0 (_data_->_vala2_err);
		goto __finally2;
	}
	__finally2:
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		block24_data_unref (_data_->_data24_);
		_data_->_data24_ = NULL;
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	block24_data_unref (_data_->_data24_);
	_data_->_data24_ = NULL;
	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;
}

static GFile*
geary_db_versioned_database_get_schema_file (GearyDbVersionedDatabase* self,
                                             gint db_version)
{
	GFile* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	GFile* _tmp3_;
	GFile* _tmp4_;
	GFile* result;
	g_return_val_if_fail (GEARY_DB_IS_VERSIONED_DATABASE (self), NULL);
	_tmp0_ = self->priv->_schema_dir;
	_tmp1_ = g_strdup_printf ("version-%03d.sql", db_version);
	_tmp2_ = _tmp1_;
	_tmp3_ = g_file_get_child (_tmp0_, _tmp2_);
	_tmp4_ = _tmp3_;
	_g_free0 (_tmp2_);
	result = _tmp4_;
	return result;
}

static void
geary_db_versioned_database_exists_data_free (gpointer _data)
{
	GearyDbVersionedDatabaseExistsData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->target);
	_g_object_unref0 (_data_->cancellable);
	_g_object_unref0 (_data_->self);
	g_slice_free (GearyDbVersionedDatabaseExistsData, _data_);
}

static void
geary_db_versioned_database_exists (GearyDbVersionedDatabase* self,
                                    GFile* target,
                                    GCancellable* cancellable,
                                    GAsyncReadyCallback _callback_,
                                    gpointer _user_data_)
{
	GearyDbVersionedDatabaseExistsData* _data_;
	GearyDbVersionedDatabase* _tmp0_;
	GFile* _tmp1_;
	GCancellable* _tmp2_;
	g_return_if_fail (GEARY_DB_IS_VERSIONED_DATABASE (self));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (target, g_file_get_type ()));
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	_data_ = g_slice_new0 (GearyDbVersionedDatabaseExistsData);
	_data_->_async_result = g_task_new (G_OBJECT (self), cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, geary_db_versioned_database_exists_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = _g_object_ref0 (target);
	_g_object_unref0 (_data_->target);
	_data_->target = _tmp1_;
	_tmp2_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp2_;
	geary_db_versioned_database_exists_co (_data_);
}

static gboolean
geary_db_versioned_database_exists_finish (GearyDbVersionedDatabase* self,
                                           GAsyncResult* _res_)
{
	gboolean result;
	GearyDbVersionedDatabaseExistsData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), NULL);
	if (NULL == _data_) {
		gboolean _tmp0_ = FALSE;
		return _tmp0_;
	}
	result = _data_->result;
	return result;
}

static void
geary_db_versioned_database_exists_ready (GObject* source_object,
                                          GAsyncResult* _res_,
                                          gpointer _user_data_)
{
	GearyDbVersionedDatabaseExistsData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	geary_db_versioned_database_exists_co (_data_);
}

static gboolean
geary_db_versioned_database_exists_co (GearyDbVersionedDatabaseExistsData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->ret = TRUE;
	{
		_data_->_state_ = 1;
		g_file_query_info_async (_data_->target, G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT, _data_->cancellable, geary_db_versioned_database_exists_ready, _data_);
		return FALSE;
		_state_1:
		_data_->_tmp0_ = g_file_query_info_finish (_data_->target, _data_->_res_, &_data_->_inner_error0_);
		_data_->_tmp1_ = _data_->_tmp0_;
		_g_object_unref0 (_data_->_tmp1_);
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		g_clear_error (&_data_->_inner_error0_);
		_data_->ret = FALSE;
	}
	__finally0:
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error0_->message, g_quark_to_string (_data_->_inner_error0_->domain), _data_->_inner_error0_->code);
		g_clear_error (&_data_->_inner_error0_);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->result = _data_->ret;
	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;
}

GearyDbVersionedDatabase*
geary_db_versioned_database_construct (GType object_type)
{
	GearyDbVersionedDatabase * self = NULL;
	self = (GearyDbVersionedDatabase*) geary_db_database_construct (object_type);
	return self;
}

GearyDbVersionedDatabase*
geary_db_versioned_database_new (void)
{
	return geary_db_versioned_database_construct (GEARY_DB_TYPE_VERSIONED_DATABASE);
}

static void
geary_db_versioned_database_class_init (GearyDbVersionedDatabaseClass * klass,
                                        gpointer klass_data)
{
	GearyNonblockingMutex* _tmp0_;
	geary_db_versioned_database_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GearyDbVersionedDatabase_private_offset);
	((GearyDbVersionedDatabaseClass *) klass)->starting_upgrade = (void (*) (GearyDbVersionedDatabase*, gint, gboolean)) geary_db_versioned_database_real_starting_upgrade;
	((GearyDbVersionedDatabaseClass *) klass)->pre_upgrade = (void (*) (GearyDbVersionedDatabase*, gint, GCancellable*, GAsyncReadyCallback, gpointer)) geary_db_versioned_database_real_pre_upgrade;
	((GearyDbVersionedDatabaseClass *) klass)->pre_upgrade_finish = (void (*) (GearyDbVersionedDatabase*, GAsyncResult*, GError**)) geary_db_versioned_database_real_pre_upgrade_finish;
	((GearyDbVersionedDatabaseClass *) klass)->post_upgrade = (void (*) (GearyDbVersionedDatabase*, gint, GCancellable*, GAsyncReadyCallback, gpointer)) geary_db_versioned_database_real_post_upgrade;
	((GearyDbVersionedDatabaseClass *) klass)->post_upgrade_finish = (void (*) (GearyDbVersionedDatabase*, GAsyncResult*, GError**)) geary_db_versioned_database_real_post_upgrade_finish;
	((GearyDbVersionedDatabaseClass *) klass)->completed_upgrade = (void (*) (GearyDbVersionedDatabase*, gint)) geary_db_versioned_database_real_completed_upgrade;
	((GearyDbDatabaseClass *) klass)->open = (void (*) (GearyDbDatabase*, GearyDbDatabaseFlags, GCancellable*, GAsyncReadyCallback, gpointer)) geary_db_versioned_database_real_open;
	((GearyDbDatabaseClass *) klass)->open_finish = (void (*) (GearyDbDatabase*, GAsyncResult*, GError**)) geary_db_versioned_database_open_finish;
	G_OBJECT_CLASS (klass)->get_property = _vala_geary_db_versioned_database_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_geary_db_versioned_database_set_property;
	G_OBJECT_CLASS (klass)->finalize = geary_db_versioned_database_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_DB_VERSIONED_DATABASE_SCHEMA_DIR_PROPERTY, geary_db_versioned_database_properties[GEARY_DB_VERSIONED_DATABASE_SCHEMA_DIR_PROPERTY] = g_param_spec_object ("schema-dir", "schema-dir", "schema-dir", g_file_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	_tmp0_ = geary_nonblocking_mutex_new ();
	geary_db_versioned_database_upgrade_mutex = _tmp0_;
}

static void
geary_db_versioned_database_instance_init (GearyDbVersionedDatabase * self,
                                           gpointer klass)
{
	self->priv = geary_db_versioned_database_get_instance_private (self);
}

static void
geary_db_versioned_database_finalize (GObject * obj)
{
	GearyDbVersionedDatabase * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEARY_DB_TYPE_VERSIONED_DATABASE, GearyDbVersionedDatabase);
	_g_object_unref0 (self->priv->_schema_dir);
	G_OBJECT_CLASS (geary_db_versioned_database_parent_class)->finalize (obj);
}

/**
 * A SQLite database with a versioned, upgradeable schema.
 *
 * This class uses the SQLite user version pragma to track the current
 * version of a database, and a set of SQL scripts (one per version)
 * to manage updating from one version to another. When the database
 * is first opened by a call to {@link open}, its current version is
 * checked against the set of available scripts, and each available
 * version script above the current version is applied in
 * order. Derived classes may override the {@link pre_upgrade} and
 * {@link post_upgrade} methods to perform additional work before and
 * after an upgrade script is executed, and {@link starting_upgrade}
 * and {@link completed_upgrade} to be notified of the upgrade process
 * starting and finishing.
 */
 G_GNUC_NO_INLINE static GType
geary_db_versioned_database_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GearyDbVersionedDatabaseClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) geary_db_versioned_database_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GearyDbVersionedDatabase), 0, (GInstanceInitFunc) geary_db_versioned_database_instance_init, NULL };
	GType geary_db_versioned_database_type_id;
	geary_db_versioned_database_type_id = g_type_register_static (GEARY_DB_TYPE_DATABASE, "GearyDbVersionedDatabase", &g_define_type_info, 0);
	GearyDbVersionedDatabase_private_offset = g_type_add_instance_private (geary_db_versioned_database_type_id, sizeof (GearyDbVersionedDatabasePrivate));
	return geary_db_versioned_database_type_id;
}

GType
geary_db_versioned_database_get_type (void)
{
	static gsize geary_db_versioned_database_type_id__once = 0;
	if (g_once_init_enter (&geary_db_versioned_database_type_id__once)) {
		GType geary_db_versioned_database_type_id;
		geary_db_versioned_database_type_id = geary_db_versioned_database_get_type_once ();
		g_once_init_leave (&geary_db_versioned_database_type_id__once, geary_db_versioned_database_type_id);
	}
	return geary_db_versioned_database_type_id__once;
}

static void
_vala_geary_db_versioned_database_get_property (GObject * object,
                                                guint property_id,
                                                GValue * value,
                                                GParamSpec * pspec)
{
	GearyDbVersionedDatabase * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEARY_DB_TYPE_VERSIONED_DATABASE, GearyDbVersionedDatabase);
	switch (property_id) {
		case GEARY_DB_VERSIONED_DATABASE_SCHEMA_DIR_PROPERTY:
		g_value_set_object (value, geary_db_versioned_database_get_schema_dir (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_geary_db_versioned_database_set_property (GObject * object,
                                                guint property_id,
                                                const GValue * value,
                                                GParamSpec * pspec)
{
	GearyDbVersionedDatabase * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEARY_DB_TYPE_VERSIONED_DATABASE, GearyDbVersionedDatabase);
	switch (property_id) {
		case GEARY_DB_VERSIONED_DATABASE_SCHEMA_DIR_PROPERTY:
		geary_db_versioned_database_set_schema_dir (self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

