All Downloads are FREE. Search and download functionalities are using the official Maven repository.

META-INF.dirigible.db.v4.orm.js Maven / Gradle / Ivy

/*
 * Copyright (c) 2022 SAP SE or an SAP affiliate company and Eclipse Dirigible contributors
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and Eclipse Dirigible contributors
 * SPDX-License-Identifier: EPL-2.0
 */
"use strict";

/**
 * Supported ORM schema:
 * {
 *	 name: ,
 *   table: ,
 *   properties: [{
 *	   name: ,
 *	   column: ,
 *	   id: ,
 *	   required: ,
 *	   unique: ,
 *	   dbValue: ,
 *	   value: ,
 *	   allowedOps: 
 *   }],
 * 	 associations: [{
 *	   name: ,
 *     joinKey: ,
 *     key: ,
 *     type: ,
 *     targetDao: ,
 *     joinDao: ,
 *     defaults: ,
 *   }]
 * }
 *
 *
 */
const isCaseSensitive = require("core/v4/configurations").get("DIRIGIBLE_DATABASE_NAMES_CASE_SENSITIVE");

var ORM = exports.ORM = function(orm){
	this.orm = orm;
	for(var i in orm){
		this[i] = orm[i];
	}
};

ORM.prototype.ASSOCIATION_TYPES = Object.freeze({
	"ONE-TO-ONE": "one-to-one",
	"ONE-TO-MANY": "one-to-many",
	"MANY-TO-MANY": "many-to-many",
	"MANY-TO-ONE": "many-to-one"
});
ORM.prototype.ASSOCIATION_TYPES_VALUES = Object.keys(ORM.prototype.ASSOCIATION_TYPES)
											.map(function (key) {
											  return ORM.prototype.ASSOCIATION_TYPES[key];
											});

ORM.prototype.getPrimaryKey = function(){
	if(!this.idProperty){
		if(!this.properties || !this.properties.length)
			throw new Error('Invalid orm configuration - no properties are defined');
		const id = this.properties.filter(function (property) {
			return property.id;
		});
		if(!id.length)
			throw new Error('Invalid orm configuration - no id property is defined');
		this.idProperty = id[0];
	}
	return this.idProperty;
};

ORM.prototype.isAutoIncrementPrimaryKey = function(){
	if(!this.autoIncrementPrimaryKeyProperty){
		if(!this.properties || !this.properties.length)
			throw new Error('Invalid orm configuration - no properties are defined');
		let isAutoIncrementOldVersion = false;
		const autoIncrementPrimaryKeyProperty = this.properties.filter(function (property) {
			if (property.id && (property.autoIncrement === undefined || property.autoIncrement === null)) {
				isAutoIncrementOldVersion = true;
			}
			return property.id && (property.autoIncrement || isAutoIncrementOldVersion);
		});
		this.autoIncrementPrimaryKeyProperty = autoIncrementPrimaryKeyProperty.length > 0;
	}
	return this.autoIncrementPrimaryKeyProperty;
};

ORM.prototype.getProperty = function(name){
	if(name === undefined)
		throw new Error('Illegal argument: name['+name+']');
	if(!this.properties || !this.properties.length)
		throw new Error('Invalid orm configuration - no properties are defined');
	const property = this.properties.filter(function (property) {
		return property.name === name;
	});
	return property.length>0?property[0]:undefined;
};

ORM.prototype.getMandatoryProperties = function(){
	if(!this.mandatoryProperties){
		if(!this.properties || !this.properties.length)
			throw new Error('Invalid orm configuration - no properties are defined');
		const mandatories = this.properties.filter(function (property) {
			return property.required;
		});
		this.mandatoryProperties = mandatories;
	}
	return this.mandatoryProperties;
};

ORM.prototype.getOptionalProperties = function(){
	if(!this.optionalProperties){
		if(!this.properties || !this.properties.length)
			throw new Error('Invalid orm configuration - no properties are defined');
		const mandatories = this.properties.filter(function (property) {
			return !property.required;
		});
		this.optionalProperties = mandatories;
	}
	return this.optionalProperties;
};

ORM.prototype.getUniqueProperties = function(){
	if(!this.uniqueProperties){
		if(!this.properties || !this.properties.length)
			throw new Error('Invalid orm configuration - no properties are defined');
		const uniques = this.properties.filter(function (property) {
			return property.unique;
		});
		this.uniqueProperties = uniques;
	}
	return this.uniqueProperties;
};

//TODO: remove this or improve by key type.
ORM.prototype.associationKeys = function(){
	let keys = [];
	if(this.associations){
		keys = this.associations.map(function(assoc){
			return assoc.joinKey;
		});
	}
	return keys;
};

ORM.prototype.getAssociationNames = function(){
	let names = [];
	if(this.associations){
		names = this.associations.map(function(assoc){
			return assoc.name;
		});
	}
	return names;
};


ORM.prototype.getAssociation = function(associationName){
	if(this.associations){
		return this.associations
				.filter(function(assoc){
					return assoc.name === associationName;
				})[0];
	}
	return;
};

ORM.prototype.validate = function(){
	let i;
	if(!this.table)
		throw new Error('Illegal configuration: invalid property table['+this.table+']');
	if(!this.properties)
		throw new Error('Illegal configuration: invalid property properties['+this.properties+']');
	if(this.properties.constructor !== Array)
		throw new Error("Illegal configuration: property 'properties' type is expected ot be Array. Instead, it was "+(typeof this.properties));
	if(!this.getPrimaryKey())
		throw new Error('Illegal configuration: No primary key specifed');
	for(i = 0; i< this.properties.length; i++){
		const property = this.properties[i];
		if(!property.name)
			throw new Error('Illegal configuration: invalid property name['+property.name+']');
		if(!property.type)
			throw new Error('Illegal configuration: invalid property type['+property.type+']');
		if(!property.column)
			throw new Error('Illegal configuration: invalid property column['+property.column+']');
		if(property.allowedOps){
			if(property.allowedOps.constructor !== Array)
				throw new Error("Illegal configuration: property[" + property.name + "]  allowedOps is expected ot be Array. Instead, it was "+(typeof property.allowedOps));
			for(let j=0; j 1 || uniqueIndices.length > 0 ) {
		table["constraints"] = {};
	}

	if(primaryKeys.length > 1){
		table.columns = table.columns.map(function(column){
			column.primaryKey = "false";
			return column;
		});
		table.constraints["primarKeys"] = primaryKeys;
	}
	if(uniqueIndices.length>0)
		table.constraints["uniqueIndices"] = uniqueIndices;

	return table;
};

exports.get = function(orm){
	const _orm = new ORM(orm);
	_orm.validate();
	return _orm;
};