Raketenleichtmatrose: PHP PDO:SQLITE - Falle: attempt to write a readonly database - und kein TRUNCATE table in SQLITE

Beitrag lesen

Ich bin gerade über folgende Falle gestolpert:

Der Connect mit

$pdo = new PDO( 'sqlite:' . $SQLite3File )

hat funktioniert.

Aber jeder Versuch, an der Datenbank etwas zu ändern warf nur folgenden Fehler:

"attempt to write a readonly database…"

Merkwürdig: Die Datei war von jedem les- und schreibbar.

Die Lösung: Der mysqli-Treiber will zwecks locking im Verzeichnis eine Flag-Datei anlegen, mit welcher signalisiert, dass diese Datei gerade schreibend benutzt wird. Also muss auch das Verzeichnis vom Webserver beschreibbar sein.

Ich hab das jetzt wie folgt gelöst:

<?php

if ( ! $pdo = PDOSQLite3Connect (
    SQLite3File,
    PDOReadOnly,
    E_USER_ERROR
) ) {
	exit;
}


function PDOSQLite3Connect ( $SQLite3File, $PDOReadOnly ) {

	if ( ! $PDOReadOnly ) {
		if ( ! is_writable( $SQLite3File ) ) {
			error_log( '(PDO): Datei "' . $SQLite3File . '/" muss beschreibbar sein.' );
			showErrorMsg();
			return false;
		}

		if ( ! is_writable( dirname( $SQLite3File ) ) ) {
			error_log( '(PDO): Verzeichnis "' . dirname( $SQLite3File ) . '" muss beschreibbar sein.' );
			showErrorMsg();
			return false;
		}
	}

	if ( ! $pdo = new PDO( 'sqlite:' . $SQLite3File ) ) {
		error_log( 'Datenbankverbindung zu "sqlite:' . SQLite3File . '" hat nicht funktioniert.' ); 
		showErrorMsg();
		return false;
	} else {
		return $pdo;
	}
}

showErrorMsg() zeigt ohne Optionen einen "allgemeinen" Server-Fehler an.

FRAGE:

Geht das eleganter?

Zweitens ein Tipp:

Bei Fummeln und testen bin ich über Folgendes gestolpert: In SQLITE gibt es kein TRUNCATE. Der oft gelesene Tipp, die Tabelle mit

DELETE FROM table;

zu löschen leert zwar die Tabelle, lässt aber den (letzten) Autoindex stehen.

Will man den auch löschen, dann geht das so:

DELETE FROM table;
DELETE FROM SQLITE_SEQUENCE WHERE name='table';