zrm/docs/docs/insert-update.md

5.1 KiB

Insert & update

To define and use inserts and updates, you must have a fully defined repository. In this tutorial, we'll be assuming that we have a defined repository for a user model, as it's defined in this section.

Executing inserts and updates also require to set up a connection to your database. We'll also be assuming that we have a working database connector set up, as it's defined in this section.

Insert

Just like queries, we can insert models using the type Insert published on repositories. With this type, the inserted shape is the default one of the repository. You can customize this structure by using InsertCustom function.

const insertQuery = UserRepository.Insert.init(allocator, poolConnector.connector());
// or
const insertQuery = UserRepository.InsertCustom(struct {
	id: i32,
	name: []const u8,
}).init(allocator, poolConnector.connector());

If you just need to insert a model without any other parameters, repositories provide a create function which do just that. The given model will be altered with inserted row data.

const results = UserRepository.create(allocator, poolConnector.connector(), model);
defer results.deinit();

Values

With an insert query, we can pass our values to insert with the values function. This looks like set function of update queries.

// Insert a single model.
try insertQuery.values(model);
// Insert an array of models.
try insertQuery.values(&[_]Model{firstModel, secondModel});

// Insert a table-shaped structure.
try insertQuery.values(table);
// Insert an array of table-shaped structures.
try insertQuery.values(&[_]Model.Table{firstTable, secondTable});

// Insert a structure matching InsertShape.
try insertQuery.values(insertShapeStructure);
// Insert an array of structures matching InsertShape.
try insertQuery.values(&[_]Model.Table.Insert{firstInsertShape, secondInsertShape});

Returning

It's often useful to retrieve inserted data after the query. One use case would for example to get the inserted auto-increment IDs of the models. We can do this using the returningX functions of the insert query builder.

::: danger Never put user-sent values as selected columns. This could lead to severe security issues (like SQL injections). :::

Returning all

This will return all the columns of the inserted rows.

try insertQuery.values(...);
insertQuery.returningAll();

Returning columns

This will return all the provided columns of the inserted rows.

try insertQuery.values(...);
insertQuery.returningColumns(&[_][]const u8{"id", "name"});

Raw returning

We can also directly provide raw RETURNING clause content.

try insertQuery.values(...);
insertQuery.returning("id, label AS name");

Results

We can perform the insertion by running insert on the insert query.

const results = try insertQuery.insert(allocator);
defer results.deinit();

The results of an insert query are the same as normal queries. You can find the documentation about it in its dedicated section.

Update

To make an update query, we must provide the structure of the updated columns (called update shape).

const updateQuery = UserRepository.Update(struct { name: []const u8 }).init(allocator, poolConnector.connector());

If you just need to update a model without any other parameters, repositories provide a save function which do just that. The given model will be altered with updated row data.

const results = UserRepository.save(allocator, poolConnector.connector(), model);
defer results.deinit();

Values

With an update query, we can set our updated values with the set function. This looks like values function of insert queries.

// Set data of a single model.
try updateQuery.set(model);
// Set data of an array of models.
try updateQuery.values(&[_]Model{firstModel, secondModel});

// Set data of a table-shaped structure.
try updateQuery.values(table);
// Set data of an array of table-shaped structures.
try updateQuery.values(&[_]Model.Table{firstTable, secondTable});

// Set data of a structure matching UpdateShape.
try updateQuery.values(myUpdate);
// Set data of an array of structures matching UpdateShape.
try updateQuery.values(&[_]UpdateStruct{myFirstUpdate, mySecondUpdate});

Conditions

The conditions building API is the same as normal queries. You can find the documentation about it in its dedicated section.

Returning

The returning columns API is the same as insert queries. You can find the documentation about it in its dedicated section.

Results

We can perform the update by running update on the update query.

const results = try updateQuery.update(allocator);
defer results.deinit();

The results of an update query are the same as normal queries. You can find the documentation about it in its dedicated section.