Our model will have the following methods: read
, getRecord
, update
, create
, delete
, isValidRecord
and getValidationDependency
.
Here, we’re going to use MySQL and Squel.
First, let’s define read
.
userGrid/model.js
:
const squel = require('squel');
const MySQLWrapper = require('../../common/mysql');
const validator = require('./validation');
const FIELDS = ['name', 'surname', 'phone', 'age', 'gender'];
class UserGridModel {
async read(settings) {
const query = squel.select()
.from('records')
.field('SQL_CALC_FOUND_ROWS id')
.limit(settings.limit || 10)
.offset(settings.offset || 0);
for (const fieldName of settings.fields) {
if (FIELDS.includes(fieldName)) {
query.field(fieldName);
}
}
if (settings.sort) {
const [sortField, sortDirection] = settings.sort[0];
if (FIELDS.includes(sortField)) {
query.order(sortField, sortDirection === 'asc');
}
}
if (settings.filters) {
if (settings.filters.search) {
const pattern = `%${settings.filters.search}%`;
query.where('name LIKE ? OR surname LIKE ?', pattern, pattern);
}
if (settings.filters.age) {
query.where('age = ?', settings.filters.age)
}
if (settings.filters.gender) {
query.where('gender = ?', settings.filters.gender)
}
}
const data = {};
const connection = await MySQLWrapper.getConnection();
try {
const mainQueryResult = await connection.query(query);
const secondQueryResult = await connection.query('SELECT FOUND_ROWS() as count');
data.records = mainQueryResult.map(elem => [elem.id, elem]);
data.count = secondQueryResult[0].count;
} finally {
connection.release();
}
return data;
}
// ...
module.exports = UserGridModel;
}
The read
method returns an object with two properties: records
and count
(the number of returned records).
Pay attention to this part:
data.records = mainQueryResult.map(elem => [elem.id, elem]);
The value of records
is an array consisting of arrays that store a record id as their first element and
a record as the second one.
For example:
[
[1, {id:1, name: "Sonya", surname: "Weaver", phone: "555-0159", age: 59, gender: 2}],
[2, {id:2, name: "Bates", surname: "Weaver", phone: "555-0144", age: 54, gender: 2}],
[3, {id:3, name: "Rodriguez", surname: "Terrell", phone: "555-0146", age: 40, gender: 1}]
]
Let’s define methods for validation:
class UserGridModel {
// ...
async isValidRecord(record) {
return await validator.isValidRecord(record);
}
async getValidationDependency(record) {
return await validator.getValidationDependency(record);
}
// ...
}
Next, we’ll define getRecord
:
class UserGridModel {
// ...
async getRecord(id, fields) {
const query = squel.select()
.from('records')
.where('id = ?', id);
for (const fieldName of fields) {
if (FIELDS.includes(fieldName)) {
query.field(fieldName);
}
}
const result = await MySQLWrapper.query(query);
return result[0];
}
// ...
}
The getRecord
method returns a single record.
Here’s the code for create
:
class UserGridModel {
// ...
async create(data) {
data = {
name: null,
surname: null,
phone: null,
age: null,
gender: null,
...data
};
const query = squel.insert()
.into('records');
for (const fieldName of FIELDS) {
if (data.hasOwnProperty(fieldName)) {
query.set(fieldName, data[fieldName]);
}
}
const validationResult = await this.isValidRecord(data);
if (!validationResult.isEmpty()) {
throw validationResult;
}
const queryResult = await MySQLWrapper.query(query);
return queryResult.insertId;
}
// ...
}
If data is valid, create
returns the id of the inserted record. Otherwise, it returns validation errors.
Let’s define the update
method:
class UserGridModel {
// ...
async update(records) {
const result = [];
for (const [recordId, record] of records) {
const query = squel.update()
.table('records')
.where('id = ?', recordId);
for (const fieldName of FIELDS) {
if (record.hasOwnProperty(fieldName)) {
query.set(fieldName, record[fieldName]);
}
}
const validationResult = await this.isValidRecord(record);
if (!validationResult.isEmpty()) {
result.push([recordId, validationResult]);
continue;
}
await MySQLWrapper.query(query);
result.push([recordId, record]);
}
return result;
}
// ...
}
This method returns validation errors and updated records. The return value format is the same as for the read
method.
Validation is used to highlight the form fields which were filled wrongly. Updated records are used for updating of the grid.
Finally, let’s define delete
:
class UserGridModel {
// ...
async delete(id) {
const query = squel.delete()
.from('records')
.where('id = ?', id);
return MySQLWrapper.query(query);
}
}
The return value of delete
can be different. It depends on the definition of this method in the client model.