Zum Hauptinhalt gehen

Datenbank Schema über FirstSpirit löschen

Kommentare

6 Kommentare

  • Zendesk API User
    Author: hoebbel - 7/1/2021 8:10

    Hallo Philipp,

    statt einer Antwort habe ich erst einmal eine Gegenfrage :smileywink:

    Warum willst Du denn das Schema löschen?

    Hintergrund der Frage: Ab einer der nächsten FirstSpirit Versionen (ich hoffe 2021-07, erwarte aber eher 2021-08) wird es beim Löschen eines FirstSpirit Projektes die Möglichkeit geben, die im Projekt benutzten Datenbank-Schemata mit zu löschen.

    Wenn es also "nur" drum geht, die Datenbank beim Löschen eines FirstSpirit Projektes zu bereinigen, wird diese Funktionalität demnächst als Standard zur Verfügung stehen.

    Falls es um etwas anderes geht: Kannst du mal die module.xml zw. module-isolated.xml Datei des Moduls posten und angeben, ob Du das Skript auf dem Server (z.B. als Auftrag) oder in einem Client (SiteArchitect/ContentCreator) ausführst?

    Viele Grüße

    Holger

    0
  • Zendesk API User
    Author: psg - 7/1/2021 8:19

    Hallo Holger,

    vielen Dank für deine Rückmeldung.

    Das Schema soll tatsächlich beim Löschen des Projektes entfernt werden, im Optimalfall auch für ältere Versionen. Daher betrachte ich die zukünftige Funktion mit einem lachenden und einem weinenden Auge. Aber sehr gut, dass das kommen wird!

    Falls du bei der Module.xml auf das scope="server | module" hinaus willst, das habe ich bereits versucht :smileywink:

    Ich lasse das Skript aktuell im Rahmen eines Server-Auftrags laufen, wegen dem eingestellten Server scope. Wenn das im SA funktionieren würde, wäre das noch cooler.

    Viele Grüße

    Philipp

    0
  • Zendesk API User
    Author: hoebbel - 7/1/2021 12:41

    Hallo Philipp,

    bei der module.xml will ich erst einmal sehen, welche Ressourcen eingebunden wurden und ja, auch in welchem Scope. Das wäre schon hilfreich so sheen, ansosten kann an nur raten.

    Wo ich beim raten bin - funktioniert die Datenbank-Verbindung im Datenbanktab auch, wenn in der Konfiguration das Modul nicht angegeben wird (also die Klassen aus dem globalen Serverkontext geladen werden)?

    Wenn nein - bist Du sicher, dass die <resource> im <resources> Tag auf scope="server" gesetzt wurde? (und nicht vielleicht im  <web-resources> Tag, falls es das gibt [wie gesagt, ich bin im Ratemodus :smileywink:] )?

    Viele Grüße

    Holger

    0
  • Zendesk API User
    Author: psg - 7/1/2021 15:09

    Dann will ich dich mal aus dem Ratemodus befreien :smileywink:

    <module>

    <name>PostgreSQL_JDBC_4_2_Driver</name>

    <version>42.2.22</version>

    <description>JDBC Driver for PostgreSQL 8.2 and newer databases</description>

    <vendor>PostgreSQL Global Development Group</vendor>

      

    <resources>

    <resource scope="server">lib/postgresql-42.2.22.jar</resource>

    </resources>

    <components>

    </components>

    <configuration>

    <DRIVER>org.postgresql.Driver</DRIVER>

    <layerclass>de.espirit.or.impl.postgres.PostgreSQLLayer</layerclass>

    </configuration>

    </module>

    Ja, die im Datenbank-Tab habe ich die Konfiguration einmal abgeändert und es funktioniert alles einwandfrei:

    # Projektvorlage_news

    jdbc.DRIVER=org.postgresql.Driver

    jdbc.PASSWORD=secret

    jdbc.SCHEMA=news

    jdbc.URL=jdbc:postgresql:fs5_project

    jdbc.USER=postgres

    jdbc.layerclass=de.espirit.or.impl.postgres.PostgreSQLLayer

    jdbc.property.defaultRowFetchSize=5000

    0
  • Zendesk API User
    Author: hoebbel - 7/2/2021 7:43

    Hallo Philipp,

    ich sehe den Fehler nicht - das muss irgendetwas damit zu tun haben, dass die global gekennzeichneten Libraries aus dem Modul in dem verwendeten Kontext nicht erreicht werden können. Aber warum das so ist, kann ich im Moment nicht sagen :smileysad:

    Mögliche Workarounds, falls ihr eine schnelle Lösung benötigt wären:

    * eigenes Modul schreiben, welches die PostGreSql Klasse mitbringt (Scope=module) und das über ein Executable die Löschoperation ausführt. Das sollte eigentlich funktionieren.

    * die PostGreSql Klasse in den Ordner <FirstSpiritROOT>/shared/lib-isolated legen. Nach einem FirstSpirit Neustart müsste es dann klappen.

    Bitte über den TechSupport entweder das bestehende Ticket oder ein neues Ticket verwenden, um prüfen zu lassen, ob das Ganze möglicherweise ein Bug ist.

    Wie gesagt - ich sehe im Moment den Fehler nicht. Deshalb kann ich auch nicht sicher sagen, ob der erste der möglichen Workarounds so funktionieren wird. Der zweite hat bei mir lokal geklappt.

    EDIT: Ich habe inzwischen etwas nachgeforscht. Das ist ein java Problem, da die Klassen nicht über den System-Classloader geladen werden (wie bei dem zwiten Workaround)

    Wenn man den korrekten ClassLoader angibt, kann man die Klasse laden, also

    myClass = Class.forName("org.postgresql.Driver",true,connection.getClassLoader());

    Das hier hingegen führt zu einer java.lang.ClassNotFoundException: org.postgresql.Driver

    noClass = Class.forName("org.postgresql.Driver");

    --> Ursache ist also JavaSpezifisch/ClassLoaderSpezifisch und kein FirstSpirit Problem im eigentlichen Sinn.

    Viele Grüße

    Holger

    0
  • Zendesk API User
    Author: psg - 7/2/2021 22:53

    Hallo Holger,

    in der Zwischenzeit habe ich mit dem Tech-Support gesprochen und hier kam noch ein altenativer Work-Around bei rum ohne den DriverManager zu nutzen. Mein Skript funktioniert damit super und sieht nun so aus:

    import de.espirit.firstspirit.access.ConnectionManager;

    import de.espirit.firstspirit.access.Connection;

    import java.sql.Driver;

    import java.sql.Statement;

    import java.sql.ResultSet;


    private final String url = "jdbc:postgresql://localhost:5432/fs5_project";

    private final String user = "postgres";

    private final String password = "secret";

    private final String schemaName = "delete_this";

    private final String statement = "DROP SCHEMA " + schemaName + " CASCADE;";


    Properties props = new Properties();

    props.setProperty("user", user);

    props.setProperty("password", password);


    try {

        Connection connection = context.getConnection();

        connection.connect();

        Driver driver = Class.forName("org.postgresql.Driver", true, connection.getClassLoader()).newInstance();

        context.logInfo("Connecting to database."); 

        conn = driver.connect(url, props);

       

        context.logInfo("Check if schema '" + schemaName + "' exists.");

        stmt = conn.createStatement();

        ResultSet rs = stmt.executeQuery("SELECT schema_name FROM information_schema.schemata WHERE schema_name = '" + schemaName + "';");

       

        // Check if there is a first row in the result set

        if (rs.next()) {

            context.logInfo("Sending statement: " + statement);

            stmt.close();

            stmt = conn.createStatement();

            stmt.executeUpdate(statement);

            context.logInfo("Statement executed.");

        } else {

            context.logInfo("Schema '" + schemaName + "' does not exist. Nothing to do.");

        }


    } catch (Exception e) {

        context.logError("Error while database connection: " + e);

    } finally {

        context.logInfo("Closing connection to database."); 

        // stmt.close();

        conn.close();

    }

    Danke für deine Anregungen, die Magie steckt nun letztendlich in diesen Zeilen:

        Driver driver = Class.forName("org.postgresql.Driver", true, connection.getClassLoader()).newInstance();

        conn = driver.connect(url, props);

    Es ist hier zwingend erforderlich auf den DriverManager zu verzichten, da trotz der erfolgreich geladenen Klasse "org.postgresql.Driver" diese schlichtweg nicht gefunden wird (wieso auch immer?!?). Das wieso habe ich an den Tech-Support weitergegeben. Mir persönlich reicht aber der Work-Aorund so mehr als aus :smileyhappy:

    Viele Grüße

    Philipp

    0

Bitte melden Sie sich an, um einen Kommentar zu hinterlassen.