Error-Handling

This commit is contained in:
Sam 2024-12-07 02:42:25 +01:00
parent fc19ac2672
commit a5aacf2f14
8 changed files with 267 additions and 31 deletions

View File

@ -1,9 +1,12 @@
"use strict"
const mysql = require("mysql");
const Select = require("./lib/Select");
const Insert = require("./lib/Insert");
const Delete = require("./lib/Delete");
const Update = require("./lib/Update");
const { CreateTable, Structure, AlterTable } = require("./lib/Tables");
const { throwTypeError } = require("./lib/Errors");
/**
* @typedef {Object} InstanceOptions
@ -38,6 +41,8 @@ class awSQL {
customIdentifier: false,
isDefault: false,
}){
if (!password) throw new Error(`Can't create instance: No password given`);
if (!username) throw new Error(`Can't create instance: No username given`);
const identifier = options.customIdentifier||`${username}@${hostname}`; // Set identifier to given identifier or [username]@[hostname]
// If an instance with that identifier exists, throw error
if (this.#instances[identifier]) throw new Error(`Can't create new instance with identifier "${identifier}": An instance with the same name already exists`);
@ -57,11 +62,12 @@ class awSQL {
getInstance(identifier) {
if (Object.keys(this.#instances).length===0) return undefined; // If no instance is found at all return -> Safety return
// If no identifier is set return default or first instance
if (!identifier) return
this.#default?
if (!identifier) {
return this.#default?
this.#instances[this.#default] // If default exists get that
:
this.#instances[Object.keys(this.#instances)[0]]; // Otherwise get instance with that identifier
this.#instances[Object.keys(this.#instances)[0]]; // Otherwise return first instance
}
return this.#instances[identifier]; // If identifier given return that instance
}
@ -80,6 +86,7 @@ class awSQL {
*/
deleteInstance(identifier){
if (!identifier) throw new Error("Can't delete Instance: No identifier set");
if (typeof identifier !== "string") throwTypeError("string", identifier);
if (!this.#instances[identifier]) throw new Error(`Can't delete Instance '${identifier}': No Instance`);
this.#instances[identifier].destroy(); // Memory: Close connection
if (this.#default === identifier) this.#default = undefined; // If this instance was default, clear it from default
@ -156,8 +163,11 @@ class Instance {
* @param {Array<Any>} values - An array holding all replacable ?-values from left to right.
* @returns {Any} - The individual result of your query
*/
queryRaw(queryString, values){
return new Promise((resolve, reject) => {
queryRaw(queryString, values=[]){
if (!queryString) throw new Error(`queryString must not be empty`);
if (typeof queryString !== "string") throwTypeError("string", queryString);
if (!Array.isArray(values)) throwTypeError("array", values);
return new Promise((resolve) => {
if (!this.#connection) throw new Error("Querying failed: No connection");
this.#connection.query(queryString, values, (err, result) => {
if (err) throw err;
@ -172,6 +182,7 @@ class Instance {
* @returns {Array<String>}
*/
async getDatabases (excludeSchema=false){
if (typeof excludeSchema !== "boolean") throwTypeError("boolean", excludeSchema);
let dbs = await this.queryRaw("SHOW DATABASES;");
if (excludeSchema) dbs = dbs.filter((db)=>db.Database!=="information_schema")
return dbs.map(db => db.Database);
@ -183,6 +194,8 @@ class Instance {
* @returns {this}
*/
selectDatabase(name){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
this.#selectedDatabase = name;
return this;
}
@ -207,6 +220,8 @@ class Instance {
* @returns {Select}
*/
select(from, ...columns){
if (!from) throw new Error("Can't prepare select: No 'from' given");
if (typeof from !== "string") throwTypeError("string", from);
return new Select(this, this.#selectedDatabase, from, columns);
}
@ -217,6 +232,8 @@ class Instance {
* @returns {Insert}
*/
insert(into){
if (!into) throw new Error("Can't prepare insert: No 'into' given");
if (typeof into !== "string") throwTypeError("string", into);
return new Insert(this, this.#selectedDatabase, into);
}
@ -226,6 +243,8 @@ class Instance {
* @returns {Delete}
*/
delete(from){
if (!from) throw new Error("Can't prepare delete: No 'from' given");
if (typeof from !== "string") throwTypeError("string", from);
return new Delete(this, this.#selectedDatabase, from);
}
@ -235,6 +254,8 @@ class Instance {
* @returns {Update}
*/
update(table){
if (!table) throw new Error("Can't prepare update: No 'table' given");
if (typeof table !== "string") throwTypeError("string", table);
return new Update(this, this.#selectedDatabase, table);
}
@ -245,6 +266,8 @@ class Instance {
* @returns {Any}
*/
async dropDatabase (database){
if (!database) throw new Error(`Can't drop database: No database given`);
if (typeof database !== "string") throwTypeError("string", database);
return await this.queryRaw(`DROP DATABASE ${database};`);
}
@ -254,6 +277,8 @@ class Instance {
* @returns {Any}
*/
async dropTable(table){
if (!table) throw new Error("Can't drop table: No table set");
if (typeof table !== "string") throwTypeError("string", table);
if (!this.#selectedDatabase) throw new Error(`Can't drop table '${table}': Database not set`);
return await this.queryRaw(`DROP TABLE ${this.#selectedDatabase}.${table}`);
}
@ -265,6 +290,8 @@ class Instance {
* @returns {Any}
*/
async createDatabase(name){
if (!name) throw new Error(`Can't create database: No name given`);
if (typeof name !== "string") throwTypeError("string", name);
return await this.queryRaw(`CREATE DATABASE ${name};`);
}
@ -274,6 +301,8 @@ class Instance {
* @returns {CreateTable}
*/
createTable(name){
if (!name) throw new Error("Can't create table: No name given");
if (typeof name !== "string") throwTypeError("string", name);
return new CreateTable(this, this.#selectedDatabase, name);
}
@ -284,6 +313,8 @@ class Instance {
* @returns {AlterTable}
*/
alterTable(name){
if (!name) throw new Error("Can't alter table: No name given");
if (typeof name !== "string") throwTypeError("string", name);
return new AlterTable(this, this.#selectedDatabase, name);
}
@ -302,6 +333,8 @@ class Instance {
* @returns {Structure}
*/
async getStructure(table, database){
if (!table) throw new Error("Can't get structure: table not given");
if (typeof table !== "string") throwTypeError("string", table);
if (!this.#selectedDatabase && !database) throw new Error(`Can't get structure of table ${table}: Database not selected`);
return new Structure(await this.queryRaw(`DESCRIBE ${database||this.#selectedDatabase}.${table};`));
}
@ -314,6 +347,9 @@ class Instance {
* @returns {CheckResult}
*/
async checkStructure(table, desiredStructure, database){
if (!table) throw new Error("Can't check structure: table not given");
if (typeof table !== "string") throwTypeError("string", table);
if (typeof desiredStructure !== "function") throwTypeError("function", desiredStructure);
if (!this.#selectedDatabase && !database) throw new Error(`Can't get structure of table ${table}: Database not selected`);
const dbStruc = (await this.getStructure(table, database||this.#selectedDatabase)).get(); // Get current structure -> Array<Objects>
const result = {
@ -351,6 +387,9 @@ class Instance {
* @returns {Any}
*/
async total(table){
if (!table) throw new Error("Can't get structure: table not given");
if (typeof table !== "string") throwTypeError("string", table);
if (!this.#selectedDatabase) throw new Error("Can't get total: No default table set");
return await new Select(this, this.#selectedDatabase, table).count(true).execute();
}
@ -371,7 +410,7 @@ class Instance {
*/
const awSQLInstance = new awSQL();
module.exports = {awSQLInstance, Structure};
module.exports = {awSQL: awSQLInstance, Structure};
/**
* @exports awSQLInstance

View File

@ -1,3 +1,5 @@
const { throwTypeError } = require("./Errors");
/**
* Prepares a new Deletion
*/
@ -23,6 +25,8 @@ class Delete {
* @returns {this}
*/
selectDatabase(database){
if (!database) throw new Error("database must not be empty");
if (typeof database !== "string") throwTypeError("string", database);
this.#database = database;
return this;
}
@ -35,6 +39,9 @@ class Delete {
* @returns {this}
*/
where(string, values=[]){
if (!string) throw new Error("string must not be empty");
if (typeof string !== "string") throwTypeError("string", string);
if (!Array.isArray(values)) throwTypeError("array", values);
this.#where = string;
this.#whereValues = values;
return this;

15
lib/Errors.js Normal file
View File

@ -0,0 +1,15 @@
function throwTypeError(e, r){
throw new TypeError(`Expected '${e}'. Received ${r}`);
}
function throwRangeError(min,max,r){
throw new RangeError(`The argument must be between ${min} and ${max}. Received ${r}`);
}
function throwEnumError(e=[],r){
throw new RangeError(`The argument must be one of [${e.join(",")}]. Received '${r}'`);
}
module.exports = {throwTypeError, throwRangeError, throwEnumError};

View File

@ -1,3 +1,5 @@
const { throwTypeError } = require("./Errors");
/**
* Prepares a new insertion
*/
@ -20,6 +22,8 @@ class Insert {
* @returns {this}
*/
selectDatabase(database){
if (!database) throw new Error("database must not be empty");
if (typeof database !== "string") throwTypeError("string", database);
this.#database = database;
return this;
}
@ -29,7 +33,9 @@ class Insert {
* @param {Array<Object>} objects - Array containing objects to insert, where the key represents the column-name. All objects must have the same structure!
* @returns {this}
*/
data(objects){
data(objects=[]){
if (!Array.isArray(objects)) throwTypeError("array", objects);
if (objects.length===0) throw new Error("data objects must not be empty");
this.#data = objects;
return this;
}

View File

@ -1,3 +1,4 @@
const { throwTypeError, throwEnumError } = require("./Errors");
/**
* Prepares a new Selection
@ -37,6 +38,8 @@ class Select {
* @returns {this}
*/
selectDatabase(database){
if (!database) throw new Error("database must not be empty");
if (typeof database !== "string") throwTypeError("string", database);
this.#database = database;
return this;
}
@ -61,6 +64,9 @@ class Select {
* @returns {this}
*/
where(string, values=[]){
if (!string) throw new Error("string must not be empty");
if (typeof string !== "string") throwTypeError("string", string);
if (!Array.isArray(values)) throwTypeError("array", values);
this.#where = string;
this.#whereValues = values;
return this;
@ -75,6 +81,9 @@ class Select {
* @returns {this}
*/
having(string, values = []){
if (!string) throw new Error("string must not be empty");
if (typeof string !== "string") throwTypeError("string", string);
if (!Array.isArray(values)) throwTypeError("array", values);
this.#having = string;
this.#havingValues = values;
return this;
@ -89,7 +98,14 @@ class Select {
* @returns {this}
*/
order(column, desc=false, aggregation){
if (["MIN", "MAX", "COUNT", "SUM", "AVG"].includes(aggregation)){
if (!column) throw new Error("column must not be empty");
if (typeof column !== "string") throwTypeError("string", column);
if (typeof desc !== "boolean") throwTypeError("boolean", desc);
const POSSIBLE_AGGREGATION = ["MIN", "MAX", "COUNT", "SUM", "AVG"];
if (aggregation && POSSIBLE_AGGREGATION.includes(aggregation)){
throwEnumError(POSSIBLE_AGGREGATION, aggregation);
}
if (POSSIBLE_AGGREGATION.includes(aggregation)){
switch(aggregation){
case "MIN":
column = `MIN(${column})`;
@ -122,6 +138,7 @@ class Select {
* @returns {this}
*/
count(doParse=false){
if (typeof doParse !== "boolean") throwTypeError("boolean", doParse);
this.#aggregator = "COUNT";
this.#aggregatorParse = doParse;
return this;
@ -133,6 +150,7 @@ class Select {
* @returns {this}
*/
sum(doParse=false){
if (typeof doParse !== "boolean") throwTypeError("boolean", doParse);
this.#aggregator ="SUM";
this.#aggregatorParse = doParse;
return this;
@ -144,6 +162,7 @@ class Select {
* @returns {this}
*/
avg(doParse=false){
if (typeof doParse !== "boolean") throwTypeError("boolean", doParse);
this.#aggregator = "AVG";
this.#aggregatorParse = doParse;
return this;
@ -155,6 +174,7 @@ class Select {
* @returns {this}
*/
group(...columns){
if (columns.length===0) throw new Error("Arguments must not be empty");
this.#group = columns;
return this;
}
@ -169,6 +189,15 @@ class Select {
* @returns {this}
*/
join(type, table, onOriginalColumn, onJoinedColumn, ...columns){
const POSSIBLE_TYPES = ["LEFT", "INNER", "RIGHT", "FULL OUTER"];
if (!POSSIBLE_TYPES.includes(type)) throwEnumError(POSSIBLE_TYPES, type);
if (!table) throw new Error("table must not be empty");
if (typeof table !== "string") throwTypeError("string", table);
if (!onOriginalColumn) throw new Error("onOriginalColumn must not be empty");
if (typeof onOriginalColumn !== "string") throwTypeError("string", onOriginalColumn);
if (!onJoinedColumn) throw new Error("onOriginalColumn must not be empty");
if (typeof onJoinedColumn !== "string") throwTypeError("string", onJoinedColumn);
if (columns.length===0) throw new Error("columns must not be empty");
this.#joins.push({
type,
on: `%%FROM%%.${onOriginalColumn}=${table}.${onJoinedColumn}`,
@ -185,6 +214,10 @@ class Select {
* @returns {this}
*/
limit(number, offset){
if (!number) throw new Error("number must not be empty");
if (typeof number !== "number") throwTypeError("number", number);
if (!offset) throw new Error("offset must not be empty");
if (typeof offset !== "number") throwTypeError("number", offset);
this.#limit = {
number,
offset
@ -199,6 +232,10 @@ class Select {
* @returns {this}
*/
pagination(page, itemsPerPage){
if (!page) throw new Error("page must not be empty");
if (typeof page !== "number") throwTypeError("number", page);
if (!itemsPerPage) throw new Error("itemsPerPage must not be empty");
if (typeof itemsPerPage !== "number") throwTypeError("number", itemsPerPage);
if (page<1) page=1;
this.#limit = {
number: itemsPerPage,

View File

@ -1,3 +1,4 @@
const { throwTypeError, throwRangeError } = require("./Errors");
/**
@ -20,6 +21,8 @@ class AlterTable {
* @returns {this}
*/
selectDatabase(database){
if (!database) throw new Error("database must not be empty");
if (typeof database !== "string") throwTypeError("string", database);
this.#database = database;
return this;
}
@ -33,6 +36,8 @@ class AlterTable {
* @returns {this}
*/
structure(struc){
if (!struc) throw new Error("struc must not be empty");
if (typeof struc !== "function") throwTypeError("function", struc);
this.#structure = struc;
return this;
}
@ -135,6 +140,8 @@ class CreateTable {
* @returns {this}
*/
selectDatabase(database){
if (!database) throw new Error("database must not be empty");
if (typeof database !== "string") throwTypeError("string", database);
this.#database = database;
return this;
}
@ -145,6 +152,8 @@ class CreateTable {
* @returns {this}
*/
name(name){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
this.#name = name;
return this;
}
@ -155,6 +164,8 @@ class CreateTable {
* @returns {this}
*/
structure(struc){
if (!struc) throw new Error("struc must not be empty");
if (typeof struc !== "function") throwTypeError("function", struc);
this.#structure = struc;
return this;
}
@ -207,6 +218,8 @@ class Structure {
* @returns {this}
*/
drop(name){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
let index;
for (let i = 0; i < this.#columns.length; i++){
if (this.#columns[i].Field === name) {
@ -233,9 +246,13 @@ class Structure {
* @param {ConstraintOptions} [options] - Extra constraint options
* @returns {this}
*/
char(name, size=1, options){
char(name, size=1, options={}){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof size !== "number") throwTypeError("number", size);
if (typeof options !== "object") throwTypeError("object", options);
if (size < 0 || size > 255){
throw new Error(`Column datatype 'char' size must be a number between 0 and 255. Received: ${size}`);
throwRangeError(0, 255, size);
}
this.#columns.push(parseColumnData(name, `char(${size})`, options));
return this;
@ -249,8 +266,12 @@ class Structure {
* @returns {this}
*/
varchar(name, size=8, options){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof size !== "number") throwTypeError("number", size);
if (typeof options !== "object") throwTypeError("object", options);
if (size < 0 || size > 255){
throw new Error(`Column datatype 'varchar' size must be a number between 0 and 65535. Received: ${size}`);
throwRangeError(0, 255, size);
}
this.#columns.push(parseColumnData(name, `varchar(${size})`, options));
return this;
@ -264,8 +285,12 @@ class Structure {
* @returns {this}
*/
binary(name, size=1, options){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof size !== "number") throwTypeError("number", size);
if (typeof options !== "object") throwTypeError("object", options);
if (size < 1){
throw new Error(`Column datatype 'binary' size must be a number above 0. Received: ${size}`);
throwRangeError(1, "*", size);
}
this.#columns.push(parseColumnData(name, `binary(${size})`, options));
return this;
@ -279,8 +304,12 @@ class Structure {
* @returns {this}
*/
varbinary(name, size=1, options){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof size !== "number") throwTypeError("number", size);
if (typeof options !== "object") throwTypeError("object", options);
if (size < 1){
throw new Error(`Column datatype 'varbinary' size must be a number above 0. Received: ${size}`);
throwRangeError(1, "*", size);
}
this.#columns.push(parseColumnData(name, `varbinary(${size})`, options));
@ -294,6 +323,9 @@ class Structure {
* @returns {this}
*/
tinyblob(name, options){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof options !== "object") throwTypeError("object", options);
this.#columns.push(parseColumnData(name, `tinyblob`, options));
return this;
}
@ -305,6 +337,9 @@ class Structure {
* @returns {this}
*/
tinytext(name, options){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof options !== "object") throwTypeError("object", options);
this.#columns.push(parseColumnData(name, `tinytext`, options));
return this;
}
@ -316,6 +351,9 @@ class Structure {
* @returns {this}
*/
text(name, options){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof options !== "object") throwTypeError("object", options);
this.#columns.push(parseColumnData(name, `text`, options));
return this;
}
@ -328,7 +366,11 @@ class Structure {
* @returns {this}
*/
blob(name, size=65535, options){
if (size < 1 || size > 65535) throw new Error(`Column datatype 'blob' size must be a number between 1 and 65535. Received: ${size}`);
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof size !== "number") throwTypeError("number", size);
if (typeof options !== "object") throwTypeError("object", options);
if (size < 1 || size > 65535) throwRangeError(1, 65535, size);
this.#columns.push(parseColumnData(name, `blob(${size})`, options));
return this;
}
@ -340,6 +382,9 @@ class Structure {
* @returns {this}
*/
mediumtext(name, options){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof options !== "object") throwTypeError("object", options);
this.#columns.push(parseColumnData(name, `mediumtext`, options));
return this;
}
@ -351,6 +396,9 @@ class Structure {
* @returns {this}
*/
longtext(name, options){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof options !== "object") throwTypeError("object", options);
this.#columns.push(parseColumnData(name, `longtext`, options));
return this;
}
@ -362,6 +410,9 @@ class Structure {
* @returns {this}
*/
longblob(name, options){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof options !== "object") throwTypeError("object", options);
this.#columns.push(parseColumnData(name, `longblob`, options));
return this;
}
@ -374,6 +425,11 @@ class Structure {
* @returns {this}
*/
enum(name, vals=[], options){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (!Array.isArray(vals)) throwTypeError("array", vals);
if (vals.length===0) throw new Error("vals must not be empty");
if (typeof options !== "object") throwTypeError("object", options);
if (!Array.isArray(vals)) throw new Error(`Column datatype 'enum': 'vals' must be of type Array`);
if (vals.length<=0) throw new Error(`Column datatype 'enum' must contain a list of possible values. Received undefined`);
this.#columns.push(parseColumnData(name, `enum(${vals.map(val=>`'${val}'`)})`, options));
@ -388,6 +444,11 @@ class Structure {
* @returns {this}
*/
set(name, vals=[], options){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (!Array.isArray(vals)) throwTypeError("array", vals);
if (vals.length===0) throw new Error("vals must not be empty");
if (typeof options !== "object") throwTypeError("object", options);
if (!Array.isArray(vals)) throw new Error(`Column datatype 'set': 'vals' must be of type Array`);
if (vals.length<=0) throw new Error(`Column datatype 'set' must contain a list of possible values. Received undefined`);
this.#columns.push(parseColumnData(name, `set(${vals.map(val=>`'${val}'`)})`, options));
@ -402,7 +463,11 @@ class Structure {
* @returns {this}
*/
bit(name, size=1, options){
if (size < 1 || size > 64) throw new Error(`Column datatype 'bit' size must be a number between 1 and 64. Received: ${size}`);
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof size !== "number") throwTypeError("number", size);
if (typeof options !== "object") throwTypeError("object", options);
if (size < 1 || size > 64) throwRangeError(1, 64, size);
this.#columns.push(parseColumnData(name, `bit(${size})`, options));
return this;
}
@ -415,7 +480,11 @@ class Structure {
* @returns {this}
*/
tinyint(name, size=255, options){
if (size < 1 || size > 255) throw new Error(`Column datatype 'tinyint' size must be a number between 1 and 255. Received: ${size}`);
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof size !== "number") throwTypeError("number", size);
if (typeof options !== "object") throwTypeError("object", options);
if (size < 1 || size > 255) throwRangeError(1, 255, size);
this.#columns.push(parseColumnData(name, `tinyint(${size})`, options));
return this;
@ -428,6 +497,9 @@ class Structure {
* @returns {this}
*/
bool(name, options){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof options !== "object") throwTypeError("object", options);
this.#columns.push(parseColumnData(name, `bool`, options));
return this;
}
@ -440,7 +512,10 @@ class Structure {
* @returns {this}
*/
smallint(name, size=255, options){
if (size < 1 || size > 255) throw new Error(`Column datatype 'smallint' size must be a number between 1 and 255. Received: ${size}`);
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof options !== "object") throwTypeError("object", options);
if (size < 1 || size > 255) throwRangeError(1, 255, size);
this.#columns.push(parseColumnData(name, `smallint(${size})`, options));
return this;
}
@ -453,7 +528,11 @@ class Structure {
* @returns {this}
*/
mediumint(name, size=255, options){
if (size < 1 || size > 255) throw new Error(`Column datatype 'mediumint' size must be a number between 1 and 255. Received: ${size}`);
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof size !== "number") throwTypeError("number", size);
if (typeof options !== "object") throwTypeError("object", options);
if (size < 1 || size > 255) throwRangeError(1, 255, size);
this.#columns.push(parseColumnData(name, `mediumint(${size})`, options));
return this;
}
@ -466,7 +545,11 @@ class Structure {
* @returns {this}
*/
int(name, size=255, options){
if (size < 1 || size > 255) throw new Error(`Column datatype 'int' size must be a number between 1 and 255. Received: ${size}`);
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof size !== "number") throwTypeError("number", size);
if (typeof options !== "object") throwTypeError("object", options);
if (size < 1 || size > 255) throwRangeError(1, 255, size);
this.#columns.push(parseColumnData(name, `int(${size})`, options));
return this;
}
@ -479,7 +562,11 @@ class Structure {
* @returns {this}
*/
bigint(name, size=255, options){
if (size < 1 || size > 255) throw new Error(`Column datatype 'bigint' size must be a number between 1 and 255. Received: ${size}`);
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof size !== "number") throwTypeError("number", size);
if (typeof options !== "object") throwTypeError("object", options);
if (size < 1 || size > 255) throwRangeError(1, 255, size);
this.#columns.push(parseColumnData(name, `bigint(${size})`, options));
return this;
}
@ -492,7 +579,11 @@ class Structure {
* @returns {this}
*/
float(name, p=25, options){
if (p < 1 || p > 53) throw new Error(`Column datatype 'float' size must be a number between 1 and 53. Received: ${p}`);
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof p !== "number") throwTypeError("number", p);
if (typeof options !== "object") throwTypeError("object", options);
if (p < 1 || p > 53) throwRangeError(1, 53, p);
this.#columns.push(parseColumnData(name, `float(${p})`, options));
return this;
@ -507,8 +598,13 @@ class Structure {
* @returns {this}
*/
double(name, size=16, d=8, options){
if (size < 1) throw new Error(`Column datatype 'double' size must be greater than 0. Received: ${p}`);
if (d < 1) throw new Error(`Column datatype 'double' d must be greater than 0. Received: ${p}`);
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof size !== "number") throwTypeError("number", size);
if (typeof d !== "number") throwTypeError("number", d);
if (typeof options !== "object") throwTypeError("object", options);
if (size < 1) throwRangeError(1, "*", size);
if (d < 1) throwRangeError(1, "*", d);
this.#columns.push(parseColumnData(name, `double(${size},${d})`, options));
return this;
}
@ -522,8 +618,13 @@ class Structure {
* @returns {this}
*/
decimal(name, size=10, d=0, options){
if (size < 1 || size > 65) throw new Error(`Column datatype 'decimal' size must be a number between 1 and 65. Received: ${size}`);
if (d < 0) throw new Error(`Column datatype 'decimal' d must be positive. Received: ${d}`);
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof size !== "number") throwTypeError("number", size);
if (typeof d !== "number") throwTypeError("number", d);
if (typeof options !== "object") throwTypeError("object", options);
if (size < 1 || size > 65) throwRangeError(1, 65, size);
if (d < 0) throwRangeError(0, "*", d);
this.#columns.push(parseColumnData(name, `decimal(${size},${d})`, options));
return this;
@ -536,6 +637,9 @@ class Structure {
* @returns {this}
*/
date(name, options){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof options !== "object") throwTypeError("object", options);
this.#columns.push(parseColumnData(name, `date`, options));
return this;
}
@ -548,7 +652,11 @@ class Structure {
* @returns {this}
*/
datetime(name, fsp=0, options){
if (fsp < 0 || fsp > 6) throw new Error(`Column datatype 'fsp' size must be a number between 0 and 6. Received: ${size}`);
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof fsp !== "number") throwTypeError("number", fsp);
if (typeof options !== "object") throwTypeError("object", options);
if (fsp < 0 || fsp > 6) throwRangeError(0, 6, fsp);
this.#columns.push(parseColumnData(name, `datetime(${fsp})`, options));
return this;
@ -562,7 +670,11 @@ class Structure {
* @returns {this}
*/
timestamp(name, fsp=0, options){
if (fsp < 0 || fsp > 6) throw new Error(`Column datatype 'fsp' size must be a number between 0 and 6. Received: ${size}`);
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof fsp !== "number") throwTypeError("number", fsp);
if (typeof options !== "object") throwTypeError("object", options);
if (fsp < 0 || fsp > 6) throwRangeError(0, 6, fsp);
this.#columns.push(parseColumnData(name, `timestamp(${fsp})`, options));
return this;
@ -576,7 +688,11 @@ class Structure {
* @returns {this}
*/
time(name, fsp=0, options){
if (fsp < 0 || fsp > 6) throw new Error(`Column datatype 'fsp' size must be a number between 0 and 6. Received: ${size}`);
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof fsp !== "number") throwTypeError("number", fsp);
if (typeof options !== "object") throwTypeError("object", options);
if (fsp < 0 || fsp > 6) throwRangeError(0, 6, fsp);
this.#columns.push(parseColumnData(name, `time(${fsp})`, options));
return this;
@ -589,6 +705,9 @@ class Structure {
* @returns {this}
*/
year(name, options){
if (!name) throw new Error("name must not be empty");
if (typeof name !== "string") throwTypeError("string", name);
if (typeof options !== "object") throwTypeError("object", options);
this.#columns.push(parseColumnData(name, `time`, options));
return this;
}

View File

@ -1,3 +1,4 @@
const { throwTypeError } = require("./Errors");
/**
* Prepares a new Update
@ -23,6 +24,8 @@ class Update{
* @returns {this}
*/
data(object){
if (!object) throw new Error("data object must not be empty");
if (typeof object !== "object") throwTypeError("object", object);
this.#data = object;
return this;
}
@ -33,6 +36,8 @@ class Update{
* @returns {this}
*/
selectDatabase(database){
if (!database) throw new Error("database must not be empty");
if (typeof database !== "string") throwTypeError("string", database);
this.#database = database;
return this;
}
@ -54,6 +59,9 @@ class Update{
* @returns {this}
*/
where(string, values=[]){
if (!string) throw new Error("string must not be empty");
if (typeof string !== "string") throwTypeError("string", string);
if (!Array.isArray(values)) throwTypeError("array", values);
this.#where = string;
this.#whereValues = values;
return this;
@ -70,7 +78,6 @@ class Update{
const values = [];
const queryString = `UPDATE ${this.#database}.${this.#table} SET ${Object.keys(this.#data).map(col=>{values.push(this.#data[col]);return `${col}=?`})}${this.#where&&` WHERE ${this.#where}`}`;
this.#where&&values.push(...this.#whereValues);
console.log(queryString);
return await this.#instance.queryRaw(queryString, values);
}
}

6
tests/test.js Normal file
View File

@ -0,0 +1,6 @@
const {awSQL, Structure} = require("..");
function test(){
new Structure().drop(1234);
}
test();