Archiv für die Kategorie ‘PostgreSQL’

PostgresSQL String Konstanten / Dateien namens “con.xyz”

Montag, 05. Juli 2010

Mein Ziel war es, korrupte javascript-RegEx Ausdrücke durch neue Ausdrücke zu ersetzen. Das Problem dabei waren die Zeichen, die ein Escaping benötigen, um den String(character varying) in eine Postgres DB einfügen zu können. Bei recht komplexen Ausdrücken eine umständliche Arbeit, die Zeichen einzeln zu “escapen”. Das ganze kann man sich aber folgendermaßen ersparen:

UPDATE testtabelle
SET textfeld = $stringconstant$Text mit vielen /^'\" $$stringconstant$
WHERE id = 4711;

Das ganze nennt sich “Dollar-Quoted String Constants”. Der String wird also zwischen zwei voranführenden und zwei endenden Dollarzeichen verpackt: $$ SomeCharacters/\^’#” $$ . Zwischen den Dollarzeichen kann, wie im obigen Beispiel, ein Tagname angegeben werden, um so z.B. auch verschachtelte Strukturen zu ermöglichen.

$outerTag$
someText $innerTag$ otherText $innerTag$
$outerTag$

Ein ganz anderes Thema…

Bei dem Versuch eine csv-Datei aus Java heraus anzulegen, flog eine Exception, nach ein bischen Verzweiflung und “googeln” kam heraus, dass der Name der Datei con.csv das Problem verursachte.
WindowsXP verbietet das Anlegen jeglicher Dateien mit Namen “con” gefolgt von einem Punkt oder einem Leerzeichen. Ärgerlich aber nicht umgehbar, angeblich ein Überbleibsel aus den alten MS-Dos Zeiten.


Sven Seiler


RoR-Migrations und PostgreSQL-Datentypen

Montag, 01. März 2010

Migrationsskripte sind in Ruby on Rails das Konzept, um die Entwicklung von Datenbanken im Verlaufe der Produktentwicklung zu verwalten und zu steuern. Da es sich bei ihnen um Ruby-Skripte handelt, steht einem auch der volle Funktionsumfang von Ruby on Rails zur Verfügung.
Ein Hauptprinzip der Migrationsskripte ist deren Datenbankneutralität. Sie soll es ermöglichen, mit möglichst geringem Aufwand die Datenbank wechseln zu können. Dies geht auf Kosten der Unterstützung spezieller Datenbank-Features.
Arbeitet man nun mit einer PostgreSQL-Datenbank und möchte man seine Spalten auch mit PostgreSQL-spezifischen Datentypen versehen, so kann man das wie folgt bewerkstelligen:

In der Methode “native_database_types” der Klasse “ActiveRecord::ConnectionAdapters::PostgreSQLAdapter” werden die Mappings für die SQL-Datentypen definiert, die von den Migrationsskripten im Zusammenhang mit einer PostgreSQL-Datenbank benutzt werden. Genau diese Methode kann man nun überschreiben, um die Mappings anzupassen.

class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
def native_database_types
{
:primary_key => "bigserial primary key",
:string      => { :name => "character varying", :limit => 255 },
:text        => { :name => "text" },
:integer     => { :name => "integer" },
:float       => { :name => "float" },
:datetime    => { :name => "timestamp" },
:timestamp   => { :name => "timestamp" },
:time        => { :name => "time" },
:date        => { :name => "date" },
:binary      => { :name => "bytea" },
:boolean     => { :name => "boolean" },
:bigint      => { :name => "int8" }
}
end
end

Nun kann man diese Definition beispielsweise in psql_ext.rb im lib-Verzeichnis speichern und sie per require ‘psql_ext’ in die Migrationsskripte einbinden.


Christian Borkowski


Erfahrungen mit Hibernate-Criteria und pgAdmin(postgres)

Montag, 15. Februar 2010

Wärend der Arbeit an einer Web Applikation, die Hibernate und eine PostgresDB verwendet, sind mir in letzter Zeit folgende Kleinigkeiten aufgefallen:

Hinzufügen von “Nicht NULL” Spalten im pgAdmin III

Möchte man mit dem pgAdmin III Tool nachträglich eine Spalte zu einer Tabelle hinzufügen, so öffnet man den entsprechenden Dialog z.B. über das Menü “Bearbeiten -> Neues Objekt -> neue Spalte”. Wir versuchen nun eine Spalte “darfAngeln” vom Typ “boolean” anzulegen. Diese soll keine “null”-Werte enthalten und als Standardwert “false” benutzen. Das ganze funktioniert solange, wie noch keine Einträge in der Tabelle existieren. Enthält die Tabelle allerdings Einträge, erhalten wir folgende Fehlermeldung:

Ein Fehler ist aufgetreten:
FEHLER: Spalte >darfAngeln< enthält NULL-Werte

Die Fehlermeldung läßt sich umgehen, indem man das Anlegen der Spalte per simplem SQL erledigt. Ins Query Fenster des pgAdmin wechseln und folgenden Code ausführen:

ALTER TABLE adm_raum_art
ADD COLUMN darfAngeln boolean NOT NULL DEFAULT false;

Punkt-Notation bei Criteria

Leider mußte ich durch eine Exception feststellen, dass die Verwendung der Punkt-Notation (implizite Erzeugung von Joins) zum Zugriff auf verknüpfte Objekte nicht möglich ist (im Gegensatz zu HQL). Um also Restrictions auf verschiedenen, assozierten Objekten “oder” verknüpfen zu können, bedarf es “createAlias” für die Erzeugung von expliziten Joins. Kleines Beispiel:

final Criteria criteria = getSession().createCriteria(Schule.class);
criteria.createAlias("schulAnsprechpartner", "schulAP", Criteria.LEFT_JOIN)
.createAlias("schulAP.person", "pers", Criteria.LEFT_JOIN)
.createAlias("pers.benutzer", "benutzer", Criteria.LEFT_JOIN)
.add(Restrictions.or(Restrictions.eq("darfAngeln", true),
Restrictions.eq("benutzer.id", 0815)));

Im Beispiel wurde nun doch die Punkt-Notation verwendet, allerdings immer nur mit der “Rekursionstiefe 1″.
Vielleicht kommt irgendwann auch für Criteria die Möglichkeit eine beliebige Tiefe zu verwenden.


Sven Seiler


PostgreSQL-Funktionen mit ANT einspielen

Mittwoch, 12. August 2009

Um eine Datenbank auf dem aktuellen Stand zu halten, bietet sich ANT mit dem Task sql an. Hiermit ist es ein leichtes viele SQL-Skripte effektiv in die Datenbank einzuspielen:

<sql
    driver="org.database.jdbcDriver"
    url="jdbc:database-url"
    userid="sa"
    password="pass"
    src="data.sql"/>

Der Lösung so nah

Dies funktioniert soweit sehr gut, es sei denn man versucht Funktionen in die Datenbank einzuspielen. ANT kann leider nicht mit den Semikoli (;) in der Funktion richtig umgehen; so wird davon ausgegegangen das jedes Semikolon ein Statement beendet. Dies trifft beim Einspielen einer Funktion natürlich nicht zu. Hierfür bietet ANT eine schnelle Lösung mit dem Attribute “delimiter” am sql-Task. In dem folgenden Beispiel wird der Default-Delimiter (;) durch “$$” ersetzt.

<sql
    driver="org.database.jdbcDriver"
    url="jdbc:database-url"
    userid="sa"
    password="pass"
    src="data.sql"
    delimiter="$$"/>

Einfacher Fall

Das SQL der einzuspielenden Funktion für PostgreSQL sollte in etwa wie folgt aussehen:

CREATE OR REPLACE FUNCTION hello_world() RETURNS void AS '
BEGIN
    -- Aktionen der Funktion
END;
' LANGUAGE 'plpgsql' $$

Das SQL-Statement erstellt eine Funktion ohne Rückgabewerte, definiert danach die verwendete Sprache und beschliesst das Statement mit dem Delimiter ($$).
Ein kleines aber sehr wichtiges Detail sind hierbei die Hochkomma (’) hinter dem AS und vor dem LANGUAGE. Auch wenn bei der Verwendung von PgAdmin fast jede beliebiege Zeichenkette dort stehen kann sollte bei der Verwendung von ANT nur das Hochkomma verwendet werden, so das der JDBC den Inhalt der Funktion als Text auffasst und nicht versucht den Inhalt zu interpretieren.

Komplexer Fall

Doch was tun, wenn innerhalb der Funktion Texte verwendet werden, die selbst mit einem Hochkomma (’) eingefasst sind. In diesem Fall muss man darauf achten, das alle Hochkommas innerhalb der Funktion mit einem Hochkomma “escaped” werden.

CREATE OR REPLACE FUNCTION hello_world() RETURNS void AS '
BEGIN
    insert into my_table (text) values (''hello'');
END;
' LANGUAGE 'plpgsql' $$

Thomas Bader