Every time an app instance is started it needs to check if the database already contains the desired tables and otherwise create them. After software updates it might also need to add new columns to existing tables. This library provides a small collection of tasks that facilitate that job.
File | common/lib/tasks_postgresql.htm |
Classes |
TaskPostgreSQLInitTable TaskPostgreSQLInitEnum |
Examples |
Initializing a database using multiple sequential tasks |
A task that creates a single table including columns, constraints and indices, if not existing. Additional columns, constraints and indices are added if they don't exist.
class TaskPostgreSQLInitTable : public ITask, public UDatabase {
...
public:
TaskPostgreSQLInitTable(class IDatabase * database, const char * tableName);
virtual ~TaskPostgreSQLInitTable();
void AddColumn(const char * name, const char * type);
void AddConstraint(const char * name, const char * value);
void AddIndex(const char * name, const char * value, bool unique);
void Start(class UTask * user) override;
};
Contructor used to initialize the class.
class IDatabase * database | The IDatabase object representing the connection to the database. |
const char * tableName |
The name of the table. The CREATE statement puts the tableName inside double quotes. Pay attention about the casing and chars inside the tableName. If you e.g. use uppercase letters or spaces within the table name, you must later double quote the table name in your queries yourself too! |
Specifies a column for the database table.
const char * name | The name of the column. |
const char * type | The type of the column, e.g. "VARCHAR(32) UNIQUE NOT NULL". |
Specifies the constraint of a column.
const char * name | The name of the column. |
const char * value | The constraint of the column, e.g. "UNIQUE (domain_id, name)". |
Adds an index to the table. Indices can include a single column or multiple columns.
const char * name | The name of the index. |
const char * value | A comma separated list of column names, e.g. "domain_id, name". |
bool unique | Tells if the data in the specified columns is unique. |
Starts the task of checking / creating the table.
class UTask * user | The UTask object that shall receive the TaskComplete or TaskFailed callback after completion. |
A task that creates an enum in the database, if it does not already exist.
class TaskPostgreSQLInitEnum : public ITask, public UDatabase {
...
public:
TaskPostgreSQLInitEnum(IDatabase * const database, const char * enumName);
virtual ~TaskPostgreSQLInitEnum();
void AddValue(const char * name);
void Start(class UTask * user) override;
};
Contructor used to initialize the class.
class IDatabase * database | The IDatabase object representing the connection to the database. |
const char * enumName | The name of the enum. |
Adds a single value to the enum.
const char * name | The value to be added, e.g. "DEMO_TYPE_1" |
Starts the task of checking / creating the enum.
class UTask * user | The UTask object that shall receive the TaskComplete or TaskFailed callback after completion. |
#include "platform/platform.h"
#include "common/interface/database.h"
#include "common/interface/task.h"
#include "common/lib/tasks_postgresql.h"
#include "sysadmin_tables.h"
TaskDatabaseInit::TaskDatabaseInit(IDatabase * database) :
initEnum(database, "demo_type"),
initDomains(database, "domains"),
initLocations(database, "locations"),
{
// enums
initEnum.AddValue("DEMO_TYPE_1");
initEnum.AddValue("DEMO_TYPE_2");
initEnum.AddValue("DEMO_TYPE_3");
// domains
initDomains.AddColumn("id", "BIGSERIAL PRIMARY KEY NOT NULL");
initDomains.AddColumn("name", "VARCHAR(32) UNIQUE NOT NULL");
initDomains.AddColum("enum_demo", "demo_type"); // Type of the field = name of the enum
initDomains.AddIndex("domains_index_name", "name", false);
// locations
initLocations.AddColumn("id", "BIGSERIAL PRIMARY KEY NOT NULL");
initLocations.AddColumn("domain_id", "BIGINT REFERENCES domains(id)");
initLocations.AddColumn("name", "VARCHAR(32) NOT NULL");
initLocations.AddConstraint("locations_unique_name", "UNIQUE (domain_id, name)");
initLocations.AddIndex("locations_index_name", "domain_id, name", true); // index on several columns
}
TaskDatabaseInit::~TaskDatabaseInit()
{
}
void TaskDatabaseInit::Start(class UTask * user)
{
this->user = user;
initEnums.Start(this);
}
void TaskDatabaseInit::TaskComplete(class ITask * const task)
{
if (task == &initEnum) initDomains.Start(this);
else if (task == &initDomains) initLocations.Start(this);
else if (task == &initLocations) user->TaskComplete(this);
else ASSERT(false, "TaskDatabaseInit::TaskComplete");
}
void TaskDatabaseInit::TaskFailed(class ITask * const task)
{
user->TaskFailed(this);
}