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

de.svws_nrw.data.schema.DataSQLite Maven / Gradle / Ivy

Go to download

Diese Bibliothek unterstützt bei dem Zugriff auf Datenbanken für die Schulverwaltungssoftware in NRW

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

import de.svws_nrw.base.FileUtils;
import de.svws_nrw.config.LogConsumerLogfile;
import de.svws_nrw.config.SVWSKonfiguration;
import de.svws_nrw.config.SVWSKonfigurationException;
import de.svws_nrw.core.data.SimpleOperationResponse;
import de.svws_nrw.core.logger.LogConsumerList;
import de.svws_nrw.core.logger.LogLevel;
import de.svws_nrw.core.logger.Logger;
import de.svws_nrw.db.Benutzer;
import de.svws_nrw.db.DBConfig;
import de.svws_nrw.db.DBDriver;
import de.svws_nrw.db.DBEntityManager;
import de.svws_nrw.db.DBException;
import de.svws_nrw.db.utils.ApiOperationException;
import de.svws_nrw.db.utils.schema.DBSchemaManager;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import jakarta.ws.rs.core.StreamingOutput;

import java.io.IOException;
import java.time.ZoneId;
import java.time.ZonedDateTime;

/**
 * Diese Klasse stellt Methoden für den Import und Export von SQLite-Datenbanken
 * zur Verfügung.
 */
public final class DataSQLite {

	private DataSQLite() {
		throw new IllegalStateException("Instantiation of " + DataSQLite.class.getName() + " not allowed");
	}

	/**
	 * Erzeugt eine einfache Anwort mit der Angabe, ob die Operation erfolgreich war und
	 * mit dem Log derOperation.
	 *
	 * @param success   gibt an, ob die Operation erfolgreich war oder nicht
	 * @param log       der Log der Operation
	 *
	 * @return das Response-Objekt
	 */
	private static SimpleOperationResponse simpleResponse(final boolean success, final LogConsumerList log) {
		final SimpleOperationResponse response = new SimpleOperationResponse();
		response.success = success;
		response.log = log.getStrings();
		return response;
	}

	/**
	 * Exportiert eine SQLite-Datenbank aus dem aktuellen Schema. Der Aufruf erfordert
	 * administrative Rechte.
	 *
	 * @param conn         die Datenbank-Verbindung zu dem aktuellen Schema
	 * @param schemaname   Name des Schemas, welches exportiert werden soll
	 *
	 * @return Die SQLite-Datenbank
	 *
	 * @throws ApiOperationException im Fehlerfall
	 */
	public static Response exportSQLite(final DBEntityManager conn, final String schemaname) throws ApiOperationException {
		final Logger logger = new Logger();
		logger.copyConsumer(Logger.global());
		final LogConsumerList log = new LogConsumerList();
		logger.addConsumer(log);
		try {
			if (SVWSKonfiguration.get().isLoggingEnabled())
				logger.addConsumer(new LogConsumerLogfile("svws_schema_" + schemaname + ".log", true, true));
		} catch (final IOException e) {
			throw new ApiOperationException(Status.INTERNAL_SERVER_ERROR, e, "Fehler beim Erstellen einer Log-Datei für das Schema");
		}

		// Bestimme den Dateinamen für eine temporäre SQLite-Datei
		try (APITempDBFile sqlite = new APITempDBFile(DBDriver.SQLITE, conn.getDBSchema(), logger, log, null, false)) {
			// Erzeuge einen Schema-Manager, der den Export des DB-Schema durchführt
			final DBSchemaManager srcManager = DBSchemaManager.create(conn.getUser(), true, logger);
			if (srcManager == null)
				throw new ApiOperationException(Status.FORBIDDEN);

			// Führe den Export mithilfe des Schema-Managers durch.
			logger.modifyIndent(2);
			srcManager.backup.exportDB(sqlite.getFilename(), logger);
			logger.modifyIndent(-2);

			// Lese die Datenbank in die Response ein
			logger.logLn("Lese die temporären SQLite-Datenbank unter dem Namen \"" + sqlite.getFilename() + "\" ein.");
			final ZoneId berlin = ZoneId.of("Europe/Berlin");
			final ZonedDateTime jetzt = ZonedDateTime.now(berlin);
			final String schemanameMitDatum = schemaname + String.format("_%02d%02d%02d_%02d%02d", jetzt.getYear(), jetzt.getMonthValue(),
					jetzt.getDayOfMonth(), jetzt.getHour(), jetzt.getMinute());
			final Response response = Response.ok((StreamingOutput) output -> {
				try {
					FileUtils.move(sqlite.getFilename(), output);
					output.flush();
				} catch (@SuppressWarnings("unused") final Exception e) {
					// TODO throw new ApiOperationException(Status.INTERNAL_SERVER_ERROR, e);
				}
			}).header("Content-Disposition", "attachment; filename=\"" + schemanameMitDatum + ".sqlite\"").build();
			if (!response.hasEntity())
				logger.logLn(2, "[FEHLER]");
			logger.logLn("Datei eingelesen.");
			return response;
		}
	}


	/**
	 * Import ein Backup der SVWS-Datenbank in das angegebene bereits vorhandene Schema der
	 * übergebenen Datenbank-Verbindung. Dabei geht der usprüngliche Inhalt des Ziel-Schemas
	 * verloren.
	 *
	 * @param conn            die Datenbank-Verbindung zum Ziel-Schema
	 * @param srcDB           die SQLite-Quell-Datenbank
	 *
	 * @return die HTTP-Response mit dem LOG des Imports
	 *
	 * @throws ApiOperationException im Fehlerfall
	 */
	public static Response importSQLite(final DBEntityManager conn, final byte[] srcDB) throws ApiOperationException {
		final Logger logger = new Logger();
		logger.copyConsumer(Logger.global());
		final LogConsumerList log = new LogConsumerList();
		logger.addConsumer(log);
		try {
			if (SVWSKonfiguration.get().isLoggingEnabled())
				logger.addConsumer(new LogConsumerLogfile("svws_schema_" + conn.getDBSchema() + ".log", true, true));
		} catch (final IOException e) {
			throw new ApiOperationException(Status.INTERNAL_SERVER_ERROR, e, "Fehler beim Erstellen einer Log-Datei für das Schema");
		}

		// Erstelle temporär eine SQLite-Datei aus dem übergebenen Byte-Array
		try (APITempDBFile sqlite = new APITempDBFile(DBDriver.SQLITE, conn.getDBSchema(), logger, log, srcDB, true)) {
			logger.logLn("Importiere in die " + conn.getDBDriver() + "-Datenbank unter " + conn.getDBLocation() + ":");
			logger.logLn(2, "- verwende den Admin-Benutzer: " + conn.getUser().getUsername());
			logger.logLn(2, "- verwende das vorhandene DB-Schema: " + conn.getDBSchema());

			// Erstelle die Quell-DB-Konfiguration für die übergebene Datei
			final DBConfig srcConfig = sqlite.getConfig();

			// Bestimme die Zielkonfiguration aus der SWVS-Konfiguration
			DBConfig tgtConfig = SVWSKonfiguration.get().getDBConfig(conn.getDBSchema());
			final boolean hatSchemaConfig = (tgtConfig != null);
			// Falls das Schema ist in der SVWS-Konfiguration nicht als SVWS-Schema angelegt wurde, dann verwende die Informationen aus der aktuellen Datenbank-Verbindung.
			if (tgtConfig == null)
				tgtConfig = SVWSKonfiguration.get().getRootDBConfig(conn.getUser().getUsername(), conn.getUser().getPassword())
						.switchSchema(conn.getDBSchema());

			try {
				final Benutzer srcUser = Benutzer.create(srcConfig);
				try (DBEntityManager srcConn = srcUser.getEntityManager()) {
					if (srcConn == null) {
						logger.logLn(0, " [Fehler]");
						throw new DBException("Fehler beim Verbinden zur SQLite-Export-Datenbank");
					}
					logger.logLn(0, " [OK]");

					final DBSchemaManager srcManager = DBSchemaManager.create(srcUser, true, logger);
					logger.modifyIndent(2);
					if (!srcManager.backup.importDBInto(tgtConfig, -1, false, logger))
						throw new ApiOperationException(Status.INTERNAL_SERVER_ERROR, simpleResponse(false, log));
					logger.modifyIndent(-2);
				}
			} catch (@SuppressWarnings("unused") final DBException e) {
				throw new ApiOperationException(Status.INTERNAL_SERVER_ERROR, simpleResponse(false, log));
			}

			// Schreibe die Verbindungsinformation für das neu angelegte SVWS-Schema in die SVWS-Konfiguration
			try {
				if (!hatSchemaConfig)
					SVWSKonfiguration.get().createOrUpdateSchema(conn.getDBSchema(), conn.getUser().getUsername(), conn.getUser().getPassword(), false);
			} catch (final SVWSKonfigurationException e) {
				logger.logLn(LogLevel.ERROR, 2, "Fehler bei dem Erstellen bzw. Anpassen der SVWS-Konfiguration (" + e.getMessage() + ")");
				final SimpleOperationResponse daten = simpleResponse(false, log);
				return Response.status(Status.INTERNAL_SERVER_ERROR).type(MediaType.APPLICATION_JSON).entity(daten).build();
			}
		}

		logger.logLn("Import abgeschlossen.");
		final SimpleOperationResponse daten = simpleResponse(true, log);
		return Response.status(Status.OK).type(MediaType.APPLICATION_JSON).entity(daten).build();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy