Skip to content

Commit

Permalink
Add documentation for sql query builder
Browse files Browse the repository at this point in the history
  • Loading branch information
Yaraslaut committed Jan 2, 2025
1 parent 0847adc commit 9c837fc
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 9 deletions.
1 change: 1 addition & 0 deletions docs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ if(DOXYGEN_FOUND)
"${PROJECT_SOURCE_DIR}/src";
"${PROJECT_SOURCE_DIR}/README.md";
"${PROJECT_SOURCE_DIR}/docs/usage.md";
"${PROJECT_SOURCE_DIR}/docs/sqlquery.md";
"${PROJECT_SOURCE_DIR}/docs/best-practices.md";
)
doxygen_add_docs(doc
Expand Down
114 changes: 114 additions & 0 deletions docs/sqlquery.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Sql Query

Sql Query builder class is the starting point of building sql queries to execute.

## Create or Modife database schema
To create a database you need to use `Migration()` function provided by the `SqlQueryBuilder` class, then use API defined in `SqlMigrationQueryBuilder` to construct sql query to migrate to another schema or create a databse with the given schema. Detailed documentation can be found on separate documentation pages for each of the classes in the hirerarchy, here we present overall usage of the library. Following options exist.

* `CreateTable(tableName)`
Following calls can be chained, for example `CreateTable("test").Column(first).Column(second)...`
Available functions:
- `PrimaryKey(std::string columnName, SqlColumnTypeDefinition columnType)`
+ create primary key colunm in the database, defined by name and type.
- `PrimaryKeyWithAutoIncrement( std::string columnName, SqlColumnTypeDefinition columnType )`
+ create primary key column in the database with automatic indexing
+ Second parameter has a default value `SqlColumnTypeDefinitions::Bigint`
- `Column(std::string columnName, SqlColumnTypeDefinition columnType)`, `Column(SqlColumnDeclaration column)`
+ create a column specified by a name and type
+ for precise control on the column specification `SqlColumnDeclaration` can be used as an argument.
- `RequiredColumn(std::string columnName, SqlColumnTypeDefinition columnType)`
+ create a non-nullable column defined by the name and type.
- `Timestamps()`
+ adds the created_at and updated_at columns to the table.
- `ForeignKey(std::string columnName, SqlColumnTypeDefinition columnType, SqlForeignKeyReferenceDefinition foreignKey)`
+ creates a new nullable foreign key column, non-nullable version is a `RequiredForeignKey` function.
- Additional function that change specification of the created columns with the following usage: `CreateTable("test").Column(first).UniqueIndex()`.
+ `Unique()` enables the UNIQUE constrain on the last declared column.
+ `Index()` enables the INDEX constrain on the last declared column.
+ `UniqueIndex()` enables the UNIQUE and INDEX constrain on the last declared column.

* `AlterTable(tableName)`
Available functions:
- `RenameTo(std::string_view newTableName)`
+ renames the table.
- `RenameColumn(std::string_view oldColumnName, std::string_view newColumnName)`
+ renames a column.
- `DropColumn(std::string_view columnName)`
+ drops a column from the table.
- `AddIndex(std::string_view columnName)`
+ add an index to the table for the specified column.
- `AddUniqueIndex(std::string_view columnName)`
+ add an index to the table for the specified column that is unique.
- `DropIndex(std::string_view columnName)`
+ drop an index from the table for the specified column.

* `DropTable(tableName)`
- Drops table with the given name, please make sure that no foreign key constrains restricts execution of this query for the given table.


### Example

```
CreateTable("Appointment").PrimaryKeyWithAutoIncrement("id", Guid{})
.RequiredColumn("date", DateTime {} )
.Column("comment", Varchar{80})
.ForeignKey("physician_id", Guid{}, SqlForeignKeyReferenceDefinition {
.tableName = "Physician",
.columnName = "id",
} )
.ForeignKey("patient_id", Guid{}, SqlForeignKeyReferenceDefinition {
.tableName = "Patient",
.columnName = "id",
} );
```

## Insert elements
To insert elements in the database first call `FrommTable(table)` function to specify which table to use, and then function `Insert()` to start construction of `SqlInsertQueryBuilder`
* `Set(std::string_view columnName, ColumnValue const& value)`
- Adds a single column to the INSERT query.

## Select elements
To select some elements from the Database you first need to specify which existing table you are going to use, for this use `FromTable(table)` function, it returns you an instance of a `SqlQueryBuilder` and then use `Select()` function to continue constructing select query that described by `SqlSelectQueryBuilder` interface. Here we present a compressed list of functions that can be used to create complete selection query.

* Select field
- `Distinct()`
+ Adds a DISTINCT clause to the SELECT query.
- `Field()`
+ Simple usage `Field("field")`
+ With table name specification as `Field(SqlQualifiedTableColumnName { "Table", "field" })`
- `Fields()`
+ Simple usage `Fields({"a", "b", "c"})`
+ Fields from another table `Fields({"a", "b", "c"}, "Table_B")`
+ Choose all fields of a structure that represents table `Field<TableType>()`. Note: can pass more than one type
* (optional) Order and Group
- `OrderBy`
- `GroupBy`
* (optional) Additional option to build WHERE clause. See documentation for `SqlWhereClauseBuilder`
- `Where`
+ `Where("a",1)` specify simple condition that is equivalent to the sql query `WHERE "a" = 1`
+ `Where(SqlQualifiedTableColumnName{ .tableName = "Table_A", .columnName = "a"}, 1)` such call translated into `WHERE "Table_A".a" = 1`
- `Or()`, `And()` and `Not()` logical functions to apply to the next call
+ Example of usage `Where("a",1).Or().Where("b",1)`
- `Inner`|`LeftOuter`|`RightOuter`|`FullOuter` + `Join`
+ See documentation for `SqlJoinConditionBuilder` for details
* End
- `First()`
+ Specify number of elements to fetch, by default only one element will be fetched.
- `All()`


### Example

```
q.FromTable("Table_A")
.Select()
.Fields({ "foo"sv, "bar"sv }, "Table_A")
.Fields({ "that_foo"sv, "that_id"sv }, "Table_B")
.LeftOuterJoin("Table_B",
[](SqlJoinConditionBuilder q) {
return q.On("id", { .tableName = "Table_A", .columnName = "that_id" })
.On("that_foo", { .tableName = "Table_A", .columnName = "foo" });
})
.Where(SqlQualifiedTableColumnName { .tableName = "Table_A", .columnName = "foo" }, 42)
.All()
```
7 changes: 6 additions & 1 deletion scripts/check-pr-todos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ if [[ "${FOUND2}" != "" ]]; then
count=$[count + 1]
fi

FOUND3=$(git grep "TODO(PR)" | grep -v "scripts/check-pr-todos.sh")
if [[ "${FOUND3}" != "" ]]; then
count=$[count + 1]
fi

if [[ "${count}" == "0" ]]; then
exit 0
fi
echo "This PR still contains PR-related TODO itmes that must be resolved."
echo
echo "${FOUND} ${FOUND2}"
echo "${FOUND} ${FOUND2} ${FOUND3}"
exit 1
8 changes: 4 additions & 4 deletions src/Lightweight/SqlQuery/Migrate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ SqlAlterTableQueryBuilder& SqlAlterTableQueryBuilder::AddColumn(std::string colu
return *this;
}

SqlAlterTableQueryBuilder& SqlAlterTableQueryBuilder::AddColumnAsNullable(std::string columnName,
SqlColumnTypeDefinition columnType)
SqlAlterTableQueryBuilder& SqlAlterTableQueryBuilder::AddNotRequiredColumn(std::string columnName,
SqlColumnTypeDefinition columnType)
{
_plan.commands.emplace_back(SqlAlterTableCommands::AddColumn {
.columnName = std::move(columnName),
Expand Down Expand Up @@ -136,10 +136,10 @@ SqlAlterTableQueryBuilder& SqlAlterTableQueryBuilder::AddForeignKeyColumn(
return AddColumn(columnName, columnType).AddForeignKey(std::move(columnName), std::move(referencedColumn));
}

SqlAlterTableQueryBuilder& SqlAlterTableQueryBuilder::AddForeignKeyColumnAsNullable(
SqlAlterTableQueryBuilder& SqlAlterTableQueryBuilder::AddNotRequiredForeignKeyColumn(
std::string columnName, SqlColumnTypeDefinition columnType, SqlForeignKeyReferenceDefinition referencedColumn)
{
AddColumnAsNullable(columnName, columnType);
AddNotRequiredColumn(columnName, columnType);
AddForeignKey(std::move(columnName), std::move(referencedColumn));
return *this;
}
Expand Down
6 changes: 3 additions & 3 deletions src/Lightweight/SqlQuery/Migrate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ class [[nodiscard]] SqlAlterTableQueryBuilder final
LIGHTWEIGHT_API SqlAlterTableQueryBuilder& AddColumn(std::string columnName, SqlColumnTypeDefinition columnType);

/// Adds a new column to the table that is nullable.
LIGHTWEIGHT_API SqlAlterTableQueryBuilder& AddColumnAsNullable(std::string columnName,
SqlColumnTypeDefinition columnType);
LIGHTWEIGHT_API SqlAlterTableQueryBuilder& AddNotRequiredColumn(std::string columnName,
SqlColumnTypeDefinition columnType);

/// @brief Alters the column to have a new non-nullable type.
///
Expand Down Expand Up @@ -166,7 +166,7 @@ class [[nodiscard]] SqlAlterTableQueryBuilder final
/// @param columnName The name of the column to add.
/// @param columnType The type of the column to add.
/// @param referencedColumn The column to reference.
LIGHTWEIGHT_API SqlAlterTableQueryBuilder& AddForeignKeyColumnAsNullable(
LIGHTWEIGHT_API SqlAlterTableQueryBuilder& AddNotRequiredForeignKeyColumn(
std::string columnName, SqlColumnTypeDefinition columnType, SqlForeignKeyReferenceDefinition referencedColumn);

/// Drops a foreign key for the column @p columnName from the table.
Expand Down
2 changes: 1 addition & 1 deletion src/Lightweight/SqlQuery/Select.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class [[nodiscard]] SqlSelectQueryBuilder final: public SqlWhereClauseBuilder<Sq
/// Adds a single column to the SELECT clause.
LIGHTWEIGHT_API SqlSelectQueryBuilder& Field(SqlQualifiedTableColumnName const& fieldName);

/// Adds a single column to the SELECT clause.
/// Adds a sequence of columns to the SELECT clause.
LIGHTWEIGHT_API SqlSelectQueryBuilder& Fields(std::vector<std::string_view> const& fieldNames);

/// Adds a sequence of columns from the given table to the SELECT clause.
Expand Down

0 comments on commit 9c837fc

Please sign in to comment.