PHP: Text File Database Manual

Php Text Database API Manual

Copyright (C) 2005 by c-worker.ch

Die Txt-Db-API bietet die Möglichkeit auf normale Text Files wie
eine SQL Datanbank zuzugreiffen.
So wird auf dem Webserver kein spezielles Datenbanksystem benötigt.

Mit der API kann man über SQL Tabellen erstellen, abfragen, ändern, löschen, u.s.w.
Dabei muss man sich nie selbst mit den Text-Files befassen, sondern
kann alles durch API aufrufe erledigen lassen.

Die Txt-Db-API ist objektorientiert aufgebaut und sehr einfach zu benutzen.

Man hat die Möglichkeiten unbegrenzt viele Datanbanken (als Ordner dargestellt) und
Tabellen zu benutzen.

Aber Version 0.2.2-Beta-01 steht die Text Db API unter einer BSD Lizenz

--

Bitte folgende Dokumente zuerst lesen:

Installation
Aufbau/Struktur/Die API verstehen und benutzen

--

Version: 0.3.1-Beta-01
(Hilfe Version entspricht immer der API Version)

Neuste PHP Version mit welcher die API funktioniert: 5.0.3
Mindestens benötigte PHP Version: 4.1.0 (bin mir nicht so sicher)

Latest Version and additional Infos:


Rechtliche Hinweise

Ich übernehme keine Verantwortung oder Haftung für Probleme oder Schäden
die durch dieses Manual oder die Txt-Db-Api entstehen könnten.
Die Anleitung und auch die Txt-Db-Api sind immer noch
in Entwicklung und unter umständen noch sehr fehlerhaft !

Lizenz:

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.


Neues

Neues in der Txt-db-api (Changelog)

Da das Changelog in Englisch ist werde ich von nun an hier einige wichtige Änderungen der
Txt-db-api kurz aufführen.

Neu seit Version 0.3.1-Beta-01

Unterstützung für IN und NOT IN (es können Zahlen oder Strings verwendet werden)

Unterstützung für JOINS (LEFT [OUTER], RIGHT [OUTER] und INNER)

Das tbedit Script (ein Script um Tabellen zu bearbeiten) ist jetzt im Release inbegriffen.
Es kann mit der URL webgui/tbedit.php gestartet werden oder über einen Link im WebGUI.

Unterstützung für COUNT(*) und COUNT(table.*) SELECT Queries

Für mehr siehe changelog.txt...


Installation

Seit den 0.3.x Versionen beinhaltet das Text-DB-Api Zip nicht mehr nur die 8
Hauptfiles und das Manual, neu sind auch das WebGUI und der Table Editor integriert.
Um die Text-DB-API zu verwenden reicht es nachwievor die 8 .php Files
auf den Webserver zu laden und die txt-db-api.php Datei anzupassen.
Diese Installation ist weiter unten unter "Manuelle Installation" beschrieben.

Seit den 0.3.x Versionen hat man aber auch die Möglichkeit die API und die
dazugehörenden GUI's mit einem Assistenten (installer.php) zu installieren und
konfigurieren zu lassen. Das Skript installer.php kann von der Sourceforge Seite SEPARAT
heruntergeladen werden.
Für die Installation lädt man das Text-DB-API Zip und das installer.php
Skript auf den Webserver und zwar ins GLEICHE Verzeichniss. Nun muss man nur noch
das installer.php Skript aufrufen und der Assistent leitet einen durch die Installation
welche soweit selbsterklärend ist.

Manuelle Installation

Upload der Dateien:

Alle Php-Dateien der Txt-Db-Api sind in ein (und das gleiche) Verzeichnis hochzuladen.

Ändern der Datei txt-db-api.php

Die Datei txt-db-api.php ist vor dem upload anzupassen. In dieser Datei sind
die beiden Variabeln $API_HOME_DIR und $DB_DIR auf den richtigen Wert zu
setzten:

$API_HOME_DIR:
Diese Variable muss auf den absoluten oder relativen Pfad zu den Txt-Db-Api Dateien zeigen.
z.B. /home/c-worker.ch/public_html/php-api/
Für mehr Infos zur Pfadangabe siehe unten.

$DB_DIR:
Diese Variable muss auf den absoulten oder relativen Pfad zeigen, unter welchem sich die Datenbank
Ordner befinden. Hat man zB einen Datenbank Ordner unter /home/c-worker.ch/dbs/TestDB
so muss man $DB_DIR auf /home/c-worker.ch/dbs/ setzten. Im Ordner /home/c-worker.ch/dbs/
können nun beliebig viele Datenbank-Ordner erzeugt werden.

Wichtig: Die Datei txt-db-api.php ändert sich nicht in neuen Versionen. Ihr braucht also NICHT bei
jeder neuen Version die Datei txt-db-api.php zu überschreiben und zu ändern. Behaltet einfach
die alte! Falls sie sich mal ändern sollte wir das im changelog und unter den news deutlich stehen!

Absolute oder relative Pfade für API_HOME_DIR und DB_DIR

Grundsätzlich hat man zwei Möglichkeiten die Verzeichnisse in den $API_HOME_DIR und $DB_DIR Variabeln
anzugeben. Man kann entweder relative (relativ zum Verzeichniss der Datei welche "txt-db-api.php" include't)
oder absolute Verzeichnisse (relativ zum Server root) verwenden.

Wenn man eine absolute Pfadangabe verwendet, so beötigt man nur eine txt-db-api.php - Datei.
Diese sollte man bei den andern Dateien der Text-Db-Api platzieren.
Dies ist auch der Standard-Ort der Datei nach dem extrahieren des Zip-Files.

Falls man eine relative Pfadangabe verwendet, ist es SEHR EMPEHLENSWERT für jedes Projekt eine
eigene txt-db-api.php - Datei zu verwenden. Diese plaziert man dann direkt im Ordner des jeweligen
Projektes. Dies ist deshalb nötig, da unterschiedliche Projekte einen anderen Relativen Pfad zur
API und zum Datanbank-Verzeichniss haben können. Mann muss nun natürlich darauf achten, auch
das entsprechende txt-db-api.php file zu includen, also dasjenige welches nun im Projekt Ordner liegt.
So muss nun jedes Projekt sein eigenes txt-db-api.php file includen, welches im gleichen Pfad wie
das Projekt liegt.
Im Ordner der API (dort wo Database.php, etc.) benötigt man dann eigentlich keine txt-db-api.php Datei mehr.

Natürlich kann man auch bei absoluten Pfaden für jedes Projekt ein eigenes txt-db-api.php File verwenden.
Dies könnte z.B. dann nützlich sein wenn die jeweiligen Projekte einen unterschiedlichen Datenbank-Root
Ordner haben.


PHP: Text File Database Manual

Struktur / Aufbau der Datenbanken

Grundsätzlich wird eine Datenbank durch ein Verzeichnis repräsentiert.
Die Datenbank hat den gleichen Namen wie das Verzeichnis.
Alle Datenbank-Verzeichnisse müssen sich im gleichen Verzeichnis befinden,
und dieses wird durch die Einstellung $DB_DIR in der Datei txt-db-api.php
festgelegt.

Kleines Beispiel:

Wurde $DB_DIR auf den Wert "/home/websites/myhome/Databases/" gesetzt
so können sich die Datenbanken bzw. Ordner nun unter /home/websites/myhome/Databases/
befinden.

Möchte man eine Datenbank mit dem Namen "MeineDB" haben so erstellt man den Ordner
/home/websites/myhome/Databases/MeineDB.
Damit die Datenbank-Dateien nicht mit dem Browser direkt angesehen werden können, ist es empfehlenswert die .htaccess Datei in diesem Ordner entsprechend zu verändern, dass mit GET und POST kein Zugriff auf die Txt-Dateien möglich ist.

Natürlich kann $DB_DIR zum lokalen testen auf einer Windows Maschine auf Laufwerke
enthalten, zB "C:\meineWebseiten\blabla\Datenbanken\".

Wenn man nun SQL-Statements auf die Datenbank MeineDB absetzen möchte so
muss man zuerst ein Datebase Objekt erzeugen, und im Konstruktor den Namen
der Datenbank (also den Namen des Verzeichnisses) angeben.
Für das Beispiel von oben sähe das folgendermassen aus:

$db=new Database("MeineDB");

ACHTUNG: bei den Datenbank-Namen (also dem Verzeichniss) wird die GROSS-klein-Schreibung
BERÜCKSICHTIGT !! (case sensitive).

Nun kann man auf der Variable $db Sql Statements absetzten.
Als ersten Schritt könnte man zB eine Tabelle "Personen" erzeugen:

$db->executeQuery("CREATE TABLE personen (nr inc, vorname str, nachname str, alter int)");

Tabellen können auch ohne SQL-Statement, manuell erstellt werden.

Tabellen werden als .txt Files im Ordner der Datenbank repräsentiert. Was aber weniger Wichtig ist, theoretisch lässt sich mehr oder weniger alles machen, ohne dass man die .txt Files je anfassen muss.

Wichtig ist nur: Alle Datenbanken sind eigentlich Verzeichnisse welche sich im Verzeichnis $DB_DIR
befinden müssen !!

WICHTIG: Dieses Verzeichnis muss auch von Hand (z.B. via FTP erzeugt werden)! NICHT vergessen die Berechtigungen
des Verzeichnisses via FTP zu ändern (chmod()), ansonsten können keine Tabellen (also Dateien) im entsprechenden
Ordner erzeugt werden und CREATE TABLE schläg fehl.

NOCH ein Beispiel:

Die Webseite (also die HTML Dateien) sind unter /home/website/myPage/

Die API Files sind unter /home/website/myPage/txt-db-api/

Der Ordner der die Datenbanken hält ist /home/website/myPage/Datanbanken

Es sind zwei Datenbanken installiert (TestDatenbank und ProdDatenbank), somit existieren
folgende Verzeichnisse:

/home/website/myPage/Datanbanken/TestDatenbank/
und
/home/website/myPage/Datanbanken/ProdDatenbank/

Bei diesen wurde mit chmod die entsprechende Berechtigungen gesetzt (zB 777).

Bei dem oben erwähnten Beispiel würden die Einstellungen in txt-db-api.php so aussehen:

$API_HOME_DIR="/home/website/myPage/txt-db-api/";
$DB_DIR="/home/website/myPage/Datanbanken/";

Ein PHP Script im Ordner /home/website/myPage/ würde dann so beginnen

<? php
include("txt-db-api/txt-db-api.php");
.....


Konfiguration

In der Datei const.php können einige Einstellungen vorgenommen werden. Dies ist jedoch nicht zwingend nötig
da man auch die Standardwerte verwenden kann. Man findet die Einstellungen in der Form von Variabeln
in der Datei const.php nach dem Kommentar "User Settings".

Einstellung | Standardwert | Beschreibung
DEBUG | 0 | Wenn man DEBUG auf 1 setzt, so gibt die API zusätzliche Debug Informationen aus. Wenn Ihr ein Problem habt oder einen Bug-Report machen wollt können diese Informationen z.T. hilfreich sein.
LIKE_CASE_SENSITIVE | 0 | Wenn man diese Einstellung auf 1 setzt, so unterscheidet LIKE GROSS- und kleinschreibung. Wenn auf 0 gesetzt wird dazwischen nicht unterschieden.
ORDER_CASE_SENSITIVE | 0 | Wenn auf 1 gesetzt, wird beim sortieren von Datensätzen mit ORDER BY die GROSS-kleinschreibung unterschieden. D.h. GROSSBUCHSTABEN kommen vor kleinbuchstaben (P -> X -> a -> b). Wenn auf 0 gesetzt, wir GROSS-kleinschreibung beim sortieren NICHT unterschieden (a -> b -> P -> X)
ASSUMED_RECORD_SIZE | 30 | Setzt diesen Wert auf die Ungefähre Durschnittsgrösse eines Datensatzes. Dieser Wert wird intern verwendet, und wenn er weise gewählt wurde kann das positive auswirkungen auf die Performance haben. NICHT auf 0 setzten! Wenn du dir nicht sicher bist lass einfach den Standardwert!! Diese Einstellung ist NICHT als Begrenzung für die Datensatzgrösse gedacht. Eine solche Begrenzung gibt es nicht!
PRINT_ERRORS | 1 | Wenn auf 1 gesetzt werden Fehler angezeigt, andernfalls werden sie unterdrückt. Sofern man keine dynamischen SQL-Statements verwendet, weisen Fehler immer auf ein Fehler des Entwicklers hin, also besser auf 1 lassen! Ausser man erzeugt seine SQL Statement dynamisch...
PRINT_WARNINGS | 0 | Wenn auf 1 gesetzt werden Warnungen angezeigt, andernfalls werden sie unterdrückt.


PHP: Text File Database Manual

Sicherheit

Damit die Tabellen Files von der text-db-api gelesen und geschrieben werden können ist es meist nötig, dass man den Tabellen Files und der Verzeichnissen in denen sie liegen mit chmod die entsprechenden rechte gibt.
Das führt jedoch zu dem Problem, dass wenn jemand den Ort eines Tabellen Files weis, er in der Lage dazu ist dieses direkt im Browser einzugeben und somit anzusehen. Das kann bei vertraulichen Daten natürlich sehr störend sein.
Um das zu verhinden, kann man im Verzeichniss wo die Tabellen Files liegen einfach ein .htaccess File erstellen mit folgendem Inhalt:

<Files>
Order deny,allow
Deny from all
</Files>

Und schon ist es nicht mehr möglich die Tabellen Files direkt über den Browser anzusehen.
Mehr über .htaccess Files findet man im Internet


Txt-db-api mit PEAR verwenden

Im Verzeichnis pear findet man seit neustem eine Datei txtdbapi.php.
Dabei handelt es sich um einen Text-Db-Api Datenbankwrapper für PEAR.

Installation

Diese Datei wird zu den anderen Datenbankwrappern in das Verzeichnis

/usr/share/php/DB/ (üblich bei *nix installationen) oder <php-installation>/PEAR/DB (auf windows) kopiert werden.

Der connect-String für die Txt-Db-Api sieht folgendermassen aus:
txtdbapi://localhost/<dbname>

Beispiel

So könnte dann eine Beispiel Datenabfrage aussehen:
Code:
<?

include "DB.php";
include "txt-db-api.php";

$dbc = DB::connect("txtdbapi://localhost/soulspring");
//$dbc = DB::connect("mysql://user:password@localhost/soulspring");

$dbc->setFetchMode(DB_FETCHMODE_ASSOC);

// Einfacher SELECT mit Ausgabe
$result = $dbc->query("SELECT * FROM news");

if (PEAR::isError($result)) {
print $result->getUserInfo();
}

if ($result->numRows()) {
$row = array();
while($row = $result->fetchRow()) {
print_r($row);
}
} else {
print "No results available\n";
}

// Test für UPDATE und affectedRows()
$dbc->query("UPDATE news SET titel = 'Txt-Db-Api goes PEAR' WHERE id = '5' ");
print "Affected Rows: " . $dbc->affectedRows();

// Andere Tests:
// getAll() liefert alle Datensätze
// getCol() liefert nur eine bestimmte Spalte (0=erste Spaltem, 1=zweite, ...)
print_r($dbc->getAll("SELECT * FROM programm", null, DB_FETCHMODE_ASSOC));
print_r($dbc->getCol("SELECT * FROM programm", 1));

$dbc->disconnect();

?>

Wenn der andere connect string oben auskommentiert wird, dann läuft das ganze ohne Problem unter MySQL, oder auch anderen Datenbanken.

Wenn man keinen Zugriff auf das PEAR verzeichnis hat (wie bei vielen Webprovídern), dann reicht es GLAUB ich auch, nur folgende Dateien auf den Server zu laden:
Code:
WEB-ROOT
|
|--include
| |
| `-- DB
| |
| |-- common.php
| |-- storage.php
| `-- txtdbapi.php
|-- DB.php
`-- PEAR.php

Im code kann man dann das PEAR::DB Modul so einbinden:
include "/include/DB.php"

Dieser Workaround ist noch Experimentell. Der Entwickler legt für diesen Workaround nicht seine Hand ins Feier ;-)
Probiert es einfach mal aus.


SQL Syntax (Einschränkungen für Txt-Db-Api)

SQL Syntax der Txt-Db-Api (Einschränkungen)

Allgemein

Die Txt-Db-Api unterstützt nicht den ganzen SQL-Sprachumfang, der unterstützte Umfang sollte jedoch
mit dem SQL Standard kompatibel sein.
Nachfolgend sind die Einschränkungen bzw. die Syntax für SQL Statements was die Txt-Db-Api betrifft aufgeführt.
Werte in [] sind freiwillig, "..." bedeutet das beliebig viele weitere Elemente folgen können,
| heisst das entweder der eine ODER der andere wert genommen werden kann.

Achtung: Wie auch im Standard definiert, sollten Werte für str (String) Felder immer in die
Anführungszeichen ' ' oder " " eingeschlossen werden!

SELECT

Syntax

SELECT [DISTINCT]
[funktion(][tabelle.]spalte[)] [AS alias_name] [, [funktion(][tabelle].spalte[)] [AS alias_name] , ...]
FROM tabelle [AS tabellen_alias] [, tabelle2 [AS tabellen_alias], ... ]
[[LEFT|RIGHT|INNER] [OUTER] JOIN [tabelle] ON tabelle2, ... ]
[WHERE spalte=wert AND|OR spalte=spalte AND|OR ...]
[GROUP BY spalte, ...]
[ORDER BY spalte [ASC | DESC] ,...]
[LIMIT [offset,]anzahl] [;]

Unterstützt

- Siehe Syntax

- Anstelle von Spaltennnamen (spalte in der Syntax oben) können auch direkte Werte verwendet werden.
Das können entweder Zahlen oder Strings in ' ' oder " " sein, z.B. SELECT 1234, 'bla', name FROM personen;

- Folgende Funktionen: UNIX_TIMESTAMP(), MD5(spalte), NOW(), ABS(spalte), LCASE(spalte), UCASE(spalte), LOWER(spalte), UPPER(spalte), EVAL(spalte *-+/ wert|spalte.....)
- Die oben genannten Funktionen werden auch bei WHERE, GROUP BY und ORDER BY unterstützt
- Folgende gruppierenden Funktionen: MAX(spalte), MIN(spalte), COUNT(spalte), SUM(spalte), AVG(spalte)
- Anstelle einer spalte kann man für Funktionen auch direkte Werte als Parameter angeben, z.B. md5('bla')

- * anstelle von Feldnamen
- tabelle.* anstelle von Feldnamen, auch Kombinationen möglich z.B. SELECT personen.*, firma.Name, ort.* ...
- SELECT COUNT([table.]*)
- Aliase für Tabellen

- Im WHERE Teil werden folgende Vergleichsoperatoren unterstützt: =,>,<,>=,<=, !=, <>, LIKE / NOT LIKE (wildcards % und _), IN / NOT IN
- Im WHERE Teil kann entweder feld=wert, wert=wert oder auch feld=feld stehen
(um tabellen verknüpft abzufragen, wie z.B. im Beispiel unten "personen.typ_id = typen.id")
"=" steht hier nur als Beispiel, für Feld=Feld sind alle oben genannten Vergleichsoperatoren möglich
- Im WHERE Teil können beliebige viele AND und OR verwendet werden
- Im WHERE Teil können beliebig viele Klammern verwendet und verschachtelt werden

- JOIN's (INNER, LEFT [OUTER] und RIGHT [OUTER])
- DISTINCT: nur zeilen die sich eindeutig von andern unterscheiden werden zurückgegeben
- GROUP BY: ergebniss nach den angegebenen spalten gruppieren.

- LIMIT (nur bei SELECT): offset ist ein offset beginnend bei 0 (d.h. ein offset 1 startet bei der 2. Reihe),
welches angibt ab welcher Reihe man das Ergebnis auf anzahl Zeilen limitieren möchte.
Wenn man ein LIMIT angibt so ist anzahl obligatorisch, das offset kann auch weggelassen werden.
Beispiel: LIMIT 4,10 (Liefert nur die Zeilen von 5 bis und mit 14 zurück => Anzahl = 10)

- Bei DISTINCT und GROUP BY wird immer der erste wert genommen,
Beispiel: "SELECT time, ip FROM log GROUP BY time"

time | ip
10348395 | 192.168.0.1
10348395 | 192.168.0.3
>
 time | ip
10348395 | 192.168.0.1

Nicht unterstützt

- Zusammenfügen von Feldern wie zB SELECT name & " " & vorname AS ganzer_name oder
SELECT name + vorname AS ganzer_name
- Alles was nicht irgendwie unter Syntax oder Unterstützt zu finden ist

Beispiele

SELECT vorname, personen.nachname, typen.typ AS personen_typ FROM personen, typen
WHERE personen.typ_id = typen.id AND (personen.Nr>=10 OR personen.vorname='Hans')
ORDER BY vorname LIMIT 100

SELECT COUNT(t.name), AVG(t.alter) AS durchschnittsalter, k.name FROM teilnehmer AS t, kurs AS k
WHERE t.kurs_nr=kurs.id GROUP BY k.name;

SELECT md5('bla');

Hinweise

ACHTUNG: Vor und nach jedem OR oder AND müssen je ein Leerschlag (" ") stehen.
Dies damit der Parser genau zwischen AND und OR's die eventuell zu Feldnamen gehören
oder AND und OR's die als Teil der Logik gemeint sind, unterscheiden kann !
Das gleiche gilt für LIKE!

Ungültig: Name='Test'OR Nr>20
Gültig: Name='Test' OR Nr>20

ACHTUNG: Benutzt LIKE nur wenn es zwingend nötig ist, da LIKE viel langsamer ist als ein
normaler String-Vergleich. Wenn man also alle Datensätze Abfragen will wo der ort genau 'Basel'
ist sollte man es so machen: SELECT * FROM tabelle WHERE ort='Basel'
und NICHT so: SELECT * FROM tabelle WHERE ort LIKE 'Basel'
und schon GAR NICHT so: SELECT * FROM tabelle WHERE ort LIKE '%Basel%'

INSERT

Syntax

INSERT [INTO] tabelle [(spalte1, spalte2, spalte_n, ...)]
VALUES  (  [funktion(]wert[)]  [, funktion[(]wert2[)], wert_n, ...]) [;]
    oder
INSERT [INTO] tabelle
SET spalte= [funktion(] wert [)]  [, spalte2=[funktion(]wert2[)], spalte_n=[funktion(]wert_n[)], ...] [;]

Unterstützt

- Siehe Syntax
- Folgende Funktionen: UNIX_TIMESTAMP(), MD5(wert), NOW(), ABS(wert), LCASE(wert), UCASE(wert), LOWER(wert), UPPER(wert)
- Als Parameter für die Funktionen werden hier logischerwesie nur Werte und keine Spalten unterstützt.

Nicht unterstützt

- INSERT mit SELECT
- Mehrere Datensätze einfügen (in einem SQL Statement)
- Gruppierende Funktionen wie zB MAX(), MIN() etc. (was auch gar keinen Sinn machen würde!)
- Alles was nicht irgendwie unter Syntax zu finden ist

Beispiele

INSERT INTO personen (vorname, nachname) VALUES ('hans','meier');

INSERT INTO passwords (user, password) VALUES ( 'user1', md5('mypassword') );

INSERT INTO personen SET vorname=upper('hans'), alter=abs(-55), eingetragen=NOW() ;

DELETE

Syntax

DELETE FROM tabelle [WHERE <gleich wie bei SELECT>] [;]

Unterstützt

- Siehe Syntax
- Das löschen der ganzen Tabelle (kein WHERE angeben)
- Für den WHERE Teil gilt das gleiche wie bei SELECT (funktionen werden also auch unterstüzt!)

Nicht unterstützt

- LIMIT
- Alles was nicht irgendwie unter Syntax zu finden ist

Beispiele

DELETE FROM personen WHERE vorname='Hans';

DELETE FROM personen WHERE passwort=md5('mypw') AND abs(alter)=abs(-5);

UPDATE

Syntax

UPDATE tabelle SET spalte=[funktion(]wert[)] [,spalte2=[funktion(]wert2[)], spalte_n=[funktion(]wert_n[)], ...]
[WHERE <gleich wie bei SELECT>] [;]

Unterstützt

- Siehe Syntax
- Folgende Funktionen für die Werte: UNIX_TIMESTAMP(), MD5(spalte oder wert), NOW(), ABS(spalte oder wert),
LCASE(spalte oder wert), UCASE(spalte oder wert), LOWER(spalte oder wert), UPPER(spalte oder wert), EVAL(spalte *-+/ wert|spalte.....)
- Updaten der ganzen Tabelle (kein WHERE angeben)
- Zuweisen des Wertes einer Spalte an eine andere
- Für den WHERE Teil gilt das gleiche wie bei SELECT (funktionen werden also auch unterstüzt!)

Nicht unterstützt

- LIMIT
- ORDER BY
- Alles was nicht irgendwie unter Syntax zu finden ist

Beispiele

UPDATE personen SET vorname='Hans2000' WHERE vorname='Hans';

UPDATE personen SET vorname=nachname WHERE vorname='Hans';

UPDATE personen SET passwort=md5(passwort);

UPDATE personen SET alter=abs(-20), name=upper(name);

CREATE TABLE

Syntax

CREATE TABLE tabellen_name (spalten_name  typ [DEFAULT 'defaultWert'] [, spalten_name2  typ2 [DEFAULT 'defaultWert'], ... ]) [;]

Unterstützt

- Siehe Syntax
- DEFAULT (Den Defaultwert in ' ' setzten, auch bei Zahlen)
- Wenn für eine inc Spalte ein Defaultwert gesetzt wurde, so sind die inc Werte des ersten
Datensatzes Defaultwert+1. Für alle weiteren Spalten wird der Defaultwert ignoriert.

Nicht unterstützt

- Alles was nicht irgendwie unter Syntax zu finden ist !!
- Nur folgende Syntax (spalten_name typ , spalten_name typ , ....)
und sonst kein einiziges Keyword (ausser DEFAULT)!!
- SQL Standardtypen, typ kann nur inc (AutoWert), int (Zahl) oder str (Text) sein.

Beispiel

CREATE TABLE personen (id inc, vorname str DEFAULT 'john' , nachname str);

DROP TABLE

Syntax

DROP TABLE tabelle1 [, tabelle2, ...][;]

Unterstützt

- Siehe Syntax
- 1 oder mehrere Tabellen gleichzeitig löschen

Nicht unterstützt

- Alles was nicht irgendwie unter Syntax zu finden ist !!

Beispiel

DTOP TABLE personen;

LIST TABLES

Syntax

LIST TABLES [WHERE ...]
[GROUP BY spalten_name, ...]
[ORDER BY spalten_name [ASC | DESC] ,...]
[LIMIT [offset,]anzahl] [;]

Unterstützt

- Siehe Syntax
- Gibt alle Tabellen einer Datenbank als ResultSet Objekt zurück. Dieses ResultSet hat eine Spalte
Namens "table" welche den Tabellennamen als String enthält
- Für WHERE, GROUP BY, ORDER BY und LIMIT Syntax siehe SELECT

Nicht unterstützt

- Alles was nicht irgendwie unter Syntax zu finden ist !!
- Funktionen

Beispiel

LIST TABLES;

CREATE DATABASE

Syntax

CREATE DATABASE datanbank_name [;]

Unterstützt

- Siehe Syntax
- Nur eine Databank kann mit einem Statement erzeugt werden.
- Dieses Statement sollte NUR auf einer ROOT_DATABASE Datanbank ausgeführt werden.
Man erhält diese mit einem $db=new Database(ROOT_DATABASE); aufruf.
ROOT_DATABASE ist eine definierte Konstante.

Nicht unterstützt

- Alles was nicht irgendwie unter Syntax zu finden ist !!

Beispiel

CREATE DATABASE meineDatenbank;

DROP DATABASE

Syntax

DROP DATABASE datanbank_name [;]

Unterstützt

- Siehe Syntax
- Nur eine Databank kann mit einem Statement gelöscht werden.
- Dieses Statement sollte NUR auf einer ROOT_DATABASE Datanbank ausgeführt werden.
Man erhält diese mit einem $db=new Database(ROOT_DATABASE); aufruf.
ROOT_DATABASE ist eine definierte Konstante.

Nicht unterstützt

- Alles was nicht irgendwie unter Syntax zu finden ist !!

Beispiel

DROP DATABASE meineDatenbank;


Escape Zeichen

Für den SQL-Parser der php-txt-db-api müssen einige Zeichen escaped werden.
Darunter versteht man das voransetzten des Zeichens \ (Backslash).
Das ist nötig, damit in einem String enthaltene " als solche erkannt werden
Somit wird zB folgendes SQL Statement möglich ist:

INSERT INTO personen (feld1,feld2) VALUES ("foo"bar","bla");

Ich möchte also in das feld1 den Wert foo"bar einfügen. Damit der Parser aber weis das " nicht angibt das nun der Wert fertig ist, sondern, dass das " noch zum Wert gehört muss ich das Escape-Zeichen \ davor stellen:

INSERT INTO personen (feld1,feld2) VALUES ("foo\"bar","bla");

Für den SQL-Parser der php-txt-db-api müssen Grundsätzlich folgende Zeichen (nur bei Werten innerhalb ' ' oder " ") escaped werden:
' (Einfaches Anführungszeichen), " (doppeltes Anführungszeichen), \ (Backslash)

Es gibt 3 unterschiedliche Varianten ein SQL Statement im PHP Code zu schreiben, bei jeder Art sind die Escape Zeichen anders zu benutzen.
Die erste Variante kommt wohl am häufigsten vor, und wenn man Glück hat braucht man sich gar nie um das escapen oder sogar doppelte escapen zu kümmern.

Variante 1: Formular Felder

Falls man in einem SQL Statement direkt Formular Felder als Werte benutzen möchte (also muss man " " verwenden, damit die Variabeln ausgewertet werden), so muss man selbst gar nichts anpassen. Die Inhalte der Formular Felder werden automatisch mit den korrekten Escape-Buchstaben versehen.

Beispiel:

$db->executeQuery("INSERT INTO personen VALUES('$formFeld1','$formFeld2') ");

Variante 2: SQL Statement ist in " "

Bei einem String in " " müssen von PHP aus u.A. folgende Zeichen escaped werden:

Zeichen | Escaped
" (doppelte Anführungszeichen) | \"
\ (Backslash) | \\

Da diese 2 Zeichen aber auch noch für den SQL-Parser zu escapen sind, ist bei diesen beiden ein doppeltes escapen nötig (PHP entfernt ja die erste Escape Folge):

Zeichen | Escaped (für PHP) | Wert escaped für SQL Parser
" (doppelte Anführungszeichen) | \" | \\\"
\ (Backslash) | \\ | \\\\
' (einfaches Anführungszeichen) | ' (kein escapen für PHP in " ") | \'

Beispiel:

$db->executeQuery("INSERT INTO personen VALUES('Doppeltes: \\\" ','Einfaches: \' '); ");

Variante 3: SQL Statement ist in ' '

Bei einem String in ' ' müssen von PHP aus folgende Zeichen escaped werden:

Zeichen | Escaped
' (doppelte Anführungszeichen) | \'
\ (Backslash) | \\

Da diese Zeichen aber auch noch für den SQL-Parser zu escapen sind, ist bei diesen beiden ein doppeltes escapen nötig (PHP entfernt ja die erste Escape Folge):

Zeichen | Escaped (für PHP) | Wert escaped für SQL Parser
" (doppelte Anführungszeichen) | " (kein escapen für PHP in ' ') | \"
\ (Backslash) | \\ | \\\\
' (einfaches Anführungszeichen) | \' | \\\'

$db->executeQuery('INSERT INTO personen VALUES("Doppeltes: \" "," Einfaches: \\\' "); ');


Fliesskomma-Zahlen

Wenn man (bei dieser Version der API) in einer Tabelle Fliesskomma-Zahlen möchte, so ist str (also String) als Datentyp für die entsprechenden Spalten zu verwenden.
Dabei ist zu beachten das bei allen SQL-Statements Fliesskomma-Zahlen in ' ' oder " " eingeschlossen werden müssen.
Obwohl man als Datentyp str verwendet, funktioniert das Sortieren und Abfragen der Fliesskomma-Zahlen tortzdem richtig, d.h. '50.1' ist > '9.99999' auch wenn '9.99999' im Alphabet zuerst käme.


Error Handling

Allgemein

Mit den beiden Einstellungen PRINT_ERRORS und PRINT_WARNINGS in const.php lässt sich Steuern ob
Fehlermeldungen angezeigt werden oder nicht. Unabhänigig von diesen Einstellungen wird aber von
der Text-Db-Api ein Error-Stack geführt. Also ein Array mit allen Fehlermeldungen. Dazu setzt die
Text-Db-Api einen eigenen PHP-Error Handler. Dieser fängt dann alle Fehler auf, speichert sie im
Fehler Stack und gibt sie abhängig von der Konfiguration aus oder nicht. Der Error Handler wird in
der executeQuery() Funktion gesetzt und am Ende dieser Funktion wieder entfernt.
Ebenfalls wird bei jedem executeQuery() Aufruf der Fehler Stack zuerst gelöscht, daher hat man immer
nur Fehler im Stack vom aktuellen executeQuery() Aufruf, und nicht noch von vorherigen.

Mit folgenden Funktionen lassen sich Fehler abfragen bzw. lässt sich der Stack manual leeren:

txtdbapi_clear_errors
txtdbapi_error_occurred
txtdbapi_get_errors
txtdbapi_get_last_error

Wichtig zu erwähnen ist ebenfalls, das der Txt-Db-Api Error Handler auch automatisch alle PHP Fehler
welche in executeQuery() auftreten auffängt und im Stack speichert.
Hat man also PRINT_ERRORS und PRINT_WARNINGS auf 0 gesetzt, sollte man theoretisch keine
Fehlermeldungen welche in executeQuery() entstehen zu sehen bekommen.


Das Database Objekt

(seit Version 0.0.1)
Database -- Diese Objekt stellt eine Datenbank (in einem Ordner) dar

Beschreibung:

Befor man irgendetwas auf einer Tabelle machen kann, benötigt man eine Instanz des
Database Objektes.

Von diesem Objekt aus kann man dann SQL aufrufe absetzten.
Dafür steht die Funktion executeQuery() zur Verfügung.

Beispiel:

$db = new Database("DatenbankName");

$resultSet = $db->executeQuery("SELECT nr, name, vorname FROM personen WHERE nr=1");
while($resultSet->next()) {
    echo "<br>" . $resultSet->getCurrentValueByName("nr") . ": " . $resultSet->getCurrentValueByName("name") . "<br>";
}


Database (Konstruktor)

(seit Version 0.0.1)
Database -- Konstuktor der Database Klasse

Beschreibung:

Database ([string dbName])

Konstuktor der Database Klasse. Erstellt und initialisiert ein neues Database Objekt.
Optional kann mit dem parameter dbName die gewünschte Datenbank (entspricht dem Ordner
in welchem die Text Files der Tabellen sind) gewählt werden. Wird kein Parameter angegeben
wird die Datenbank (also der Ordner) defaultDb verwendet.
Der Datanbankodner ist immer relativ zu dem Verzeichnis welches in dem Parameter
$DB_DIR in der Konigurationsdatei (txt-db-api.php) angegeben wurde

Parameter:

dbName
 (optional, Defaultwert="defaultDb")
Name bzw. Ordner der Datanbank

Rückgabewert:

--


executeQuery

(seit Version 0.0.1)
executeQuery -- Führt ein Sql Statement aus, und gibt je nach Typ ein ResultSet Objekt oder ein int zurück

Beschreibung:

ResultSet/int executeQuery (string sqlQueryString)

Führt ein Sql Statement auf der Datanbank aus.
Es sind nicht alle Statement Typen und Keywords aus dem SQL Standard enthalten.

Nicht vergessen eventuellen " in dem Sql-String ein \ voranzusetzten

Parameter:

sqlQueryString
 Sql Statement String (z.B. "SELECT nr, name FROM personen WHERE personen.name=\"HANS\";")

Rückgabewert:

Bei SELECT/LIST TABLES Satements:
- Ein ResultSet Objekt welches die Daten enthält.
- Im Fehlerfalle wird false zurückgegeben.

Bei UPDATE/INSERT/DELETE Statements:
- Die Anzahl der veränderten Datensätze
- Im Fehlerfalle wird false zurückgegeben (Achtung: FALSE und 0 haben nicht die gleiche Bedeutung!)

Bei CREATE TABLE/DROP TABLE/CREATE DATABASE/DROP DATABASE Statements:
- Wenn ok: true
- Im Fehlerfalle wird false zurückgegeben


getLastInsertId

(seit Version 0.2.0)
getLastInsertId -- Gibt die Insert ID zurück

Beschreibung:

int getLastInsertId ()

Gibt den Wert der ersten inc Spalte zurück, für den letzten Datensatz welcher bei einem INSERT Statement angefügt wurde.
(Dazu muss also erst mal ein INSERT auf der verwendeten Database Instanz ausgeführt worden sein!)

Rückgabewert:

letzte Insert ID


Das Database Objekt

Das ResultSet Objekt

(seit Version 0.0.1)
ResultSet -- Diese Objekt stellt das Ergebnis einer SELECT Abfrage dar

Beschreibung:

Nachdem man mit Database->executeQuery() eine SELECT Abfrage ausgeführt hat
bekommt man ein ResultSet Objekt zurück, welches die Daten dieser Abfrage enthält.
Mit dem ResultSet Objekt kann man dann durch die Datensätze des Ergebnisses navigieren
und diese abfragen.

Beispiel:

$db = new Database("DatenbankName");

$resultSet = $db->executeQuery("SELECT nr, name, vorname FROM personen WHERE nr=1");
while($resultSet->next()) {
    echo "<br>" . $resultSet->getCurrentValueByName("nr") . ": " . $resultSet->getCurrentValueByName("name") . "<br>";
}


next

(seit Version 0.0.1)
next -- Geht zum nächsten Datensatz des ResultSet Objektes

Beschreibung:

bool next ()

Setzt die Postition des ResultSet Objektes auf den nächsten Datensatz.

Rückgabewert:

Falls ein nächster Datensatz vorhanden war: TRUE
Wenn das Ende des ResultSet Objektes erreicht ist: FALSE


prev

(seit Version 0.0.1)
prev -- Geht zum vorherigen Datensatz des ResultSet Objektes

Beschreibung:

bool prev ()

Setzt die Postition des ResultSet Objektes auf den vorherigen Datensatz.

Rückgabewert:

Falls ein vorheriger Datensatz vorhanden war: TRUE
Wenn der Anfang des ResultSet Objektes erreicht ist: FALSE


reset

(seit Version 0.0.1)
reset -- Setzt die Position des ResultSet's vor den ersten Datensatz

Beschreibung:

reset ()

Diese Funktion setzt die Position des ResultSet's vor den ersten Datensatz.
Wieso vor den Ersten ? Damit man mit dem nächsten next() Aufruf zum ersten
Datensatz gelangt. So wird zB folgender Quelltext möglich:

$resultSet->reset();
while($resultSet->next()) {
    echo "Aktuelle Reihe: ";
    $arr=$resultSet->getCurrentValues();
    print_r($arr);
}

Rückgabewert:

keiner


getPos

(seit Version 0.0.1)
getPos -- Gibt die aktuelle Position des ResultSet Objektes zurück

Beschreibung:

int getPos ()

Gibt die aktuelle Position des ResultSet Objektes zurück.

Rückgabewert:

Ein Wert von -1 (vor dem ersten Datensatz) bis getRowCount()-1


setPos

(seit Version 0.0.1)
setPos -- Legt die aktuelle Position des ResultSet Objektes fest

Beschreibung:

setPos (int pos)

Legt die aktuelle Position des ResultSet Objektes fest.

Parameter:

pos
 Die zu setzende Position, ein Wert von -1 (vor dem ersten Datensatz) bis getRowCount()-1

Rückgabewert:

keiner


getRowCount

(seit Version 0.0.1)
getRowCount -- Gibt die Anzahl Reihen (also Datensätze) des ResultSet's zurück

Beschreibung:

int getRowCount ()

Liefert die Anzahl Datensätze des ResultSet's.

Rückgabewert:

Anzahl Reihen (Rows).


getRowSize

(seit Version 0.0.1)
getRowSize -- Gibt die Anzahl Spalten des ResultSet Objektes zurück (d.h. die Anzahl Felder pro Reihe)

Beschreibung:

int getRowSize ()

Gibt die Anzahl Spalten des ResultSet Objektes zurück (d.h. die Anzahl Felder pro Reihe)

Rückgabewert:

Anzahl Spalten des ResultSet Objektes


getColumnNames

(seit Version 0.0.1)
getColumnNames -- Gibt ein Array zurück, welches die Spaltennamen des ResultSet's enthält.

Beschreibung:

array getColumnNames ()

Gibt ein Array zurück, welches die Spaltennamen des ResultSet's enthält. Diese könnten zB.
später bei getCurrentValueByName() oder getValueByName() verwendet werden.

Rückgabewert:

Ein Array welches die Spaltennamen enthält.


getCurrentValueByName

(seit Version 0.0.1)
getCurrentValueByName -- Gibt den Wert der Spalte colName der aktuellen Reihe zurück.

Beschreibung:

string getCurrentValueByName (string colName)

Gibt den Wert der Spalte colName des aktuellen Datensatzes des ResultSet
Objektes zurück. Der aktuelle Datensatz, bwz. die aktuelle Reihe kann zB. mit den
Funktionen next(), prev() oder setPos() verändert werden.

Parameter:

colName
Name der Spalte in welcher der Wert zu lesen ist.

Rückgabewert:

Wert der Spalte colName an der momentanen Position des ResultSet's als string.


getCurrentValueByNr

(seit Version 0.0.1)
getCurrentValueByNr -- Gibt den Wert der Spalte colNr der aktuellen Reihe zurück.

Beschreibung:

string getCurrentValueByNr (int colNr)

Gibt den Wert der Spalten Nummer colNr des aktuellen Datensatzes des ResultSet
Objektes zurück. Der aktuelle Datensatz, bwz. die aktuelle Reihe kann zB. mit den
Funktionen next(), prev() oder setPos() verändert werden.

Parameter:

colNr
Nummer der Spalte in welcher der Wert zu lesen ist. Die Spalten sind im ResultSet Objekt gleich angeordnet wie in der SQL Abfrage. Die erste Spalte ist die 0.

Rückgabewert:

Wert der Spalte colNr an der momentanen Position des ResultSet's als string.


getValueByName

(seit Version 0.0.1)
getValueByName -- Gibt den Wert der Spalte colNome der Reihe rowNr zurück.

Beschreibung:

string getValueByName (int rowNr, string colName)

Gibt den Wert der Spalte colName der Reihe rowNr zurück.

Parameter:

rowNr
 Reihe in welcher der Wert zu lesen ist
colName
Name der Spalte in welcher der Wert zu lesen ist.

Rückgabewert:

Wert der Spalte colName an der Position rowNr als string.


getValueByNr

(seit Version 0.0.1)
getValueByNr -- Gibt den Wert der Spalte colNr der Reihe rowNr zurück.

Beschreibung:

string getValueByNr (int rowNr, int colNr)

Gibt den Wert der Spalte colNr der Reihe rowNr zurück.

Parameter:

rowNr
 Reihe in welcher der Wert zu lesen ist
colNr
Nummer der Spalte in welcher der Wert zu lesen ist. Die Spalten sind im ResultSet Objekt gleich angeordnet wie in der SQL Abfrage. Die erste Spalte ist die 0.

Rückgabewert:

Wert der Spalte colNr an der Position rowNr als string.


getCurrentValues

(seit Version 0.0.1)
getCurrentValues -- Gibt die Werte der aktuellen Reihe als Array zurück.

Beschreibung:

array getCurrentValues ()

Gibt die Werte des aktuellen Datensatzes als array zurück. Die werte sind im Array
gleich angeordnet wir in der Sql-Abfrage. Der aktuelle Datensatz, bwz. die aktuelle Reihe kann zB. mit den
Funktionen next(), prev() oder setPos() verändert werden.

Hier ist eine Verwendung von list() sehr gut geeignet, z.B.

$db=new Database("MeineDatenbank");

$rs=$db->executeQuery("SELECT nr, name, ort, email FROM Personen");
while($rs->next()) {
    list($nr, $name, $ort, $mail)=$rs->getCurrentValues();
    echo "$nr: $name aus $ort (Email: $mail)";
}

Rückgabewert:

Die Werte der akuellen Reihe als Array;


getCurrentValuesAsHash

(seit Version 0.1.3-alpha5)
getCurrentValuesAsHash -- Gibt die Werte der aktuellen Reihe als Hash Array zurück.

Beschreibung:

array getCurrentValuesAsHash ()

Gibt die Werte des aktuellen Datensatzes als hash array zurück. Die werte sind im Array
gleich angeordnet wir in der Sql-Abfrage. Der aktuelle Datensatz, bwz. die aktuelle Reihe kann zB. mit den
Funktionen next(), prev() oder setPos() verändert werden.

Da es ein hash array ist können mit den spalten-namen die werte ausgelesen werden:

$db=new Database("TestDB");

$rs=$db->executeQuery("SELECT * FROM woerter GROUP BY wort, art ORDER BY wort DESC LIMIT 0,3");
while($rs->next()) {
    $arr=$rs->getCurrentValuesAsHash();
    echo $arr['wort'] . $arr['art'] . "<br>";
}

Rückgabewert:

Die Werte der akuellen Reihe als Hash Array


getValues

(seit Version 0.0.1)
getValues -- Gibt die Werte der Reihe rowNr als Array zurück.

Beschreibung:

array getValues (int rowNr)

Gibt die Werte der Reihe rowNr als Array zurück. Die werte sind im Array
gleich angeordnet wir in der Sql-Abfrage.

Parameter:

rowNr
Reihe von welcher die Werte zu lesen sind

Rückgabewert:

Die Werte der Reihe rowNr als Array;


dump

(seit Version 0.0.1)
dump -- Gibt den Inhalt des ResultSet's aus

Beschreibung:

dump ()

Gibt den Inhalt des ResultSet's aus.

Rückgabewert:

--


txtdbapi_version

(seit Version 0.1.1)
txtdbapi_version -- Gibt die Version der API zurück

Beschreibung:

string txtdbapi_version ()

Gibt die Version der API als String zurück.

Rückgabewert:

Versionsnummer als String.


txtdbapi_clear_errors

(seit Version 0.2.0)
txtdbapi_clear_errors -- Leert den Fehler Stack

Beschreibung:

txtdbapi_clear_errors ()

Leert den Fehler Stack. Dies geschieht am anfang der executeQuery() funktion automatisch.
Daher hat man automatisch immer nur Fehler des letzten executeQuery() aufrufes im Stack,
und diese Funktion sollte eigentlich nicht nötig sein.

Rückgabewert:

keiner


txtdbapi_error_occurred

(seit Version 0.2.0)
txtdbapi_error_occurred -- Gibt true zurück falls im letzten executeQuery() Aufruf ein Fehler auftrat

Beschreibung:

bool txtdbapi_error_occurred ()

Gibt true zurück falls im letzten executeQuery() Aufruf ein Fehler auftrat.
Falls kein Fehler auftrat leifert die Funktion false.

Rückgabewert:

true falls im letzten executeQuery() Aufruf ein Fehler auftrat, sonst false


txtdbapi_get_errors

(seit Version 0.2.0)
txtdbapi_get_errors -- Gibt alle Fehler als array zurück

Beschreibung:

array txtdbapi_get_errors ()

Gibt alle Fehler als array von Strings zurück. Der Fehler Stack wird in dieser Funktion geleert.

Rückgabewert:

Alle Fehler als array


txtdbapi_get_last_error

(seit Version 0.2.0)
txtdbapi_get_last_error -- Gibt den letzten Fehler zurück und entfernt ihn vom Fehler-Stack

Beschreibung:

string txtdbapi_get_last_error ()

Gibt den letzten Fehler als String zurück und entfernt ihn vom Fehler-Stack, d.h. der nächste
txtdbapi_get_last_error() aufruf liefert den nächsten Fehler.

Rückgabewert:

den letzten Fehler als String


PHP: Text File Database Manual

Tutorial 1: Die txt-db-api benutzen

Die API ist sehr einfach zu benutzen. Typischerweise ist eine PHP-Seite welche die API verwendet
folgendermassen aufgebaut:

1. Txt-Db-Api Includen

<?php
include ("../php-api/txt-db-api.php");

Wichtig ist das der Pfad zu der txt-db-api.php Datei stimmt. Je nachdem wo man die API installiert
hat, und wo sich die bearbeitete PHP Datei befindet könnte dieser auch etwas länger
werden, dafür ist es die einzige Include Anweisung die man benötigt.

2. Datenbank-Objekt erzeugen

Wenn man die Installation korrekt ausgeführt hat und von Hand (via FTP) einen entsprechenden
Ordner erzeugt hat, so kann man nun ein Database Objekt erzeugen. Dabei muss im
Konstruktor immer der Name der Datenbank angegeben werden (Achtung Gross-klein schreibung):

$db = new Database("MeineDatenbank");

3. SQL Statements absetzten

Hat man einmal ein Database Objekt so kann man nun darauf beliebig viele
SQL-Statements ausführen. Dies geschieht mit der Methode executeQuery()

$rs=$db->executeQuery("SELECT name, vorname, plz AS daWohntEr FROM Personen WHERE plz='1234' ORDER BY name; ");

Das ";" am Ende des SQL-Strings ist übrigens freiwillig. Je nach Typ des Statements wird executeQuery() einen anderen Wert
zurückgeben, der dan Ausgewertet werden kann.

4. ResultSet Daten anzeigen (Nur bei SELECT Statements)

Falls es ein SELECT Statement war, bekommt man ein ResultSet Objekt zurück, welches die Daten enthält.
Diese Daten können nun auf unterschiedliche Arten abgefragt werden.
Überlicherweise wird man wohl folgende while-Schleife verwenden:

while($rs->next()) {

Mit next() wird im ResultSet automatisch zur nächsten Reihe gewechselt.
(Vor dem ersten next() aufruf ist die Position nicht am Anfang, sondern 1 vor dem Anfang, somit
gelagt man mit dem ersten next() Aufruf auch zur ersten Reihe (Datensatz)).

Innerhalb dieser Schleife kann man nun bequem mit getCurrentValues/getCurrentValueByName oder getCurrentValueByNr
die Daten der aktuellen Reihe abfragen.

    list($name,$vorname,$PostLeitZahl)=$rs->getCurrentValues();
    echo "$name $vorname  kommt aus  $PostLeitZahl";
}


PHP: Text File Database Manual

Tutorial 2: Tabellen "manuell" erstellen

ACHTUNG: Das Tabellen-Format hat in 0.1.3-Alpha-02 und 0.1.5-Alpha-01 geändert!

Wenn man neue Tabellen nicht immer mit einem CREATE TABLE Aufruf erstellen möchte, so
kann man dies auch "von Hand" tun.

1. Text Datei erstellen

Als erstes ist eine Text Datei (Endung .txt) zu erstellen.
Datei > Neu > Textdokument (oder so ähnlich)

2. Spalten definieren (1. Zeile)

In der ersten Zeile der Text Datei sind die Namen der Spalten niederzuschreiben.
Dabei wird jeder Spaltenname mit einem # beendet.

Beispiel:
Nr#Name#Vorname#Adresse#Alter

3. Datentypen definieren (2. Zeile)

Im gleichen Format wie oben ist nun der Datentyp für jede Spalte zu definieren.
Welche Datentypen momentan unterstütz werden sieht man hier.

Die 2. Zeile könnte etwa so aussehen:

inc#str#str#str#int

4. Standardwerte definieren (3. Zeile)

Im gleichen Format wie oben ist nun für jede Spalte ein Standartwert festzulegen.
Dieser wird verwendet wenn man bei INSERT Statements nicht alle Spalten angibt.

Die 3. Zeile könnte etwa so aussehen:

0#Standard Name#Standard Vorname#Keine Adresse#40

5. (Freiwillig) Daten eingeben

Im gleichen Format wie oben können nun bei Bedarf bereits einige Daten (zB für Testzwecke) eingegeben werden.
Die fertige Tabellen-Datei könnte dann so aussehen:

Nr#Name#Vorname#Adresse#Alter
inc#str#str#str#int
0#Standard Name#Standard Vorname#Keine Adresse#40
0#Hans#Wurst#Wurststrasse 9#40
1#Maxx#Test#Teststrasse 1#22

6. Berechtigungen setzten

Auf der neu erstellen Datei sind nun noch die Berechtigungen zu setzten. Dies ist mit den meisten FTP-Clients möglich!
Am besten macht man gleich ein chmod 777.
Damit die Datenbank-Dateien nicht mit dem Browser direkt angesehen werden können, ist es empfehlenswert die .htaccess Datei entsprechend zu verändern, dass mit GET und POST kein Zugriff auf die Txt-Dateien möglich ist.

7. Weiteres / Hinweise

Falls man ein % oder # als Teil des Spaltennamens oder als Teil der Daten verwenden möchte, ist anstelle von "%" "%p" zu schreiben, und anstelle von "#" ein "%h". Dies ist nötig, da # und % eine spezielle Bedeutung haben. Ansonsten braucht man sich darum aber NIE (auch bei CREATE TABLE Statements nicht) zu kümmern (# und % werden automatisch umgewandelt), sondern nur dann, wenn man Werte direkt im Text-File eingibt. Und das #-Zeichen, das wie oben beschrieben die Spaltennamen und Datentypen voneinander trennt, ist natürlich nicht als %h zu schreiben.

Beispiele:

nr#link
inc#str
##
1#http://www.abc.de/index.htm%hanker
2#http://www.abc.de/start.htm%habsatz2
nr#person#rabatt
inc#str#str
##10%p
1#müller#5%p
2#maier#7,5%p


FAQ (Häufig gestellte Fragen)

Wird man einmal ein Datum speichern können ? / Wie soll ich ein Datum speichern ?

Vielleicht kommt das mal, eber das braucht es doch eigentlich gar nicht.

Empfohlene Variente:
Du kannst entweder einen timestamp als int speichern und dann vor dem anzeigen in ein datum umwandeln.
Das sortieren funktioniert dann automatisch richtig.

Oder:
... du speicherst das datum als string (str), am besten im format yyyymmdd also für heute wäre das zB 20021101. so funktioniert das sortieren ebenfalls richtig (da zuerst jahr dann monat dann tag kommt). auch hier musst du dann halt den string form dem anzeigen umwandeln.
auch könntest du ein format wie z.B. yyyy-mm-dd nehmen, was vielleicht sogar einfach zum parsen ist.

Wenn du mit dem gespeicherten datum keine operationen vornehmen musst, z.B. + 1 tag, dann kannst du auch einfach den rückgabewert von z.B. date("D M j H:i:s Y") als string speichern und diesen unverändert anzeigen und später überschreiben. Der nachteil ist hier einfach das ein sortieren nach dem datumsfeld nicht richtig funktionieren würde.

Ich verstehe das mit den 3 Zeilen wo die Spalteninformationen gespeichert werden nicht

Um eins mal gleich vorne weg zu nehmen: Wenn man eine Tabelle mit CREATE TABLE erstellt, braucht man sich nicht darum zu kümmern.
Hat man eine Tabelle jedoch nocht mit einer Version vor 0.1.5-Alpha-01 erstellt (auch mit CREATE TABLE) muss man diese nun
SELBST, also VON HAND anpassen.

Die tabellen werden ja bekanntlich in text files gespeichert. Früher war es so das die oberen beiden zeilen, also die ersten 2, noch keine daten enthielten,
sondern informationen über die spalten der tabelle. Die erste Zeile enthält die spaltennamen. Für eine personen-tabelle könnte das z.B.

name#vorname#alter

sein.
die zweite zeile enthält den datentyp dieser spalten. z.B.

str#str#int

jetzt, in den neueren versionen ist noch eine dritte zeile hinzugekommen die noch informationen über die spalten der tabelle speichert,
und zwar die Standardwerte. Wenn man ein INSERT macht, und dabei einige spalten nicht angibt, wird anstatt nichts, der entsprechende
Wert der 3. Zeile eingefügt. Diese 3. Zeile könnte z.B. so aussehen:

meier#hans#40

So würde nun also die leere tabelle, ohne daten aussehen:

name#vorname#alter
str#str#int
meier#hans#40

Denke daran das in den früheren Versionen (vor 0.1.5-Alpha-01) die 3. Zeile bereits daten enthalten durfte.
Das ist jetzt aber seit 0.1.5-Alpha-01 nicht mehr so. Wenn du eine alte Tabelle weiterverwenden willst,
musst du von Hand (also mit einem Texteditor) schnell eine 3. Zeile einfügen.
Ums dir einfach zu machen kannnst du einfach gleichviele # machen wie die zeile überhalb. Also für mein beispiel wäre das:

name#vorname#alter
str#str#int
##

nun sind all die Standardwerte einfach "nichts", also ein leerer string.

aber zurück zum Beispiel mit richtigen Standardwerten:

name#vorname#alter
str#str#int
meier#hans#40

Wenn du nun folgendes Statement ausführst:

INSERT into personen (vorname,alter) VALUES ('john',34);

wie du siehst wurde für die soakte name kein wert angegeben, und deshalbt fügt er nun den standardwert ein, also sie die tabelle
nachher so aus:

name#vorname#alter
str#str#int
meier#hans#40
meier#john#34

Du siehst, da die Spalte name im INSERT Statement nicht angegeben wurde, wurde für diese Spalte der Standardwert "meier"
übernommen. Diese tabelle hat nun genau EINEN Datensatz drin.
Auf den ersten blick könnte man vielleicht meinen es sind 2!
Es ist aber nur einer, denn die dritte zeile enthält ja die Standardwerte, und die kann unter Umständen einem richtigen Datensatz sehr gleichen.


Reservierte Wörter und Zeichen

Folgende Wörter sollten NICHT als Spaltennamen verwendet werden (jedoch ohne weiteres als Daten):

AND
AS
ASC
BY
CREATE
DATABASE
DELETE
DESC
DISTINCT
DROP
FROM
GROUP
INSERT
INTO
LIKE
LIMIT
LIST
OR
ORDER
SELECT
SET
TABLE
UPDATE
VALUES
WHERE

Folgende Zeichen sollten NICHT als Teil eines Spaltennamen verwendet werden (jedoch ohne weiteres als Daten):

<>
!=
>=
<=
=
<
>
(
)
;
, (Komma)
. (Punkt)
' (Einfache Quote)
" (Doppelte Quote)
!


About

About: Php Text Database API

Hilfe Version: 0.3.1-Beta-01 (zur entsprechenden API Version)

Neuste PHP Version mit welcher die API funktioniert: 5.0.3

Entwickler API: | www.c-worker.ch, (super)mario sansone
Developer WebGUI: | Gobo
Dokumentation/Manual: | www.c-worker.ch, Lester (Korrekturen Englischen)

Danksagungen:

Dank für diverse Fehlerhinweise/Mithilfe geht an:
mike, Wolfgang, die Leute von www.codeforum.ch, Lester, Jakob Wankel,
jens rauschning, Mario Sansone, Gobo, Armin Gelhausen, deep:blue,
Sam Thursfield, stefan, stepan