Skip to content
John Njuki edited this page Jun 27, 2025 · 1 revision

Models

In this library, models are C++ classes that represent SQL database table schemas. They contain columns with different datatypes and attributes which describe the table schema. An example is given below which will be explained below.

#include <memory>
#include <strata/models.hpp>

class users : public Model{
public:
  users(){
    col_map["username"] = std::make_shared<CharField>(CharField("varchar", 24, true, true));
    col_map["email"] = std::make_shared<CharField>(CharField("varchar", 50, true, true));
    col_map["pin"] = std::make_shared<IntegerField>(IntegerField("integer", false, true));
  }
};REGISTER_MODEL(users);

Note

The Datatypes used above e.g. CharField(...) are documented under the Data Type Classes chapter.

Model Structure

The structure of the model users and any other model is as follows:

Inheritance from the Model class

Each defined model must inherit from the Model class. This is because the Model class contains all the necessary components needed to track changes in the models efficiently. e.g. the col_map map which is used to initialize the columns for the table, the make_migrations() function which does all the tracking, etc.

Note

These components are included from the <strata/models.hpp> header file.

Model Definition

  • Each model is defined as a class and inherits from Model class.
  • Each model must have a constructor which is to be used to initialize and define the columns and their datatypes.
  • The REGISTER_MODEL(model_name) macro MUST be called immediately after defining the model to register the model for tracking.

Warning

If REGISTER_MODEL() is ommitted, then the model shall not be tracked.

New models will be ignored and previously existing models will be marked for deletion.

The col_map column map

The column map is of the following structure:

using col_map = std::unordered_map<std::string, std::variant<std::shared_ptr<Datatype Class>...>>;

Now, most of you reading this might wonder/disagree with the choice for going with shared pointers in the variant, and I would agree. However, variant design requiring fully defined types before its definition and circular dependencies constrict me to use shared_pointers.

The definition of a column is as follows:

    col_map["column_name"] = std::make_shared<Datatype>(Datatype());

This means that to create a column inside the model, we make an entry in the col_map with the key as the column_name and the value as a shared pointer to the object of the datatype class representing the column.

Clone this wiki locally