mysql2.createPool() & Managed Database Cluster Limits. Should I use mysql2.createConnection() instead? - mysql

I've decided to start using mysql2 library lately and created the following example to illustrate what currently works.
A MySQL tempt table is created, a series of queries are run in parallel and then it terminates.
I then found this article MySQL Limits on Digital Ocean.
Specifically the bullet point referring to:
Connection pooling is not supported for MySQL.
My question is, should I use mysql.createConnection() instead of mysql.createPool()? I ask because, both of them work just fine.
// deno run --allow-env --allow-net todo.ts
import * as mysql2 from "https://deno.land/x/mysql2/mod.ts";
const pool = mysql2.createPool({
host: "db.ondigitalocean.com",
port: 12345,
user: "user1",
password: "letmein",
database: "devdb",
connectionLimit: 10,
timezone: "+00:00" // Development
// timezone: "-06:00" // Production
});
/* CREATE temp table tblTodos in database memory */
const sqlCREATE1: string =
`CREATE TEMPORARY TABLE IF NOT EXISTS tblTodos (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
userId BIGINT UNSIGNED DEFAULT NULL,
CHECK (userId >= 0),
todoCreated TIMESTAMP DEFAULT NULL,
todoModified TIMESTAMP DEFAULT NULL,
todoStatus VARCHAR(16) DEFAULT NULL,
todoTitle VARCHAR(128) DEFAULT NULL,
todoBody VARCHAR(1024) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE = INNODB
AUTO_INCREMENT=2001
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;`;
/* SELECT 1 shows an empty table */
const sqlSELECT1: string =
`SELECT
*
FROM
tblTodos;`;
/* INSERT 1 adds a Pending todo record to the table */
const sqlINSERT1: string =
`INSERT INTO tblTodos (
id, userId,
todoCreated, todoModified, todoStatus,
todoTitle, todoBody
)
VALUES
(
NULL, 1001,
NOW(), NOW(), 'Pending',
'Shopping List #1', 'Apples & Oranges'
);`;
/* SELECT 2 shows the Pending todo record */
const sqlSELECT2: string =
`SELECT
*
FROM
tblTodos
WHERE
todoStatus = 'Pending';`;
/* UPDATE 1 changes todo status from Pending to Complete */
const sqlUPDATE1: string =
`UPDATE
tblTodos
SET
todoModified = NOW(),
todoStatus = 'Complete'
WHERE
id = 2001
AND userId = 1001;`;
/* SELECT 3 shows the Complete todo record */
const sqlSELECT3: string =
`SELECT
*
FROM
tblTodos
WHERE
todoStatus = 'Complete'
AND userId = 1001;`;
/* DELETE 1 deletes todo from table */
const sqlDELETE1: string =
`DELETE FROM
tblTodos
WHERE
id = 2001
AND userId = 1001;`;
/* SELECT 4 once again shows an empty table */
const sqlSELECT4: string =
`SELECT
*
FROM
tblTodos;`;
/* DROP 1 deletes table tblTodos from database */
const sqlDROP1: string =
`DROP
TEMPORARY TABLE IF EXISTS tblTodos;`;
const connection = await pool.getConnection();
let create1Result, select1Result, insert1Result, select2Result,
update1Result, select3Result, delete1Result, select4Result,
drop1Result;
try {
create1Result = await connection.execute(sqlCREATE1);
if (create1Result) console.log("Table tblToDos created.");
select1Result = await connection.execute(sqlSELECT1);
if (select1Result) console.log("Table tblToDos contains", select1Result[0].length, "records.");
insert1Result = await connection.execute(sqlINSERT1);
if (insert1Result) console.log(insert1Result[0].affectedRows, "record(s) inserted.", "id:", insert1Result[0].insertId);
select2Result = await connection.execute(sqlSELECT2);
if (select2Result) console.log(select2Result[0]);
update1Result = await connection.execute(sqlUPDATE1);
if (update1Result) console.log(update1Result[0].affectedRows, "record(s) updated.");
select3Result = await connection.execute(sqlSELECT3);
if (select3Result) console.log(select3Result[0]);
delete1Result = await connection.execute(sqlDELETE1);
if (delete1Result) console.log(delete1Result[0].affectedRows, "record(s) deleted.");
select4Result = await connection.execute(sqlSELECT4);
if (select4Result) console.log("Table tblToDos contains", select1Result[0].length, "records.");
drop1Result = await connection.execute(sqlDROP1);
if (drop1Result) console.log("Table tblToDos droped.");
} catch(error) {
// Complete MySQL error message.
// console.log(`%cError: ${error.message}`, "color: #e53935");
// Build a smaller MySQL error message.
const errorPart1 = error.message.split(";")[0];
const errorPart2 = error.message.split(" use ")[1];
console.log(`%cError: ${errorPart1} ${errorPart2}`, "color: #e53935");
} finally {
connection.release();
}
// Debug created datetime
console.log(select3Result[0][0].todoCreated.toLocaleString());
// End pool when web server shuts down.
await pool.end();

Related

update a object second value as a object with JSON_SET in mysql apostrof problem

I hava a longtext type column in mysql and it is default value is like that :
{"aaaaa": [], "bbbbb": []}
when I want to update that column with :
const IamCreator = 1;
const myValue= [1,22,66,77]; //object
const query = `UPDATE 8users SET content = JSON_SET(content, '$.aaaaa', '?') WHERE id = ?`;
connection.query(query,[myValue,IamCreator],function (err, result, fields) {
console.log(err)
})
it give syntex problemand update value like that ;
{"aaaaa": "[1,22,66,77]", "bbbbb": []}
how can I solve that appostrof prolem?
I tried :
content = JSON_SET(content, '$.aaaaa', ?)
content = JSON_SET(content,'$.aaaaa', [?])
const query = `UPDATE table SET json_column = JSON_SET(json_column, '$.mykanban', ?) WHERE id = ?`; connection.query(query, [JSON.stringify(myValue), IamCreator]);
ı took syntex error all the time

Update the inserted record in ASP.NET Web API project

In my project I am inserting an employee and as my employee is inserted my save button HTML turns to update and on the back-end I am using the same insert function for updating the employee which I just inserted, my insert functionality is working perfectly but as I attempt to update the same record it inserts a new record in database instead of updating the data against the inserted ID, how do I update the existing or currently inserted user against their respective IDs.
I do not know why my update is not working and why I am not able to update right after inserting the user, every time I try to update the user I end up inserting the user again, and how should I restrict my application from inserting similar data again and again, the insert and update button are the same, as I mentioned above that on inserting the user I am changing the inner HTML of my button from save to update and using that same button to update
Here is my complete code, please let me know If I am making any mistakes at any part of my code, all the help I get from you guys is highly appreciated
My stored procedure code:
ALTER PROCEDURE [dbo].[InsEmpOfficialDetails]
(#EmpID int = NULL,
#UserName varchar(500) = NULL,
#pass varchar(500) = NULL,
#OfficialEmailAddress varchar(500) = NULL,
#Department varchar(500) = NULL,
#RoleID int = NULL,
#Role varchar(500) = NULL,
#IsAdmin bit = NULL,
#Designation varchar(500) = NULL,
#ReportToID int = NULL,
#ReportTo varchar(500) = NULL,
#JoiningDate datetime = NULL,
#IsPermanent bit = NULL,
#DateofPermanancy datetime = NULL,
#IsActive bit = NULL,
#HiredbyReference bit = NULL,
#HiredbyReferenceName varchar(500) = NULL,
#BasicSalary int = NULL,
#CurrentPicURL nvarchar(max) = NULL
-- #CreatedBy int,
-- #CreatedOn datetime,
-- #UpdatedOn datetime,
-- #UpdatedBy int
)
AS
BEGIN
IF EXISTS (SELECT 1 FROM Employee
WHERE UserName = #UserName
AND pass = #pass
AND OfficialEmailAddress = #OfficialEmailAddress
AND Department = #Department
AND RoleID = #RoleID
AND Role = #Role
AND IsAdmin = #IsAdmin
AND Designation = #Designation
AND ReportToID = #ReportToID
AND ReportTo = #ReportTo
AND JoiningDate = #JoiningDate
AND IsPermanent = #IsPermanent
AND DateofPermanancy = #DateofPermanancy
AND IsActive = #IsActive
AND HiredbyReference = #HiredbyReference
AND HiredbyReferenceName = HiredbyReferenceName
AND BasicSalary = #BasicSalary
AND CurrentPicURL = #CurrentPicURL)
BEGIN
UPDATE Employee
SET UserName = #UserName,
pass = #pass,
OfficialEmailAddress = #OfficialEmailAddress,
Department = #Department,
RoleID = #RoleID,
Role = #Role,
IsAdmin = #IsAdmin,
Designation = #Designation,
ReportToID = #ReportToID,
ReportTo = #ReportTo,
JoiningDate = #JoiningDate,
IsPermanent = #IsPermanent,
DateofPermanancy = #DateofPermanancy,
IsActive = #IsActive,
HiredbyReference = #HiredbyReference,
HiredbyReferenceName = HiredbyReferenceName,
BasicSalary = #BasicSalary,
CurrentPicURL = #CurrentPicURL
WHERE EmpID = #EmpID
END
ELSE
BEGIN
SET NOCOUNT ON;
INSERT INTO Employee(UserName, pass,
OfficialEmailAddress,Department,
RoleID, Role, IsAdmin, Designation,
ReportToID, ReportTo, JoiningDate,
IsPermanent, DateofPermanancy, IsActive,
HiredbyReference, HiredbyReferenceName,
BasicSalary, CurrentPicURL)
VALUES (#UserName, #pass, #OfficialEmailAddress, #Department,
#RoleID, #Role, #IsAdmin, #Designation,
#ReportToID, #ReportTo, #JoiningDate,
#IsPermanent, #DateofPermanancy, #IsActive,
#HiredbyReference, #HiredbyReferenceName,
#BasicSalary, #CurrentPicURL)
SELECT SCOPE_IDENTITY();
END
END
In my HTML on top of my input fields I am storing the currently inserted user ID in a hidden field like this
<input type="hidden" class="HiddenID" />
I do not know how to use this hidden field ID for updating the User right after inserting, because as I mentioned my insert and update functions both lies on same button
My ajax code:
$('.empOfficialDetails').click(function (ev) {
ev.preventDefault();
var data = new Object();
data.UserName = $('#username').val();
data.UPassword = $('#userpass').val();
data.OfficialEmailAddress = $('#officialemail').val();
data.Departments = $('#departments :selected').text();
data.Designation = $('#designation :selected').text();
data.RoleID = $('#role').val();
data.Role = $('#role :selected').text();
data.ReportToID = $('#reportToID').val();
data.ReportTo = $('#reportTo :selected').text();
data.JoiningDate = $('#joindate').val();
data.IsAdmin = $('#isAdmin :selected').val() ? 1 : 0;
data.IsActive = $('#isActive :selected').val() ? 1 : 0;
data.IsPermanent = $('#isPermanent :selected').val() ? 1 : 0;
data.DateofPermanancy = $('#permanantdate').val();
data.HiredbyReference = $('#hiredbyRef :selected').val() ? 1 : 0;
data.HiredbyReferenceName = $('#refePersonName').val();
data.BasicSalary = $('#basicSalary').val();
data.CurrentPicURL = $('.picture').val();
//data.CurrentPicURL = $('.picture')[0].files;
if (data.UserName && data.UPassword && data.OfficialEmailAddress && data.Departments && data.Designation && data.Role && data.IsAdmin && data.IsPermanent) {
$.ajax({
url: 'http://localhost:1089/api/Employee/EmpOfficialDetails',
type: "POST",
dataType: 'json',
contentType: "application/json",
data: JSON.stringify(data),
enctype: 'multipart/form-data',
beforeSend: function () {
$("#dvRoomsLoader").show();
},
complete: function () {
$("#dvRoomsLoader").hide();
},
success: function (data) {
var ID = parseInt(data);
if (ID > 0) {
//var id = data;
$(".HiddenID").val(data);
//var id = $(".HiddenID").val();
$('#official').css('display', 'block');
$('#official').html("Employees Official details added successfully...!");
$('#official').fadeOut(25000);
$("#dvRoomsLoader").show();
$('.empOfficialDetails').html("Update <i class='fa fa-angle-right rotate-icon'></i>");
}
else {
$('#official').find("alert alert-success").addClass("alert alert-danger").remove("alert alert-success");
}
},
error: function (ex) {
alert("There was an error while submitting employee data");
alert('Error' + ex.responseXML);
alert('Error' + ex.responseText);
alert('Error' + ex.responseJSON);
alert('Error' + ex.readyState);
alert('Error' + ex.statusText);
}
});
}
return false;
});
my controller code:
public int Emp_OfficialDetails(Employee emp)
{
//SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["AmanraHRMS"].ConnectionString);
var con = DB.getDatabaseConnection();
SqlCommand com = new SqlCommand("InsEmpOfficialDetails", con);
com.CommandType = CommandType.StoredProcedure;
#region Employee Official Details Insert Code block
com.Parameters.AddWithValue("#UserName", emp.UserName);
com.Parameters.AddWithValue("#pass", emp.UPassword);
com.Parameters.AddWithValue("#OfficialEmailAddress", emp.OfficialEmailAddress);
com.Parameters.AddWithValue("#Department", emp.Departments);
com.Parameters.AddWithValue("#Role", emp.Role);
com.Parameters.AddWithValue("#IsAdmin", Convert.ToBoolean(emp.IsAdmin));
com.Parameters.AddWithValue("#Designation", emp.Designation);
com.Parameters.AddWithValue("#ReportToID", emp.ReportToID);
com.Parameters.AddWithValue("#ReportTo", emp.ReportTo);
com.Parameters.AddWithValue("#JoiningDate", Convert.ToDateTime(emp.JoiningDate));
com.Parameters.AddWithValue("#IsPermanent", Convert.ToBoolean(emp.IsPermanent));
com.Parameters.AddWithValue("#DateofPermanancy", Convert.ToDateTime(emp.DateofPermanancy));
com.Parameters.AddWithValue("#IsActive", Convert.ToBoolean(emp.IsActive));
com.Parameters.AddWithValue("#HiredbyReference", Convert.ToBoolean(emp.HiredbyReference));
com.Parameters.AddWithValue("#HiredbyReferenceName", emp.HiredbyReferenceName);
com.Parameters.AddWithValue("#BasicSalary", emp.BasicSalary);
com.Parameters.AddWithValue("#CurrentPicURL", emp.CurrentPicURL);
#endregion
//var file = emp.CurrentPicURL;
//EmployeeImage(file);
var ID = com.ExecuteScalar();
com.Clone();
return Convert.ToInt32(ID);
}
//Ajax call hit this method from AddEmployee page
[Route("api/Employee/EmpOfficialDetails")]
[HttpPost]
public int? EmpOfficialDetails(Employee emp)
{
IHttpActionResult ret;
try
{
var id = Emp_OfficialDetails(emp);
return id;
}
catch (Exception ex)
{
ret = InternalServerError(ex);
}
return null;
}
fix your hidden field
<input type="hidden" asp-for ="EmpID" id="empId" class="HiddenID" value="#Model.EmpID />
fix your stored procedure. for exist would be enough EmpID, too many parameters can give the wrong result
BEGIN
IF EXISTS (SELECT 1 FROM Employee
WHERE EmpID = #EmpID)
BEGIN
UPDATE Employee
SET UserName = #UserName,
.....
and the most important add EmpId to ajax
var data = new Object();
data.EmpID = $('#empId').val();
and action command
com.Parameters.AddWithValue("#EmpID", emp.EmpID);

AWS Aurora DB Combine Data from Multiple SQL Statements

I have three tables with data schema, like:
TABLE user (
user_id BINARY(16) PRIMARY KEY NOT NULL,
created DATETIME NOT NULL,
last_updated DATETIME,
coordinator BINARY(16),
num_updates INT NOT NULL
);
TABLE summary (
user_id BINARY(16) PRIMARY KEY NOT NULL,
calculation_time DATETIME NOT NULL,
calculation_method VARCHAR(25) NOT NULL,
label VARCHAR(50) NOT NULL,
critical_count INT NOT NULL,
median_risk FLOAT(10)
);
TABLE actions(
user_id BINARY(16) PRIMARY KEY NOT NULL,
label VARCHAR(50) NOT NULL,
access_count INT NOT NULL,
median FLOAT(10)
);
The data for all the users (user table) is simply fetched using the lambda handler function in the following manner:
const AWS = require('aws-sdk');
const rdsDataService = new AWS.RDSDataService();
module.exports.hello = async (event, context, callback) => {
const req_id = "5a9dbfca-74d6-471a-af27-31beb4b53bb2";
const sql = 'SELECT * FROM user WHERE user_id=:id';
try {
const params = {
resourceArn: 'arn:aws:rds:us-west-********************',
secretArn: 'arn:aws:secretsmanager:us-west**************',
sql,
database: 'dev_db1',
continueAfterTimeout: true,
includeResultMetadata: true,
parameters: [{ 'name': 'id', 'value': { 'stringValue': `${req_id}` } }]
}
const db_res = await rdsDataService.executeStatement(params).promise();
const convertToJson = (dbresponse) => {
const columns = dbresponse.columnMetadata.map(col => col.name);
const row_data = dbresponse.records.map(row => {
const json_obj = {};
row.map((val, i) => {
json_obj[columns[i]] = Object.values(val)[0];
});
return json_obj;
});
return row_data;
};
const modified_data = convertToJson(db_res);
const response = {
body: {
statusCode: 200,
message: 'Data fetched successfully',
data: modified_data,
}
};
callback(null, response);
} catch (error) {
console.log('Error Received', error);
const error_res = {
body: {
statusCode: error.statusCode,
message: error.message,
data: null
}
}
callback(null, error_res);
}
};
If the same is followed for another table summary or actions, it also works. Now, I need to combine all the columns of these three tables and then return the data (returned rows should match on the basis of req_id).
My working snippet: https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=016ecc94c792611fbaca810605e81a6a
But the final result obtained contains the column user_id in duplicated form i.e. three times inclusion. I don't need the same column to be repeated thrice.
I am a bit new to handling MySQL queries, so unable to figure out the exact reason for the error even when the table exists. The MYSQL version used in Aurora is 5.7.
Any help to resolve the same is appreciated!
Plan A: Explicitly specify the columns you want. Extra benefit: You can get rid of the ids, which tend to be useless to others reading the output.
Plan B: (This option is not always possible.) Instead of JOIN .. ON t1.a = t2.a, say JOIN .. USING(a)
I like to use short aliases. Here's doing all things together:
SELECT u.last_name, u.first_name,
s.risk_score,
t.likes
FROM user AS u
JOIN summary AS s USING(user_id)
LEFT JOIN test AS t USING(user_id)
In general, it is not wise to have a 1:1 relationship (as you have via user_id); you may as well have all the columns in a single table.
try this
SELECT users.*, summary.* from users, summary WHERE users.user_id = summary.user_id
OR
SELECT * from users, summary WHERE users.user_id = summary.user_id

Records not inserting - mySql Node

The Task
I am trying read all the records from one table, and insert them into another table. I will re-use these functions later on in the app.
The Problem
The data doesn't appear to be being passed correctly. I am not getting any errors, yet the records are not inserted.
I debugged the data variable, and all the records are consoled correctly. For some reason, I am losing them when I call my insertData function.
Note: My table name is results, which may be a little confusing. I may change that in the future.
Entire Source Code
var mysql = require('mysql');
var connection = mysql.createConnection({
host: "localhost",
user: "root",
password: "",
database: "marketplace"
});
connection.connect(function (err) {
if (err) throw err;
console.log("Connected!");
})
const getData = function (tblName) {
var data = {};
switch (tblName) {
case "results":
sql = "SELECT * FROM results";
break;
case "items":
sql = "SELECT * FROM items";
break;
default:
sql = "SELECT * FROM results";
break;
}
return new Promise(resolve => {
connection.query(sql, function (err, results) {
if (err) {
console.log(err);
} else {
data.numResults = results.length;
data.data = results;
resolve(data);
}
})
})
}
const insertData = function (tbl, entity) {
return new Promise(resolve => {
var sql = `INSERT INTO ${tbl} (title,price,location,miles,imgUrl,itemURL) VALUES ?`;
var insertedIds = [];
for (var i = 0; i < entity.length; i++) {
connection.query(sql, entity[i], function (err, res) {
if (err) throw err;
insertedIds.push(res.insertId);
});
}
resolve(insertedIds);
})
}
const init = async function () {
var data = await getData("items");
console.log(data); // Works. Display all data
var insertSuccess = await insertData("results", data);
}
init();
Data Structure
{
id: 251,
title: '2008 Jeep Wrangler Unlimited Sahara Sport Utility 4D',
price: '$10,500',
location: 'Lake Sarasota, Florida',
miles: '123K miles',
itemURL: '/marketplace/item/174406817245706/',
imgUrl: 'https://scontent-mia3-1.xx.fbcdn.net/v/t1.0-0/c43.0.260.260a/p261x260/98434536_3577078698974198_8432375958719168512_n.jpg?_nc_cat=111&_nc_sid=843cd7&_nc_oc=AQlLn3CVPZmD4dKSsfXd-rV0WxXBo98zneuGAEgz2JP2yWrkt5rxI-fa1ShTtMGYbrw&_nc_ht=scontent-mia3-1.xx&oh=89e552882baeb14c642a1cd28b8ba683&oe=5EEA3991',
seen: 0,
created_date: 2020-05-20T20:45:24.000Z
}
Schema
DROP TABLE IF EXISTS `results`;
CREATE TABLE IF NOT EXISTS `results` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`price` varchar(255) DEFAULT NULL,
`location` varchar(255) DEFAULT NULL,
`miles` varchar(22) DEFAULT 'unavailable',
`itemURL` text,
`imgUrl` text,
`created_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=612 DEFAULT CHARSET=latin1;
COMMIT;
Output
When I try to console.log the insertSuccess variable, which should show me a list of inserted id's:
.
.
.
console.log(insertSuccess);

Insert into two dependent tables in MySQL with node.js

I am new to MySQL and node.js (as well as the callback). I try to insert data into table B, which depends on data in table A. Here is an example.
employee table (table A):
CREATE TABLE employees (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(50),
location varchar(50),
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
age table (table B, I do not include age column in table A on purpose):
CREATE TABLE age (
id int(11) NOT NULL AUTO_INCREMENT,
index_id int(11),
age int(50),
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
The problem:
For each row inserted into table A, I can get the id for it. I want to use the id as the index_id in table B, and insert the corresponding age info into age table B. The problem occurs when I have multiple rows to insert.
The example:
I implement the following function to achieve above goal.
var mysql = require("mysql");
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "root",
database: "sitepoint"
});
function insert_employees() {
var employees = [
{name: 'Jasmine', location: 'Australia', age: 24},
{name: 'Jay', location: 'India', age: 25},
{name: 'Jim', location: 'Germany', age: 26},
{name: 'Lesley', location: 'Scotland', age: 27}
];
var name_id;
for (var i = 0; i < 4; i++) {
var employee = employees[i];
var command = sprintf('INSERT INTO employees (name, location) VALUES ("%s", "%s");', employee.name, employee.location);
con.query(command, function (err, res) {
if (err) throw err;
name_id = res.insertId;
console.log('Last insert ID in employees:', res.insertID);
// insert age here
var age = employee.age;
var command = sprintf('INSERT INTO age (index_id, age) VALUES (%d, %d);', name_id, age);
con.query(command, function (err, res) {
if (err) throw err;
});
});
}
}
The Output:
The employee table is fine, but for the age table, the age column is 27 for all fields, instead of 24, 25, 26, 27
The Question:
I think the problem is on my misuse of callback feature, but I still don't know how to solve it. Could anyone help me with it? Thanks a lot!
var employee = employees[i];
Change the above line to below, so that variable employee has the correct scope:
let employee = employees[i];
Add the following to the beginning of your script, so that let works:
'use strict';