lib/database.js

1.
/**
2.
 * This is the database manager class. With this class you can select the database driver, connect 
3.
 * to the driver and get a specific database.
4.
 * @class database
5.
 */
6.
class manager {
7.
	constructor(cerus) {
8.
		this._cerus = cerus;
9.
	}
10.

			
11.
	/**
12.
	 * With this function you can select the driver the database manager will use. The driver is 
13.
	 * the module that is used to interact with the database. This module depends on what you're 
14.
	 * using, like MySQL or MongoDB. The function will automatically load the driver and if the
15.
	 * driver is unknown it will throw an error.
16.
	 * @summary Changes the database driver.
17.
	 * @param {String} name The name of the driver.
18.
	 * @function driver
19.
	 */
20.
	driver(name) {
21.
		if(typeof name !== "string") {
22.
			throw new TypeError("the argument name must be a string");
23.
		}
24.

			
25.
		switch(name) {
26.
			case "mongo":
27.
				this._driver = require("cerus-" + name)(this._cerus);
28.
				this._name = name;
29.
				break;
30.
			default:
31.
				throw new Error("the driver " + name + " is unknown");
32.
		}
33.
	}
34.

			
35.
	/**
36.
	 * This function lets the driver connect to the database. How the driver connects to the 
37.
	 * database depends on the driver. If your connecting to a local database, often you can use 
38.
	 * "localhost" as domain to connect. This function returns a promise that will continue 
39.
	 * depending on the events returned by the driver.
40.
	 * @example
41.
	 * cerus.database().connect("localhost");
42.
	 * // -> connects to the database at localhost
43.
	 * @summary Connects to the database.
44.
	 * @param {String} domain The domain to connect to.
45.
	 * @param {Object} [options] 
46.
	 * @return {Promise} This function returns a promise.
47.
	 * @function connect
48.
	 */
49.
	connect(domain, options = {}) {
50.
		if(typeof domain !== "string") {
51.
			throw new TypeError("the argument name must be a string");
52.
		}
53.

			
54.
		if(this._driver === undefined) {
55.
			throw new Error("the driver must be set before connecting to a database");
56.
		}
57.

			
58.
		return this._driver.connect(domain, options);
59.
	}
60.

			
61.
	/**
62.
	 * This function will return the specified database. Read more about databases {@link database.database.constructor here}.
63.
	 * @summary Returns the specified database.
64.
	 * @param {String} name The name of the database to return.
65.
	 * @return {Class} The database class.
66.
	 * @function database
67.
	 */
68.
	database(name) {
69.
		return new database(this._driver, name);
70.
	}
71.

			
72.
	/**
73.
	 * This function lets you close the connection to the database. This is done to close unneeded 
74.
	 * connections to relieve stress, since they are a pretty expensive resource. The function will
75.
	 * return a promise that is called when the database has been closed.
76.
	 * @example
77.
	 * cerus.database("test").close();
78.
	 * // -> closes the connection to the database
79.
	 * @summary Closes the connection to the database.
80.
	 * @return {Promise} This function returns a promise.
81.
	 * @function close
82.
	 */
83.
	close() {
84.
		return this._driver.close();
85.
	}
86.
}
87.

			
88.
module.exports = manager;
89.

			
90.
/**
91.
 * This is the database class. With this class you can manage a database and get tables. You can 
92.
 * also close the database with this class.
93.
 * @class database.database
94.
 */
95.
class database {
96.
	constructor(driver, name) {
97.
		if(typeof name !== "string") {
98.
			throw new TypeError("the argument name must be a string");
99.
		}
100.

			
101.
		if(driver === undefined) {
102.
			throw new Error("the driver must be set before selecting a database");
103.
		}
104.

			
105.
		this._driver = driver;
106.
		this._database = driver.database(name);
107.
	}
108.

			
109.
	/**
110.
	 * With this database you can clone the database. The database is cloned to the name specified 
111.
	 * with the newdb parameter. It will return a promise that is called when the database is 
112.
	 * closed.
113.
	 * @example
114.
	 * cerus.database("test1").clone("test2");
115.
	 * // -> clones the database to test2
116.
	 * @summary Clones the database.
117.
	 * @param {String} newdb The name of the new database.
118.
	 * @return {Promise} This function returns a promise.
119.
	 * @function clone
120.
	 */
121.
	clone(newdb) {
122.
		if(typeof newdb !== "string") {
123.
			throw new TypeError("the argument newdb must be a string");
124.
		}
125.

			
126.
		return this._database.clone(newdb);
127.
	}
128.

			
129.
	/**
130.
	 * This function lets you close the connection to the database. This is done to close unneeded 
131.
	 * connections to relieve stress, since they are a pretty expensive resource. The function will
132.
	 * return a promise that is called when the database has been closed.
133.
	 * @example
134.
	 * cerus.database("test").close();
135.
	 * // -> closes the connection to the database
136.
	 * @summary Closes the database.
137.
	 * @return {Promise} This function returns a promise.
138.
	 * @function close
139.
	 */
140.
	close() {
141.
		return this._database.close();
142.
	}
143.

			
144.
	/**
145.
	 * This function will return the specified table.
146.
	 * @example
147.
	 * cerus.database("test").table("test_table");
148.
	 * // -> return the "test_table" table
149.
	 * @summary Returns the specified table.
150.
	 * @param {String} name The name of the table to return.
151.
	 * @return {Class} The specified table.
152.
	 * @function table
153.
	 */
154.
	table(name) {
155.
		return new table(this._database, name);
156.
	}
157.

			
158.
	/**
159.
	 * This function return the name of the database.
160.
	 * @summary Returns the name of the database.
161.
	 * @return {String} The name of the database.
162.
	 * @function name
163.
	 */
164.
	name() {
165.
		return this._database.name();
166.
	}
167.

			
168.
	/**
169.
	 * With this function you can delete the database. It returns a promise that is called when the
170.
	 * database has been dropped.
171.
	 * @example
172.
	 * cerus.database("test").drop();
173.
	 * // -> deletes the database
174.
	 * @summary Drops the database.
175.
	 * @return {Promise} This function returns a promise.
176.
	 * @function drop
177.
	 */
178.
	drop() {
179.
		return this._database.drop();
180.
	}
181.
}
182.

			
183.
/**
184.
 * This is the table class. With this class you can manage the table returned by the 
185.
 * {@link database.database.table} function.
186.
 * @example
187.
 * cerus.database("test").table("test_table");
188.
 * // -> return the "test_table" table
189.
 * @class database.table
190.
 */
191.
class table {
192.
	constructor(database, name) {
193.
		if(typeof name !== "string") {
194.
			throw new TypeError("the argument name must be a string");
195.
		}
196.

			
197.
		this._database = database;
198.
		this._table = database.table(name);
199.
	}
200.

			
201.
	/**
202.
	 * With this function you can close the connection to the database. It is basically an alias of
203.
	 * the {@link database.database.close} function. You should close connections when you're 
204.
	 * finished with them, to relieve stress from the system. It returns a promise that is called 
205.
	 * when the connection has been closed.
206.
	 * @example
207.
	 * cerus.database("test").table("test_table").close();
208.
	 * // -> closes the connection to the database
209.
	 * @summary Closes the connection to the database.
210.
	 * @return {Promise} This function returns a promise.
211.
	 * @function close
212.
	 */
213.
	close() {
214.
		return this._database.close();
215.
	}
216.

			
217.
	/**
218.
	 * This function clears the table. This means removing everything that is in the table. Use
219.
	 * {@link database.database.table.drop} to delete the whole table, instead of its contents. It
220.
	 * returns a promise that is called when the table is cleared.
221.
	 * @example
222.
	 * cerus.database("test").table("test_table").clear();
223.
	 * // -> clears everything in the table
224.
	 * @summary Clears the table.
225.
	 * @return {Promise} This function returns a promise.
226.
	 * @function clear
227.
	 */
228.
	clear() {
229.
		return this._table.clear();
230.
	}
231.

			
232.
	/**
233.
	 * With this function you can delete the table. This means removing the whole table. Use 
234.
	 * {@link database.database.table.clear} to remove the contents of the table, instead of the whole
235.
	 * table. It returns a promise that is called when the table has been dropped.
236.
	 * @example
237.
	 * cerus.database("test").table("test_table").drop();
238.
	 * // -> deletes the table
239.
	 * @summary Drops the table.
240.
	 * @return {Promise} This function returns a promise.
241.
	 * @function drop
242.
	 */
243.
	drop() {
244.
		return this._table.drop();
245.
	}
246.

			
247.
	/**
248.
	 * This function lets you insert a row into the database. A row is basically a new item that 
249.
	 * will be added to the table. This function will return a promise that is called when the row
250.
	 * has been added.
251.
	 * @example
252.
	 * cerus.database("test").table("test_table").insert({row: "new_item"});
253.
	 * // -> adds the item {row: "new_item"} to the table
254.
	 * @summary Adds a new row to the table.
255.
	 * @param {Object} row The row that will be added.
256.
	 * @return {Promise} This function returns a promise.
257.
	 * @function insert
258.
	 */
259.
	insert(row) {
260.
		if(typeof row !== "object") {
261.
			throw new TypeError("the argument row must be an object");
262.
		}
263.

			
264.
		return this._table.insert(row);
265.
	}
266.

			
267.
	/**
268.
	 * With this function you can modify the specified rows. You can specify the rows using the 
269.
	 * query parameter. Multiple rows can be selected to be modified. The columns that will be 
270.
	 * modified are specified using the change paramater. This function will return a promise that 
271.
	 * is called when the rows have been modified.
272.
	 * @example
273.
	 * cerus.database("test").table("test_table").modify({id: 1}, {row: "new_item"});
274.
	 * // -> changes the item {id: 1, row: "item"} to {id: 1, row: "new_item"}
275.
	 * @summary Modifies the specfied rows.
276.
	 * @param {Object} query The rows that will be modified.
277.
	 * @param {Object} change The changes that will be done to the rows.
278.
	 * @return {Promise} This function returns a promise.
279.
	 * @function modify
280.
	 */
281.
	modify(query, change) {
282.
		if(typeof query !== "object") {
283.
			throw new TypeError("the argument query must be an object");
284.
		}
285.
		
286.
		if(typeof change !== "object") {
287.
			throw new TypeError("the argument change must be an object");
288.
		}
289.

			
290.

			
291.
		return this._table.modify(query, change);
292.
	}
293.

			
294.
	/**
295.
	 * Using this function you can delete the specified rows. You can specify the rows you need to 
296.
	 * be deleted using the query parameter. Multiple rows can be deleted. The function will return
297.
	 * a promise that is resolved when the rows have been deleted.
298.
	 * @example
299.
	 * cerus.database("test").table("test_table").delete({id: 1});
300.
	 * // -> deletes the item {id: 1, row: "item"}
301.
	 * @summary Deletes the specified rows.
302.
	 * @param {Object} query The rows that will be deleted.
303.
	 * @return {Promise} This function returns a promise.
304.
	 * @function delete
305.
	 */
306.
	delete(query) {
307.
		if(typeof query !== "object") {
308.
			throw new TypeError("the argument query must be an object");
309.
		}
310.

			
311.
		return this._table.delete(query);
312.
	}
313.

			
314.
	/**
315.
	 * With this function you can find the specified rows. The rows that will be searched for are 
316.
	 * specified using the query parameter. Multiple rows can be searched for. The function will 
317.
	 * return a promise that is resolved with all the rows that were found.
318.
	 * @summary Seaches for the specified rows.
319.
	 * @param {Object} query The rows that will be searched for.
320.
	 * @return {Promise} This function returns a promise.
321.
	 * @function find
322.
	 */
323.
	find(query) {
324.
		if(typeof query !== "object") {
325.
			throw new TypeError("the argument query must be an object");
326.
		}
327.

			
328.
		return this._table.find(query);
329.
	}
330.

			
331.
	/**
332.
	 * Using this function you can count the rows that are specified. The rows that will be counted
333.
	 * can be specified using the query parameter. The function returns a promise that is resolved 
334.
	 * with the amount of rows that were found.
335.
	 * @summary Counts the specified rows.
336.
	 * @param {Object} query The rows that will be counted.
337.
	 * @return {Promise} This function returns a promise.
338.
	 * @function count
339.
	 */
340.
	count(query) {
341.
		if(typeof query !== "object") {
342.
			throw new TypeError("the argument query must be an object");
343.
		}
344.

			
345.
		return this._table.count(query);
346.
	}
347.

			
348.
	/**
349.
	 * With this function you can clone this database to the specified name. The promise that is 
350.
	 * returned resolves when the database has been created. It will reject when the name that the 
351.
	 * database is being cloned to already is already used.
352.
	 * @summary Clones this database.
353.
	 * @param {String} new_database The name to clone to.
354.
	 * @return {Promise} This function returns a promise.
355.
	 * @function clone
356.
	 */
357.
	clone(new_database) {
358.
		if(typeof new_database !== "string") {
359.
			throw new TypeError("the argument new_database must be a string");
360.
		}
361.

			
362.
		return this._table.clone(new_database);
363.
	}
364.

			
365.
	/**
366.
	 * This function returns the {@link columns} class.
367.
	 * @summary Returns the {@link columns} class.
368.
	 * @return {Class} Returns the columns class.
369.
	 * @function columns
370.
	 */
371.
	columns() {
372.
		return new columns(this._table);
373.
	}
374.

			
375.
	/**
376.
	 * This function returns the {@link keys} class.
377.
	 * @summary Returns the {@link keys} class.
378.
	 * @return {Class} Returns the keys class.
379.
	 * @function keys
380.
	 */
381.
	keys() {
382.
		return new keys();
383.
	}
384.
}
385.

			
386.
/**
387.
 * This is the columns class. Using this class you can manage the columns for the {@link database.table.contructor} class.
388.
 * @class database.table.columns
389.
 */
390.
class columns {
391.
	constructor(table) {
392.
		this._columns = table.columns();
393.
	}
394.

			
395.
	/**
396.
	 * This function adds a column to the table. The name of the new column is specified using the 
397.
	 * name parameter. You can set the data type of the column using the datatype parameter. The 
398.
	 * function returns a promise that is resolved when the new column has been created.
399.
	 * @summary Adds a new columns to the table.
400.
	 * @param {String} name The name of the new column.
401.
	 * @param {String} datatype The data type of the new column.
402.
	 * @return {Promise} This function returns a promise.
403.
	 * @function add
404.
	 */
405.
	add(name, datatype) {
406.
		if(typeof name !== "string") {
407.
			throw new TypeError("the argument name must be a string");
408.
		}
409.

			
410.
		return this._columns.add(name, datatype);
411.
	}
412.

			
413.
	/**
414.
	 * Using this function you can drop the specified column. You can specify the column that will 
415.
	 * be dropped using the name parameter. The function returns a promise that is resolved when 
416.
	 * the column has been dropped.
417.
	 * @summary Drops the specified column.
418.
	 * @param {String} name The name of the column to drop.
419.
	 * @return {Promise} This function returns a promise.
420.
	 * @function drop
421.
	 */
422.
	drop(name) {
423.
		if(typeof name !== "string") {
424.
			throw new TypeError("the argument name must be a string");
425.
		}
426.

			
427.
		return this._columns.drop(name);
428.
	}
429.

			
430.
	/**
431.
	 * This function modifies the specified column. The name of the columns that will be modified 
432.
	 * is specified using the name parameters and can be modified using the options parameter. The
433.
	 * function returns a promise that is resolved when the column has been modified.
434.
	 * @summary Modifies the specified column.
435.
	 * @param {String} name The name of the column to modify.
436.
	 * @param {Object} options The options containing what will be modified.
437.
	 * @return {Promise} This function returns a promise.
438.
	 * @function modify
439.
	 */
440.
	modify(name, options) {
441.
		if(typeof name !== "string") {
442.
			throw new TypeError("the argument name must be a string");
443.
		}
444.

			
445.
		return this._columns.modify(name, options);
446.
	}
447.

			
448.
	/**
449.
	 * With this function you can check if a column exists. The function returns a promise that is 
450.
	 * resolved with a boolean if the column exists.
451.
	 * @summary Checks if the column exists.
452.
	 * @param {String} name The name of the column exists.
453.
	 * @return {Promise} This function returns a promise.
454.
	 * @function has
455.
	 */
456.
	has(name) {
457.
		if(typeof name !== "string") {
458.
			throw new TypeError("the argument name must be a string");
459.
		}
460.

			
461.
		return this._columns.exists(name);
462.
	}
463.

			
464.
	/**
465.
	 * This function returns a promise that resolves with the specified column as argument.
466.
	 * @summary Returns the specified column.
467.
	 * @param {String} name The name of the column to return.
468.
	 * @return {Promise} This function returns a promise.
469.
	 * @function get
470.
	 */
471.
	get(name) {
472.
		if(typeof name !== "string") {
473.
			throw new TypeError("the argument name must be a string");
474.
		}
475.

			
476.
		return this._columns.get(name);
477.
	}
478.

			
479.
	/**
480.
	 * This function returns promise that is resolved with a list with all of the columns.
481.
	 * @summary Lists all of the columns.
482.
	 * @return {Promise} This function returns a promise.
483.
	 * @function list
484.
	 */
485.
	list() {
486.
		return this._columns.list();
487.
	}
488.

			
489.
	/**
490.
	 * With this function you can remove all of the columns.
491.
	 * @summary Clears all of the columns.
492.
	 * @return {Promise} This function returns a promise.
493.
	 * @function clear
494.
	 */
495.
	clear() {
496.
		return this._colums.clear();
497.
	}
498.
}
499.

			
500.
/**
501.
 * This class manages the keys for the specified table. With this class you can manage the primary 
502.
 * and secondary keys.
503.
 * @class database.table.keys
504.
 */
505.
class keys {
506.
	constructor(table) {
507.
		this._keys = table.keys();
508.
		this._primary = new primary(this._keys.primary());
509.
		this._secondary = new secondary(this._keys.secondary());
510.
	}
511.
	
512.
	primary() {
513.
		return this._primary;
514.
	}
515.

			
516.
	secondary() {
517.
		return this._secondary;
518.
	}
519.
}
520.

			
521.
/**
522.
 * This is the primary keys class. With this class you can manage the primary keys for the 
523.
 * specified table.
524.
 * @class database.table.keys.primary
525.
 */
526.
class primary {
527.
	constructor(primary) {
528.
		this._primary = primary;
529.
	}
530.

			
531.
	create(column) {
532.
		if(typeof column !== "string") {
533.
			throw new TypeError("the argument column must be a string");
534.
		}
535.

			
536.
		return this._primary.create(column);
537.
	}
538.

			
539.
	drop() {
540.
		return this._primary.drop();
541.
	}
542.
}
543.

			
544.
/**
545.
 * This is the secondary keys class. With this class you can manager the secondary keys for the
546.
 * specified table.
547.
 * @class database.table.keys.secondary
548.
 */
549.
class secondary {
550.
	constructor(secondary) {
551.
		this._secondary = secondary;
552.
	}
553.

			
554.
	create(name, column) {
555.
		if(typeof name !== "string") {
556.
			throw new TypeError("the argument name must be a string");
557.
		}
558.

			
559.
		if(typeof column !== "string") {
560.
			throw new TypeError("the argument column must be a string");
561.
		}
562.

			
563.
		return this._secondary.create(name, column);
564.
	}
565.

			
566.
	has(name) {
567.
		if(typeof name !== "string") {
568.
			throw new TypeError("the argument name must be a string");
569.
		}
570.

			
571.
		return this._secondary.has(name);
572.
	}
573.

			
574.
	drop(name) {
575.
		if(typeof name !== "string") {
576.
			throw new TypeError("the argument name must be a string");
577.
		}
578.

			
579.
		return this._secondary.drop(name);
580.
	}
581.

			
582.
	list() {
583.
		return this._secondary.list();
584.
	}
585.

			
586.
	clear() {
587.
		return this._secondary.clear();
588.
	}
589.
}
590.