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

de.svws_nrw.db.schema.SchemaTabelleFremdschluessel Maven / Gradle / Ivy

Go to download

Diese Bibliothek regelt den Zugriff auf Datenbanken für die Schulverwaltungssoftware in NRW

There is a newer version: 1.0.1
Show newest version
package de.svws_nrw.db.schema;

import java.util.List;
import java.util.stream.Collectors;

import de.svws_nrw.db.DBDriver;

/**
 * Diese Klasse dient der Definition eines Fremdschlüssels bei SVWS-Datenbank-Tabellen.
 */
public class SchemaTabelleFremdschluessel {

	/** Der Name des Fremdschlüssels */
	private final String _name;

	/** Die Tabelle, der dieser Fremdschluessel zugeordnet ist */
	private final SchemaTabelle _tabelle;

	/** Die Tabelle, die dieser Fremdschluessel referenziert */
	private final SchemaTabelle _tabelleReferenziert;

	/** Die Spalten dieser Tabelle */
	private final List _spalten;

	/** Die zugehörigen Spalten der referenzierten Tabelle */
	private final List _spaltenReferenziert;

	/** Die Aktion bei einer Aktualisierung des referenzierten Schlüsselwertes */
	private final SchemaFremdschluesselAktionen _onUpdate;

	/** Die Aktion bei dem Entfernen des referenzierten Schlüsselwertes */
	private final SchemaFremdschluesselAktionen _onDelete;

	/** Die Revision, ab wann der Fremdschluessel gültig ist. */
	private SchemaRevisionen _revision;

	/** Die Revision, ab wann der Fremdschluessel veraltet ist, sofern er veraltet ist, ansonsten {@link SchemaRevisionen#UNDEFINED} */
	private SchemaRevisionen _veraltet;


	/**
	 * Erstellt einen neuen Fremdschluessel.
	 *
	 * @param name         der Name des Index
	 * @param tab          die Tabelle, der diese Index zugeordnet ist.
	 * @param tabRef       die referenzierte Tabelle
	 * @param onUpdate     die Aktion bei einer Aktualisierung des referenzierten Schlüsselwertes
	 * @param onDelete     die Aktion bei dem Entfernen des referenzierten Schlüsselwertes
	 * @param spalten      die Spalten des Fremdschlüssel dieser Tabelle
	 * @param spaltenRef   die referenzierten Spalten der referentierten Tabelle des Fremdschlüssels
	 */
	SchemaTabelleFremdschluessel(final String name, final SchemaTabelle tab, final SchemaTabelle tabRef, final SchemaFremdschluesselAktionen onUpdate,
			final SchemaFremdschluesselAktionen onDelete, final List spalten, final List spaltenRef) {
		this._name = name;
		this._tabelle = tab;
		this._tabelleReferenziert = tabRef;
		this._spalten = spalten;
		this._spaltenReferenziert = spaltenRef;
		this._onUpdate = onUpdate;
		this._onDelete = onDelete;
		this._revision = tab.revision();
		this._veraltet = tab.veraltet();
	}


	/**
	 * Setzt die Revision, ab wann der Fremdschlüssel gültig ist. Dabei wird
	 * der übernommene Wert von der Tabelle überschrieben.
	 *
	 * @param revision   die Revision
	 *
	 * @return dieses Objekt
	 */
	public SchemaTabelleFremdschluessel setRevision(final SchemaRevisionen revision) {
		if (revision == SchemaRevisionen.UNDEFINED)
			throw new RuntimeException("Die Revision eines Fremdschlüssels kann nicht auf undefiniert gesetzt werden.");
		if (revision.revision <= this._revision.revision)
			throw new RuntimeException("Die Revision eines Fremdschlüssels kann nur Überschrieben werden, wenn die Revision größer ist als die,"
					+ " welche bei der Tabelle gesetzt ist.");
		this._revision = revision;
		return this;
	}

	/**
	 * Setzt die Revision, ab wann der Fremdschlüssel veraltet ist. Dabei wird
	 * der übernommene Wert von der Tabelle überschrieben.
	 *
	 * @param veraltet   die Revision
	 *
	 * @return dieses Objekt
	 */
	public SchemaTabelleFremdschluessel setVeraltet(final SchemaRevisionen veraltet) {
		if (veraltet == SchemaRevisionen.UNDEFINED)
			throw new RuntimeException("Die Revision, wann ein Fremdschlüssel veraltet, kann nicht auf undefiniert gesetzt werden, da in diesem Fall"
					+ " das Erben des Veraltet-Attributes der Tabelle vorrangig ist.");
		if ((this._veraltet != SchemaRevisionen.UNDEFINED) && (veraltet.revision >= this._veraltet.revision))
			throw new RuntimeException("Die Revision, wann ein Fremdschlüssel veraltet, kann nicht auf eine Revision größer oder gleich der Revision"
					+ " gesetzt werden, wo die zugehörige Tabelle veraltet.");
		this._veraltet = veraltet;
		return this;
	}

	/**
	 * Gibt die Tabelle zurück, der dieser Fremdschlüssel zugeordnet ist.
	 *
	 * @return die Tabelle
	 */
	public SchemaTabelle tabelle() {
		return _tabelle;
	}

	/**
	 * Gibt die vom Fremdschlüssel referenzierte Tabelle zurück.
	 *
	 * @return die referenzierte Tabelle
	 */
	public SchemaTabelle tabelleReferenziert() {
		return _tabelleReferenziert;
	}

	/**
	 * Gibt den Namen des Fremdschlüssels zurück.
	 *
	 * @return der Name des Fremdschlüssels
	 */
	public String name() {
		return _name;
	}

	/**
	 * Gibt die Spalten der Tabelle des Fremdschlüssels zurück.
	 *
	 * @return die Spalten der Tabelle des Fremdschlüssels
	 */
	public List spalten() {
		return _spalten;
	}

	/**
	 * Gibt die referenzierten Spalten der referenzierten Tabelle des Fremdschlüssels zurück.
	 *
	 * @return die referenzierten Spalten der referenzierten Tabelle des Fremdschlüssels
	 */
	public List spaltenReferenziert() {
		return _spaltenReferenziert;
	}

	/**
	 * Gibt die Aktion bei einer Aktualisierung des referenzierten Schlüsselwertes.
	 *
	 * @return die Aktion bei einer Aktualisierung des referenzierten Schlüsselwertes
	 */
	public SchemaFremdschluesselAktionen onUpdate() {
		return _onUpdate;
	}

	/**
	 * Gibt die Aktion bei dem Entfernen des referenzierten Schlüsselwertes.
	 *
	 * @return die Aktion bei dem Entfernen des referenzierten Schlüsselwertes
	 */
	public SchemaFremdschluesselAktionen onDelete() {
		return _onDelete;
	}

	/**
	 * Gibt die Revision zurück, ab wann der Fremdschlüssel gültig ist.
	 *
	 * @return die Revision
	 */
	public SchemaRevisionen revision() {
		return _revision;
	}

	/**
	 * Gibt die Revision zurück, ab wann der Fremdschlüssel veraltet ist.
	 * Ist er nicht veraltet, so wird {@link SchemaRevisionen#UNDEFINED}
	 * zurückgegeben.
	 *
	 * @return die Revision, ab wann der Fremdschlüssel veraltet ist, oder {@link SchemaRevisionen#UNDEFINED}
	 */
	public SchemaRevisionen veraltet() {
		return _veraltet;
	}


	/**
	 * Liefert die Tabellenspalten des Fremdschlüssels in der durch das Feld Sortierung definierten Reihenfolge
	 *
	 * @return die Tabellenspalten des Fremdschlüssels in der durch das Feld Sortierung definierten Reihenfolge
	 */
	public List getSpalten() {
		return _spalten.stream().sorted((a, b) -> Integer.compare(a.sortierung(), b.sortierung())).toList();
	}


	/**
	 * Erstellt einen SQL-String für das Erstellen einen Fremdschlüssels als SQL-CONSTRAINT
	 *
	 * @return der SQL-String für das Erstellen des Fremdschlüssels
	 */
	public String getSQL() {
		return "CONSTRAINT " + this.name() + " FOREIGN KEY ("
				+ getSpalten().stream().map(spalte -> spalte.name()).collect(Collectors.joining(", "))
				+ ") REFERENCES " + this._tabelleReferenziert.name() + '('
				+ _spaltenReferenziert.stream().map(spalte -> spalte.name()).collect(Collectors.joining(", "))
				+ ")"
				+ ((this._onUpdate == null) || (this._onUpdate == SchemaFremdschluesselAktionen.NO_ACTION) ? "" : " ON UPDATE " + this._onUpdate.sql())
				+ ((this._onDelete == null) || (this._onDelete == SchemaFremdschluesselAktionen.NO_ACTION) ? "" : " ON DELETE " + this._onDelete.sql());
	}


	/**
	 * Erstellt einen SQL-String für das nachträgliche Erstellen einen Fremdschlüssels
	 * für den SQL-Dialekt des angegebenen DBMS
	 *
	 * @param dbms   das DBMS
	 *
	 * @return der SQL-String für das nachträgliche Erstellen des Fremdschlüssels
	 */
	public String getSQLCreate(final DBDriver dbms) {
		switch (dbms) {
			case SQLITE:
				// TODO currently not supported
				return null;
			case MDB, MARIA_DB, MYSQL, MSSQL:
			default:
				return "ALTER TABLE " + this._tabelle.name() + " ADD " + this.getSQL();
		}
	}


	/**
	 * Erzeugt den SQL-Drop-Befehl für diesen Fremdschlüssel für den SQL-Dialekt des angegebenen DBMS
	 *
	 * @param dbms   das DBMS
	 *
	 * @return der SQL-Drop-Befehl
	 */
	public String getSQLDrop(final DBDriver dbms) {
		return switch (dbms) {
			// TODO SQLite - Currently not supported
			case SQLITE -> null;
			case MARIA_DB, MYSQL -> "ALTER TABLE " + this._tabelle.name() + " DROP FOREIGN KEY " + this._name + ";";
			case MDB, MSSQL -> "ALTER TABLE " + this._tabelle.name() + " DROP CONSTRAINT " + this._name + ";";
			default -> "ALTER TABLE " + this._tabelle.name() + " DROP FOREIGN KEY " + this._name + ";";
		};
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy