Compare commits
6
Commits
main
..
6306bfba17
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6306bfba17 | ||
|
|
e2596b6e1c | ||
|
|
a66ace58c4 | ||
|
|
0d0059f033 | ||
|
|
ec6222c4eb | ||
|
|
210a6c47a8 |
@@ -11,6 +11,8 @@
|
||||
# --- Datenbank-Dumps / Backups ---------------------------------
|
||||
*.sql
|
||||
*.sql.gz
|
||||
# Ausnahme: das Schema selbst enthaelt keine Daten
|
||||
!update/schema.sql
|
||||
*.dump
|
||||
*.bak
|
||||
|
||||
|
||||
@@ -84,6 +84,8 @@ Eine Schemaänderung besteht also aus: neuer Eintrag **vorn** in `update/version
|
||||
|
||||
## Datenbankzugriff
|
||||
|
||||
**Umbau läuft (Branch `db-umbau`):** Verbindungen entstehen nur noch über `db_verbinden()` aus `incs/db.php`. Die Funktion setzt `utf8mb4`, den strikten `sql_mode` und schaltet die mysqli-Exceptions ab. Neue und umgebaute Abfragen nutzen `db_abfrage()`, `db_zeilen()`, `db_zeile()` und `db_wert()` mit `?`-Platzhaltern statt String-Verkettung. Ziel-Schema ist das der Instanz `kunden` in `utf8mb4`; die Altdaten sind teils doppelt kodiert und werden per Migration repariert. Dieser Stand darf nur zusammen mit der migrierten Datenbank live gehen.
|
||||
|
||||
Prozedurales `mysqli`. `$dbconn` wird zusätzlich in `$_SESSION["dbconn"]` abgelegt, damit `incs/mysql_ecape_wrapper.php` eine globale Funktion `mysql_escape_string()` als Shim über diese Verbindung bereitstellen kann — ein Überbleibsel der `mysql_*`-Ära, das in altem Code noch aufgerufen wird.
|
||||
|
||||
SQL wird durchgehend per String-Verkettung gebaut. Escaping ist Handarbeit über `mysqli_real_escape_string($dbconn, …)` und muss bei jeder Änderung mitgedacht werden.
|
||||
|
||||
+4
-10
@@ -11,21 +11,15 @@ if($settings != "valid")
|
||||
|
||||
if($settings == "valid")
|
||||
{
|
||||
if(!$dbconn = @mysqli_connect($mysql_server, $mysql_user, $mysql_pw))
|
||||
$err = error("Verbindung zur Datenbank fehlgeschlagen!!");
|
||||
if(!@mysqli_select_db($dbconn,$mysql_db))
|
||||
$err = error("Datenbank nicht gefunden!! ($mysql_db)");
|
||||
if(!$dbconn = db_verbinden($mysql_server, $mysql_user, $mysql_pw, $mysql_db))
|
||||
$err = error("Verbindung zur Datenbank fehlgeschlagen: ".htmlspecialchars(mysqli_connect_error()));
|
||||
}
|
||||
// Wie sites/userkeys.php: nur Superadmins dürfen Passkeys vergeben
|
||||
if($_SESSION["login"] == "valid" && isset($_GET["id"]) && ((int)substr($_SESSION["rights"], RIGHTS_SUPERADMIN, 1) & RIGHTS_CHANGE)){
|
||||
if(!mysqli_query($dbconn,"DELETE FROM addKey WHERE datetime < DATE_SUB(NOW(), INTERVAL 1 MINUTE);")){
|
||||
echo mysqli_error($dbconn);
|
||||
}
|
||||
db_abfrage($dbconn, "DELETE FROM addKey WHERE datetime < DATE_SUB(NOW(), INTERVAL 1 MINUTE)") or print(mysqli_error($dbconn));
|
||||
if(isLocal()){
|
||||
$accessKey = strval(random_int(0,99999999));
|
||||
if(!mysqli_query($dbconn,"INSERT INTO addKey SET accesskey=".$accessKey.", datetime=NOW();")){
|
||||
echo mysqli_error($dbconn);
|
||||
}
|
||||
db_abfrage($dbconn, "INSERT INTO addKey SET accesskey = ?, datetime = NOW()", array($accessKey)) or print(mysqli_error($dbconn));
|
||||
header('Location: https://wm.el-wa.org/kunden?action=userkeys&id='.(int)$_GET["id"].'&addKey='.$accessKey);
|
||||
echo 'https://wm.el-wa.org/kunden?action=userkeys&id='.(int)$_GET["id"].'&addKey='.$accessKey;
|
||||
}else{
|
||||
|
||||
@@ -2,19 +2,14 @@
|
||||
require_once("../../incs/constants.php");
|
||||
session_name(SESSION_NAME);
|
||||
session_start();
|
||||
// Alle AJAX-Endpunkte laden diese Datei: ohne Anmeldung gibt es keine Daten.
|
||||
if(($_SESSION["login"] ?? "") !== "valid")
|
||||
{
|
||||
http_response_code(403);
|
||||
exit("Nicht angemeldet.");
|
||||
}
|
||||
require_once("../../incs/settings.php");
|
||||
$settings=readsettings();
|
||||
if($settings == "valid")
|
||||
{
|
||||
|
||||
$dbconn = mysqli_connect($mysql_server, $mysql_user, $mysql_pw);
|
||||
mysqli_select_db($dbconn,$mysql_db);
|
||||
$dbconn = db_verbinden($mysql_server, $mysql_user, $mysql_pw, $mysql_db);
|
||||
if(!$dbconn)
|
||||
$err = 1;
|
||||
}
|
||||
else
|
||||
$err = 1;
|
||||
|
||||
@@ -123,7 +123,7 @@ if(!isset($err))
|
||||
|
||||
//OLD SKS RECHNUNGEN!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
if(getUserSetting($dbconn,"show_sks", mysql_escape_string($_SESSION["user"]), 1)) //show sks rechnungen????
|
||||
if(getUserSetting($dbconn,"show_sks", $_SESSION["user"], 1)) //show sks rechnungen????
|
||||
{
|
||||
echo "<h3>SKS Dokumente:</h3><div class='line'></div>";
|
||||
$queries="";
|
||||
|
||||
+1
-1
@@ -118,7 +118,7 @@ if(!isset($err))
|
||||
|
||||
//OLD SKS RECHNUNGEN!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
if(getUserSetting($dbconn,"show_sks", mysql_escape_string($_SESSION["user"]), 1)) //show sks rechnungen????
|
||||
if(getUserSetting($dbconn,"show_sks", $_SESSION["user"], 1)) //show sks rechnungen????
|
||||
{
|
||||
echo "<h3>SKS Dokumente:</h3><div class='line'></div>";
|
||||
$queries = createRechQry($skspage,$pagesize,$src,$combiner,1);
|
||||
|
||||
+21
-26
@@ -50,10 +50,8 @@ try {
|
||||
|
||||
if($settings == "valid")
|
||||
{
|
||||
if(!$dbconn = @mysqli_connect($mysql_server, $mysql_user, $mysql_pw))
|
||||
$err = error("Verbindung zur Datenbank fehlgeschlagen!!");
|
||||
if(!@mysqli_select_db($dbconn,$mysql_db))
|
||||
$err = error("Datenbank nicht gefunden!! ($mysql_db)");
|
||||
if(!$dbconn = db_verbinden($mysql_server, $mysql_user, $mysql_pw, $mysql_db))
|
||||
$err = error("Verbindung zur Datenbank fehlgeschlagen: ".htmlspecialchars(mysqli_connect_error()));
|
||||
}
|
||||
// read get argument and post body
|
||||
$fn = filter_input(INPUT_GET, 'fn');
|
||||
@@ -141,23 +139,21 @@ try {
|
||||
// ------------------------------------
|
||||
|
||||
} else if ($fn === 'getGetArgs') {
|
||||
$result = mysqli_query($dbconn,"SELECT id FROM user WHERE nick = '".mysqli_real_escape_string($dbconn,$_GET["user"])."';");
|
||||
if ($result->num_rows > 0) {
|
||||
$row = $result->fetch_assoc();
|
||||
$userId = $row["id"];
|
||||
}else{
|
||||
$userId = db_wert($dbconn, "SELECT id FROM user WHERE nick = ?", array((string)filter_input(INPUT_GET, 'user')));
|
||||
if ($userId === false) {
|
||||
throw new Exception(mysqli_error($dbconn));
|
||||
}
|
||||
if ($userId === null) {
|
||||
throw new Exception('Username not found');
|
||||
}
|
||||
$ids = [];
|
||||
$result = mysqli_query($dbconn,"SELECT credentialId FROM passkeys WHERE userId = '".$userId."';");
|
||||
if(!$result){
|
||||
$msg = "Error:<br>".mysqli_error($dbconn)."<br />";
|
||||
$zeilen = db_zeilen($dbconn, "SELECT credentialId FROM passkeys WHERE userId = ?", array($userId));
|
||||
if ($zeilen === false) {
|
||||
throw new Exception(mysqli_error($dbconn));
|
||||
}
|
||||
if ($result->num_rows > 0) {
|
||||
while($row = $result->fetch_assoc()) {
|
||||
foreach ($zeilen as $row) {
|
||||
$ids[] = base64_decode($row["credentialId"]);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($ids) === 0) {
|
||||
throw new Exception('no registrations in session for userId ' . $userId);
|
||||
@@ -199,7 +195,8 @@ try {
|
||||
if (!isset($_SESSION['registrations']) || !array_key_exists('registrations', $_SESSION) || !is_array($_SESSION['registrations'])) {
|
||||
$_SESSION['registrations'] = [];
|
||||
}*/
|
||||
if(!mysqli_query($dbconn,"INSERT INTO passkeys SET credentialId = '".base64_encode($data->credentialId)."', credentialPublicKey = '".base64_encode($data->credentialPublicKey)."', signatureCounter = '".base64_encode($data->signatureCounter)."', name = '".mysqli_real_escape_string($mysql,filter_input(INPUT_GET, 'name'))."', userId = '".(int)$passkeyFreigabe["user"]."';")){
|
||||
if(!db_abfrage($dbconn, "INSERT INTO passkeys SET credentialId = ?, credentialPublicKey = ?, signatureCounter = ?, name = ?, userId = ?, lastAuth = NOW(), authKey = 0",
|
||||
array(base64_encode($data->credentialId), base64_encode($data->credentialPublicKey), base64_encode($data->signatureCounter), (string)filter_input(INPUT_GET, 'name'), $passkeyFreigabe["user"]))){
|
||||
$msg = "Error:<br>".mysqli_error($dbconn)."<br />";
|
||||
}
|
||||
else{
|
||||
@@ -238,12 +235,11 @@ try {
|
||||
// looking up correspondending public key of the credential id
|
||||
// you should also validate that only ids of the given user name
|
||||
// are taken for the login.
|
||||
$result = mysqli_query($dbconn,"SELECT credentialPublicKey, userId, name FROM passkeys WHERE credentialId = '".base64_encode($id)."';");
|
||||
if(!$result){
|
||||
$msg = "Error:<br>".mysqli_error($dbconn)."<br />";
|
||||
$row = db_zeile($dbconn, "SELECT credentialPublicKey, userId, name FROM passkeys WHERE credentialId = ?", array(base64_encode((string)$id)));
|
||||
if ($row === false) {
|
||||
throw new Exception(mysqli_error($dbconn));
|
||||
}
|
||||
if ($result->num_rows > 0) {
|
||||
$row = $result->fetch_assoc();
|
||||
if ($row) {
|
||||
$userId = $row["userId"];
|
||||
$credentialPublicKey = base64_decode($row["credentialPublicKey"]);
|
||||
$reg = (object) ['userId' => base64_decode($row["userId"])];
|
||||
@@ -272,16 +268,15 @@ try {
|
||||
|
||||
|
||||
$authKey = strval(random_int(0,99999999));
|
||||
$result = mysqli_query($dbconn,"UPDATE passkeys SET authKey=".$authKey.", lastAuth=NOW() WHERE credentialId = '".base64_encode($id)."';");
|
||||
db_abfrage($dbconn, "UPDATE passkeys SET authKey = ?, lastAuth = NOW() WHERE credentialId = ?", array($authKey, base64_encode($id)));
|
||||
// Gesperrte Benutzer bleiben gesperrt, auch mit gültigem Passkey
|
||||
$qry= mysqli_query($dbconn, "SELECT * FROM user WHERE id = '".mysqli_real_escape_string($dbconn,$userId)."' AND blocked = 0");
|
||||
if(!$qry || mysqli_num_rows($qry) != 1)
|
||||
$udata = db_zeile($dbconn, "SELECT * FROM user WHERE id = ? AND blocked = 0", array($userId));
|
||||
if(!$udata)
|
||||
{
|
||||
throw new Exception('Benutzer nicht gefunden oder gesperrt.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$udata = mysqli_fetch_assoc($qry);
|
||||
session_regenerate_id(true);
|
||||
$_SESSION["login"] = "valid";
|
||||
$_SESSION["logedout"] = $udata["logedout"];
|
||||
@@ -301,7 +296,7 @@ try {
|
||||
$_SESSION["zoom"] = getUserSetting($dbconn,"zoom", $_SESSION["user"], 1);
|
||||
$_SESSION["privateNotes"] = getUserSetting($dbconn,"privnotes", $_SESSION["user"], "");
|
||||
|
||||
mysqli_query($dbconn, "UPDATE user SET wrongpw = 0, lastlogin = NOW(), numlogins = numlogins + 1, logedout = 0 WHERE id = '".mysqli_real_escape_string($dbconn,$userId)."'");
|
||||
db_abfrage($dbconn, "UPDATE user SET wrongpw = 0, lastlogin = NOW(), numlogins = numlogins + 1, logedout = 0 WHERE id = ?", array($userId));
|
||||
}
|
||||
$return = new stdClass();
|
||||
$return->success = true;
|
||||
|
||||
+3
-5
@@ -1,7 +1,4 @@
|
||||
<?php
|
||||
// Wartungsskript: nur per Kommandozeile, nie über den Webserver
|
||||
if(PHP_SAPI != "cli")
|
||||
exit;
|
||||
require_once("./incs/constants.php");
|
||||
session_name(SESSION_NAME);
|
||||
session_start();
|
||||
@@ -10,8 +7,9 @@ $settings=readsettings();
|
||||
if($settings == "valid")
|
||||
{
|
||||
|
||||
$dbconn = mysqli_connect($mysql_server, $mysql_user, $mysql_pw);
|
||||
mysqli_select_db($dbconn,$mysql_db);
|
||||
$dbconn = db_verbinden($mysql_server, $mysql_user, $mysql_pw, $mysql_db);
|
||||
if(!$dbconn)
|
||||
$err = 1;
|
||||
}
|
||||
else
|
||||
$err = 1;
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
<?php
|
||||
// Nur per Kommandozeile (Cronjob), nie über den Webserver
|
||||
if(PHP_SAPI != "cli")
|
||||
exit;
|
||||
/*
|
||||
* Datenbank-Backup (Cronjob).
|
||||
*
|
||||
|
||||
+10
-36
@@ -8,10 +8,8 @@ if($settings != "valid")
|
||||
|
||||
if($settings == "valid")
|
||||
{
|
||||
if(!$mysql = @mysqli_connect($mysql_server, $mysql_user, $mysql_pw))
|
||||
$err = error("Verbindung zur Datenbank fehlgeschlagen!!");
|
||||
if(!@mysqli_select_db($mysql,$mysql_db))
|
||||
$err = error("Datenbank nicht gefunden!! ($mysql_db)");
|
||||
if(!$mysql = db_verbinden($mysql_server, $mysql_user, $mysql_pw, $mysql_db))
|
||||
$err = error("Verbindung zur Datenbank fehlgeschlagen: ".htmlspecialchars(mysqli_connect_error()));
|
||||
}
|
||||
|
||||
$_SESSION["local"] =false;
|
||||
@@ -86,41 +84,17 @@ function isLocal(){
|
||||
return $lokal;
|
||||
}
|
||||
|
||||
function checkLogin(){
|
||||
global $mysql;
|
||||
//$mysql = new mysqli($GLOBALS["mysql_server"],$GLOBALS["mysql_user"],$GLOBALS["mysql_pass"],$GLOBALS["mysql_db"]);
|
||||
if(isLocal()){
|
||||
$_SESSION["local"] =true;
|
||||
return true;
|
||||
}
|
||||
if(isset($_SESSION["authKey"])){
|
||||
$res = mysqli_query($mysql,"SELECT id FROM users WHERE lastAuth > DATE_SUB(NOW(), INTERVAL 2 DAY) AND authKey = '".mysqli_real_escape_string($mysql,$_SESSION["authKey"])."' AND name = '".mysqli_real_escape_string($mysql,$_SESSION["user"])."';");
|
||||
if(!$res){
|
||||
echo mysqli_error($mysql);
|
||||
return false;
|
||||
}
|
||||
if(mysqli_num_rows($res) == 1){
|
||||
return isset($_SESSION["Logged"]);
|
||||
}
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ist $_GET["addKey"] eine gültige, höchstens eine Minute alte Freigabe? */
|
||||
function checkAdduser(){
|
||||
global $mysql;
|
||||
//$mysql = new mysqli($GLOBALS["mysql_server"],$GLOBALS["mysql_user"],$GLOBALS["mysql_pass"],$GLOBALS["mysql_db"]);
|
||||
if(!mysqli_query($mysql,"DELETE FROM addKey WHERE datetime < DATE_SUB(NOW(), INTERVAL 1 MINUTE);")){
|
||||
echo mysqli_error($mysql);
|
||||
}
|
||||
$result = mysqli_query($mysql,"SELECT * FROM addKey WHERE accesskey='".mysqli_real_escape_string($mysql,$_GET["addKey"])."';");
|
||||
if(!$result){
|
||||
return false;
|
||||
}
|
||||
if ($result->num_rows > 0) {
|
||||
return true;
|
||||
}
|
||||
db_abfrage($mysql, "DELETE FROM addKey WHERE datetime < DATE_SUB(NOW(), INTERVAL 1 MINUTE)") or print(mysqli_error($mysql));
|
||||
// Nur reine Ziffern: accesskey ist eine Zahlenspalte, MariaDB würde
|
||||
// "12345678xyz" beim Vergleich stillschweigend zu 12345678 machen.
|
||||
$key = $_GET["addKey"] ?? "";
|
||||
if(!is_string($key) || !ctype_digit($key))
|
||||
return false;
|
||||
$anzahl = db_wert($mysql, "SELECT COUNT(*) FROM addKey WHERE accesskey = ?", array((int)$key));
|
||||
return $anzahl > 0;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -2,19 +2,14 @@
|
||||
require_once("../incs/constants.php");
|
||||
session_name(SESSION_NAME);
|
||||
session_start();
|
||||
// Alle AJAX-Endpunkte laden diese Datei: ohne Anmeldung gibt es keine Daten.
|
||||
if(($_SESSION["login"] ?? "") !== "valid")
|
||||
{
|
||||
http_response_code(403);
|
||||
exit("Nicht angemeldet.");
|
||||
}
|
||||
require_once("../incs/settings.php");
|
||||
$settings=readsettings();
|
||||
if($settings == "valid")
|
||||
{
|
||||
|
||||
$dbconn = mysqli_connect($mysql_server, $mysql_user, $mysql_pw);
|
||||
mysqli_select_db($dbconn,$mysql_db);
|
||||
$dbconn = db_verbinden($mysql_server, $mysql_user, $mysql_pw, $mysql_db);
|
||||
if(!$dbconn)
|
||||
$err = 1;
|
||||
}
|
||||
else
|
||||
$err = 1;
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/*
|
||||
* Datenbankzugriff: Verbindungsaufbau und Prepared Statements.
|
||||
*
|
||||
* Neue und umgebaute Abfragen laufen über db_abfrage() und Co. Werte stehen
|
||||
* im SQL nur als ? und kommen getrennt als Array - sie werden nie in den
|
||||
* SQL-String eingesetzt, Escaping entfällt. Tabellen- und Spaltennamen
|
||||
* (z.B. für ORDER BY) lassen sich nicht binden und müssen gegen eine feste
|
||||
* Liste erlaubter Werte geprüft werden.
|
||||
*
|
||||
* Fehler verhalten sich wie bei mysqli_query(): Rückgabe false, Details über
|
||||
* mysqli_error($dbconn). Das bestehende Muster
|
||||
* db_abfrage(...) or $err = error(...mysqli_error($dbconn));
|
||||
* funktioniert also unverändert.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Baut die Verbindung auf und stellt sie einheitlich ein. Gibt die
|
||||
* Verbindung zurück oder false; der Grund steht dann in
|
||||
* mysqli_connect_error().
|
||||
*/
|
||||
function db_verbinden($server, $user, $pw, $db)
|
||||
{
|
||||
// Seit PHP 8.1 wirft mysqli standardmäßig Exceptions. Der Code prüft
|
||||
// Rückgabewerte, also das alte Verhalten wiederherstellen.
|
||||
mysqli_report(MYSQLI_REPORT_OFF);
|
||||
|
||||
$dbconn = @mysqli_connect($server, $user, $pw, $db);
|
||||
if(!$dbconn)
|
||||
return false;
|
||||
|
||||
// Ohne das behandelt der Server die Verbindung je nach Einstellung als
|
||||
// latin1, und UTF-8 aus dem Browser wird doppelt kodiert gespeichert.
|
||||
mysqli_set_charset($dbconn, "utf8mb4");
|
||||
|
||||
// Unabhängig von der Server-Konfiguration immer strikt: ungültige Werte
|
||||
// und fehlende Pflichtfelder sind Fehler, statt still zu '' oder 0 zu
|
||||
// werden.
|
||||
mysqli_query($dbconn, "SET SESSION sql_mode = 'STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'");
|
||||
|
||||
return $dbconn;
|
||||
}
|
||||
|
||||
/*
|
||||
* Führt eine Abfrage mit ?-Platzhaltern aus. Gibt bei SELECT ein
|
||||
* mysqli_result zurück, sonst true, bei Fehlern false.
|
||||
*/
|
||||
function db_abfrage($dbconn, $sql, $params = array())
|
||||
{
|
||||
return mysqli_execute_query($dbconn, $sql, array_values($params));
|
||||
}
|
||||
|
||||
/* Alle Zeilen als Liste assoziativer Arrays, bei Fehlern false. */
|
||||
function db_zeilen($dbconn, $sql, $params = array())
|
||||
{
|
||||
$res = db_abfrage($dbconn, $sql, $params);
|
||||
if(!$res)
|
||||
return false;
|
||||
return mysqli_fetch_all($res, MYSQLI_ASSOC);
|
||||
}
|
||||
|
||||
/* Erste Zeile als assoziatives Array, null ohne Treffer, bei Fehlern false. */
|
||||
function db_zeile($dbconn, $sql, $params = array())
|
||||
{
|
||||
$res = db_abfrage($dbconn, $sql, $params);
|
||||
if(!$res)
|
||||
return false;
|
||||
return mysqli_fetch_assoc($res);
|
||||
}
|
||||
|
||||
/* Erste Spalte der ersten Zeile, null ohne Treffer, bei Fehlern false. */
|
||||
function db_wert($dbconn, $sql, $params = array())
|
||||
{
|
||||
$res = db_abfrage($dbconn, $sql, $params);
|
||||
if(!$res)
|
||||
return false;
|
||||
$zeile = mysqli_fetch_row($res);
|
||||
return $zeile === null ? null : $zeile[0];
|
||||
}
|
||||
+15
-17
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
include_once("constants.php");
|
||||
require_once(__DIR__."/db.php");
|
||||
function readsettings()
|
||||
{
|
||||
if(is_file(CONFIG_PATH.CONFIG_FILE))
|
||||
@@ -17,30 +18,27 @@ function readsettings()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Benutzereinstellungen. Werte und ids roh übergeben - nicht escapen, das
|
||||
* erledigen die Platzhalter.
|
||||
*/
|
||||
function getUserSetting($dbconn,$setting, $user, $default = 0)
|
||||
{
|
||||
$qry2 = mysqli_query($dbconn, "SELECT val FROM setting WHERE opt = '".mysqli_real_escape_string($dbconn, $setting)."' AND user_id = '".mysqli_real_escape_string($dbconn, $user)."'") or die(mysqli_error($dbconn));
|
||||
if($res = mysqli_fetch_array($qry2))
|
||||
$ret = $res[0];
|
||||
else
|
||||
$ret = $default;
|
||||
|
||||
return $ret;
|
||||
$wert = db_wert($dbconn, "SELECT val FROM setting WHERE opt = ? AND user_id = ?", array($setting, $user));
|
||||
if($wert === false)
|
||||
die(mysqli_error($dbconn));
|
||||
return $wert === null ? $default : $wert;
|
||||
}
|
||||
|
||||
function updateUserSetting($dbconn,$setting, $value, $user)
|
||||
{
|
||||
$qry = mysqli_query($dbconn,"SELECT id FROM setting WHERE opt = '".mysqli_real_escape_string($dbconn, $setting)."' AND user_id = '".mysqli_real_escape_string($dbconn, $user)."'") or die(mysqli_error($dbconn));
|
||||
if(mysqli_num_rows($qry))
|
||||
{
|
||||
$res = mysqli_fetch_array($qry);
|
||||
mysqli_query($dbconn, "UPDATE setting SET val = '".mysqli_real_escape_string($dbconn, $value)."' WHERE id = ".$res[0]) or die($mysqli_error($dbconn));
|
||||
echo "update";
|
||||
}
|
||||
$id = db_wert($dbconn, "SELECT id FROM setting WHERE opt = ? AND user_id = ?", array($setting, $user));
|
||||
if($id === false)
|
||||
die(mysqli_error($dbconn));
|
||||
if($id !== null)
|
||||
db_abfrage($dbconn, "UPDATE setting SET val = ? WHERE id = ?", array($value, $id)) or die(mysqli_error($dbconn));
|
||||
else
|
||||
{
|
||||
mysqli_query($dbconn, "INSERT INTO setting SET val = '".mysqli_real_escape_string($dbconn, $value)."', user_id = '".mysqli_real_escape_string($dbconn, $user)."', opt = '".mysqli_real_escape_string($setting)."'") or die(mysqli_error($dbconn));
|
||||
}
|
||||
db_abfrage($dbconn, "INSERT INTO setting SET val = ?, user_id = ?, opt = ?", array($value, $user, $setting)) or die(mysqli_error($dbconn));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -56,10 +56,8 @@ else if($action == "setup")
|
||||
|
||||
if($settings == "valid" && $action != "setup")
|
||||
{
|
||||
if(!$dbconn = @mysqli_connect($mysql_server, $mysql_user, $mysql_pw))
|
||||
$err = error("Verbindung zur Datenbank fehlgeschlagen!!");
|
||||
if(!@mysqli_select_db($dbconn,$mysql_db))
|
||||
$err = error("Datenbank nicht gefunden!! ($mysql_db)");
|
||||
if(!$dbconn = db_verbinden($mysql_server, $mysql_user, $mysql_pw, $mysql_db))
|
||||
$err = error("Verbindung zur Datenbank fehlgeschlagen: ".htmlspecialchars(mysqli_connect_error()));
|
||||
$newversion = checknewversion($version);
|
||||
$status = manageupdate($version, $newversion);
|
||||
$version = $status[1];
|
||||
|
||||
+5
-4
@@ -76,12 +76,13 @@ else
|
||||
{
|
||||
if($_GET["formsent"] == 1)
|
||||
{
|
||||
if(is_file("./styles/".$_POST["style"]))
|
||||
// nur Dateien direkt in styles/, kein ../
|
||||
if(basename($_POST["style"]) === $_POST["style"] && is_file("./styles/".$_POST["style"]))
|
||||
{
|
||||
updateUserSetting($dbconn,"style", mysqli_real_escape_string($dbconn,$_POST["style"]), mysqli_real_escape_string($dbconn,$_SESSION["user"]));
|
||||
updateUserSetting($dbconn,"style", $_POST["style"], $_SESSION["user"]);
|
||||
$_SESSION["style"] = $_POST["style"];
|
||||
}
|
||||
updateUserSetting($dbconn,"show_sks", mysqi_real_escape_string($dbconn,$_POST["show_sks"]), mysqli_real_escape_string($dbconn,$_SESSION["user"]));
|
||||
updateUserSetting($dbconn,"show_sks", (int)$_POST["show_sks"], $_SESSION["user"]);
|
||||
}
|
||||
if(substr($_SESSION["rights"],RIGHTS_SUPERADMIN,1) & RIGHTS_CHANGE || substr($_SESSION["rights"],RIGHTS_SUPERADMIN,1) & RIGHTS_ADD)
|
||||
$smarty->assign("superadmin","add");
|
||||
@@ -129,7 +130,7 @@ else
|
||||
}
|
||||
|
||||
|
||||
$show_sks = getUserSetting($dbconn,"show_sks", mysqli_real_escape_string($dbconn,$_SESSION["user"]), 1);
|
||||
$show_sks = getUserSetting($dbconn,"show_sks", $_SESSION["user"], 1);
|
||||
$smarty->assign("show_sks",$show_sks);
|
||||
$smarty->assign("styles",$styles);
|
||||
|
||||
|
||||
+17
-33
@@ -1,25 +1,21 @@
|
||||
<?php
|
||||
if(!isset($_POST["user"]))
|
||||
$_POST["user"] = "";
|
||||
else
|
||||
$_POST["user"] = htmlspecialchars($_POST["user"]);
|
||||
if(!isset($_POST["pass"]))
|
||||
$_POST["pass"] = "";
|
||||
else
|
||||
$_POST["pass"] = htmlspecialchars($_POST["pass"]);
|
||||
|
||||
$smarty->display("heading.tpl");
|
||||
$smarty->assign("local",isLocal());
|
||||
if(isset($_GET["formsent"]) && $_SESSION["login"] != "valid" && isLocal())
|
||||
{
|
||||
$qry= mysqli_query($dbconn, "SELECT salt FROM user WHERE LOWER(nick) = '".mysql_escape_string(strtolower($_POST["user"]))."' AND blocked = 0") or error("Es ist ein Fehler in der abfrage der Benutzerdaten: <br />".formaterror(mysqli_error($dbconn)));
|
||||
if(mysqli_num_rows($qry) == 1)
|
||||
// Eingaben unverändert verwenden: Passwörter werden beim Anlegen roh
|
||||
// gehasht, ein htmlspecialchars() hier ließ Passwörter mit & < > " '
|
||||
// nie passen. Ausgabe-Escaping übernimmt das Template.
|
||||
$nick = isset($_POST["user"]) && is_string($_POST["user"]) ? $_POST["user"] : "";
|
||||
$pass = isset($_POST["pass"]) && is_string($_POST["pass"]) ? $_POST["pass"] : "";
|
||||
|
||||
$udata = db_zeile($dbconn, "SELECT * FROM user WHERE nick = ? AND blocked = 0", array($nick));
|
||||
if($udata === false)
|
||||
error("Es ist ein Fehler in der abfrage der Benutzerdaten: <br />".formaterror(mysqli_error($dbconn)));
|
||||
elseif($udata === null)
|
||||
error("Dieser Benutzername existiert nicht.");
|
||||
elseif(hash_equals($udata["pass"], crypt($pass, $udata["salt"])))
|
||||
{
|
||||
$res = mysqli_fetch_array($qry);
|
||||
$qry= mysqli_query($dbconn, "SELECT * FROM user WHERE nick = '".mysql_escape_string($_POST["user"])."' AND pass = '".crypt($_POST["pass"],$res[0])."'") or error("Es ist ein Fehler in der abfrage der Benutzerdaten: <br />".formaterror(mysqli_error($dbconn)));
|
||||
if(mysqli_num_rows($qry) == 1)
|
||||
{
|
||||
$udata = mysqli_fetch_assoc($qry);
|
||||
// neue Session-ID nach dem Login, sonst ist Session-Fixation möglich
|
||||
session_regenerate_id(true);
|
||||
$_SESSION["login"] = "valid";
|
||||
@@ -40,18 +36,12 @@ if(isset($_GET["formsent"]) && $_SESSION["login"] != "valid" && isLocal())
|
||||
$_SESSION["zoom"] = getUserSetting($dbconn,"zoom", $_SESSION["user"], 1);
|
||||
$_SESSION["privateNotes"] = getUserSetting($dbconn,"privnotes", $_SESSION["user"], "");
|
||||
|
||||
mysqli_query($dbconn, "UPDATE user SET wrongpw = 0, lastlogin = NOW(), numlogins = numlogins + 1, logedout = 0 WHERE nick = '".mysql_escape_string($_POST["user"])."'");
|
||||
db_abfrage($dbconn, "UPDATE user SET wrongpw = 0, lastlogin = NOW(), numlogins = numlogins + 1, logedout = 0 WHERE id = ?", array($udata["id"]));
|
||||
}
|
||||
else
|
||||
elseif($udata["wrongpw"] < 10)
|
||||
{
|
||||
$qry= mysqli_query($dbconn, "SELECT wrongpw FROM user WHERE nick = '".mysql_escape_string($_POST["user"])."'") or error("Es ist ein Fehler in der abfrage der Benutzerdaten: <br />".formaterror(mysqli_error($dbconn)));;
|
||||
if(mysqli_num_rows($qry))
|
||||
{
|
||||
$wrongpw = mysqli_fetch_array($qry);
|
||||
if($wrongpw[0] < 10)
|
||||
{
|
||||
mysqli_query($dbconn, "UPDATE user SET wrongpw = wrongpw + 1 WHERE nick = '".mysql_escape_string($_POST["user"])."'");
|
||||
$triesleft = 10 - $wrongpw[0];
|
||||
db_abfrage($dbconn, "UPDATE user SET wrongpw = wrongpw + 1 WHERE id = ?", array($udata["id"]));
|
||||
$triesleft = 10 - $udata["wrongpw"];
|
||||
if($triesleft > 1)
|
||||
error("Der Benuzername oder das Passwort sind falsch, bitte versuchen Sie es erneut (Nach weiteren $triesleft Versuchen wird der Benutzer deaktiviert und muss vom Hauptbenutzer wieder aktiviert werden, damit er sich anmelden kann.)");
|
||||
else
|
||||
@@ -59,15 +49,9 @@ if(isset($_GET["formsent"]) && $_SESSION["login"] != "valid" && isLocal())
|
||||
}
|
||||
else
|
||||
{
|
||||
mysqli_query($dbconn, "UPDATE user SET blocked = 1 WHERE nick = '".mysql_escape_string($_POST["user"])."'");
|
||||
db_abfrage($dbconn, "UPDATE user SET blocked = 1 WHERE id = ?", array($udata["id"]));
|
||||
error("Der Benuzer wurde deaktiviert, er muss vom Hauptbenutzer wieder aktiviert werden, damit er sich anmelden kann.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
error("Dieser Benutzername existiert nicht.");
|
||||
}
|
||||
if($_SESSION["login"]=="valid"){
|
||||
header('Location:?action=kunden');
|
||||
|
||||
+7
-8
@@ -7,7 +7,7 @@ if(isset($_GET["id"]) && isset($_GET["addKey"])){
|
||||
// in dieser Session (geprüft in authServer.php). Der addKey ist damit
|
||||
// verbraucht.
|
||||
$_SESSION["passkey_freigabe"] = array("user" => (int)$_GET["id"], "bis" => time() + 300);
|
||||
mysqli_query($mysql, "DELETE FROM addKey WHERE accesskey = '".mysqli_real_escape_string($mysql, $_GET["addKey"])."'");
|
||||
db_abfrage($mysql, "DELETE FROM addKey WHERE accesskey = ?", array((int)$_GET["addKey"]));
|
||||
echo <<<ENDE
|
||||
<html>
|
||||
<head></head>
|
||||
@@ -78,15 +78,14 @@ if(isset($_GET["id"]) && isset($_GET["addKey"])){
|
||||
$smarty->assign("heading","Passkeys für externen Zugang verwalten");
|
||||
$smarty->display("heading.tpl");
|
||||
|
||||
$qry = mysqli_query($_SESSION["dbconn"],"SELECT id, vname, nname FROM user WHERE blocked = 0 AND user.id = ".(int)$_GET["id"]) or die("Datenbank fehler: ".mysqli_error($_SESSION["dbconn"]));
|
||||
$row=mysqli_fetch_array($qry);
|
||||
$row = db_zeile($dbconn, "SELECT id, vname, nname FROM user WHERE blocked = 0 AND user.id = ?", array($_GET["id"]));
|
||||
if($row === false)
|
||||
die("Datenbank fehler: ".mysqli_error($dbconn));
|
||||
$smarty->assign("user",$row);
|
||||
|
||||
$qry = mysqli_query($_SESSION["dbconn"],"SELECT passkeys.id , passkeys.name FROM user JOIN passkeys ON user.id = passkeys.userId WHERE blocked = 0 AND user.id = ".(int)$_GET["id"]) or die("Datenbank fehler: ".mysqli_error($_SESSION["dbconn"]));
|
||||
$keys = array();
|
||||
while($row=mysqli_fetch_array($qry)){
|
||||
$keys[] = $row;
|
||||
}
|
||||
$keys = db_zeilen($dbconn, "SELECT passkeys.id, passkeys.name FROM user JOIN passkeys ON user.id = passkeys.userId WHERE blocked = 0 AND user.id = ?", array($_GET["id"]));
|
||||
if($keys === false)
|
||||
die("Datenbank fehler: ".mysqli_error($dbconn));
|
||||
$smarty->assign("keys",$keys);
|
||||
$smarty->assign("local",isLocal());
|
||||
$smarty->display("userkeys.tpl");
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
<?php
|
||||
require_once("incs/constants.php");
|
||||
session_name(SESSION_NAME);
|
||||
session_start();
|
||||
if((($_SESSION["login"] ?? "") !== "valid"))
|
||||
{
|
||||
http_response_code(403);
|
||||
exit("Nicht angemeldet.");
|
||||
}
|
||||
|
||||
error_reporting(E_ERROR | E_WARNING | E_PARSE);
|
||||
// Standard inclusions
|
||||
@@ -17,8 +9,7 @@ if((($_SESSION["login"] ?? "") !== "valid"))
|
||||
// Zugang zur Statistik-Datenbank steht in der externen Config
|
||||
require_once("incs/settings.php");
|
||||
readsettings();
|
||||
$dbconn = mysqli_connect($stats_mysql_server, $stats_mysql_user, $stats_mysql_pw) or die("Keine Verbindung zur Statistik-Datenbank.");
|
||||
mysqli_select_db($dbconn, $stats_mysql_db);
|
||||
$dbconn = db_verbinden($stats_mysql_server, $stats_mysql_user, $stats_mysql_pw, $stats_mysql_db) or die("Keine Verbindung zur Statistik-Datenbank.");
|
||||
|
||||
$qry = mysqli_query($dbconn, "SELECT DATE_FORMAT(datetime, '%d.%m.%y') AS datetime, MAX(percent) AS value FROM hdd WHERE datetime > DATE_SUB(NOW(), INTERVAL 31 DAY) GROUP BY DATE_FORMAT(datetime, '%d.%m.%y') ORDER BY DATE_FORMAT(datetime, '%y%m%d') ASC") or die(mysqli_error($dbconn));
|
||||
// Dataset definition
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<table><tr><th>Name</th><th>Aktion</th></tr>
|
||||
{foreach $keys as $key}
|
||||
<tr>
|
||||
<td>{$key.name}</td>
|
||||
<td>{$key.name|escape}</td>
|
||||
<td><a href="?action=userkeys&id={$user.id}&del={$key.id}"><span class="del" title="Passkey löschen"></span></a></td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
|
||||
@@ -0,0 +1,418 @@
|
||||
<?php
|
||||
/*
|
||||
* Migration einer Instanz-Datenbank auf das Schema update/schema.sql
|
||||
* (utf8mb4) mit Reparatur doppelt kodierter Texte.
|
||||
*
|
||||
* Hintergrund: Die Anwendung hat jahrelang UTF-8 aus dem Browser über eine
|
||||
* Verbindung geschrieben, die der Server als latin1 behandelt hat. Aus "ä"
|
||||
* wurde dabei "ä". Datensätze, die auf anderem Weg entstanden sind
|
||||
* (phpMyAdmin, neuere Server-Defaults), können dagegen korrekt sein. Deshalb
|
||||
* wird jeder Wert einzeln geprüft und nur repariert, wenn er eindeutig
|
||||
* doppelt kodiert ist.
|
||||
*
|
||||
* Aufruf im Installationsverzeichnis der Instanz (die Zugangsdaten kommen
|
||||
* aus deren Config):
|
||||
*
|
||||
* php update/migration-utf8mb4.php pruefen
|
||||
* Liest nur und gibt einen Bericht aus. Ändert nichts.
|
||||
*
|
||||
* php update/migration-utf8mb4.php migrieren <zieldatenbank>
|
||||
* Legt die Zieldatenbank mit update/schema.sql an und kopiert alle
|
||||
* Daten hinein. Die Quelldatenbank bleibt unverändert. Die Ziel-
|
||||
* datenbank darf noch nicht existieren oder muss leer sein.
|
||||
*
|
||||
* Für lokale Tests lässt sich die Config übergehen:
|
||||
* --server=127.0.0.1:3307 --user=root --db=wagner
|
||||
* Das Passwort kommt dann aus der Umgebungsvariable MIGRATION_PW, damit es
|
||||
* nicht in der Prozessliste steht.
|
||||
*/
|
||||
|
||||
if(PHP_SAPI != "cli")
|
||||
exit("Nur per Kommandozeile aufrufbar.\n");
|
||||
|
||||
require_once(__DIR__."/../incs/db.php");
|
||||
|
||||
function fehler($text)
|
||||
{
|
||||
fwrite(STDERR, "FEHLER: ".$text."\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Kodierung
|
||||
* ------------------------------------------------------------------ */
|
||||
|
||||
/*
|
||||
* Umkehrung dessen, was MariaDB beim Speichern gemacht hat: Unicode-Text
|
||||
* zurück in die Bytes von MySQL-"latin1" (das ist cp1252; die fünf dort
|
||||
* undefinierten Bytes bildet MySQL auf U+0081, U+008D, U+008F, U+0090 und
|
||||
* U+009D ab). Gibt null zurück, wenn ein Zeichen in latin1 nicht vorkommt -
|
||||
* dann kann der Wert nicht über eine latin1-Verbindung entstanden sein.
|
||||
*/
|
||||
function latin1Bytes($text)
|
||||
{
|
||||
static $cp1252 = array(
|
||||
0x20AC => 0x80, 0x201A => 0x82, 0x0192 => 0x83, 0x201E => 0x84,
|
||||
0x2026 => 0x85, 0x2020 => 0x86, 0x2021 => 0x87, 0x02C6 => 0x88,
|
||||
0x2030 => 0x89, 0x0160 => 0x8A, 0x2039 => 0x8B, 0x0152 => 0x8C,
|
||||
0x017D => 0x8E, 0x2018 => 0x91, 0x2019 => 0x92, 0x201C => 0x93,
|
||||
0x201D => 0x94, 0x2022 => 0x95, 0x2013 => 0x96, 0x2014 => 0x97,
|
||||
0x02DC => 0x98, 0x2122 => 0x99, 0x0161 => 0x9A, 0x203A => 0x9B,
|
||||
0x0153 => 0x9C, 0x017E => 0x9E, 0x0178 => 0x9F,
|
||||
0x0081 => 0x81, 0x008D => 0x8D, 0x008F => 0x8F, 0x0090 => 0x90,
|
||||
0x009D => 0x9D,
|
||||
);
|
||||
$bytes = "";
|
||||
foreach(preg_split('//u', $text, -1, PREG_SPLIT_NO_EMPTY) as $zeichen)
|
||||
{
|
||||
$cp = codepoint($zeichen);
|
||||
if($cp < 0x80 || ($cp >= 0xA0 && $cp <= 0xFF))
|
||||
$bytes .= chr($cp);
|
||||
elseif(isset($cp1252[$cp]))
|
||||
$bytes .= chr($cp1252[$cp]);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
function codepoint($zeichen)
|
||||
{
|
||||
$b = array_values(unpack("C*", $zeichen));
|
||||
switch(count($b))
|
||||
{
|
||||
case 1: return $b[0];
|
||||
case 2: return (($b[0] & 0x1F) << 6) | ($b[1] & 0x3F);
|
||||
case 3: return (($b[0] & 0x0F) << 12) | (($b[1] & 0x3F) << 6) | ($b[2] & 0x3F);
|
||||
default: return (($b[0] & 0x07) << 18) | (($b[1] & 0x3F) << 12) | (($b[2] & 0x3F) << 6) | ($b[3] & 0x3F);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Ordnet einen Textwert ein und liefert array(kategorie, neuer_wert).
|
||||
*
|
||||
* ascii nur ASCII, unverändert
|
||||
* korrekt enthält Nicht-ASCII, ist aber kein doppelt kodierter Text
|
||||
* repariert war doppelt kodiert
|
||||
* mehrfach war mehr als doppelt kodiert
|
||||
* unklar sieht teilweise doppelt kodiert aus, lässt sich aber nicht
|
||||
* eindeutig zurückführen; bleibt unverändert
|
||||
*/
|
||||
function pruefeText($wert)
|
||||
{
|
||||
if(!preg_match('/[^\x00-\x7F]/', $wert))
|
||||
return array("ascii", $wert);
|
||||
|
||||
$runden = 0;
|
||||
$aktuell = $wert;
|
||||
while($runden < 5)
|
||||
{
|
||||
$bytes = latin1Bytes($aktuell);
|
||||
// Echte Umlaute in latin1-Bytes ("M\xFCller") sind kein gültiges
|
||||
// UTF-8. Nur wenn die Bytes gültiges UTF-8 mit Nicht-ASCII ergeben,
|
||||
// war der Text doppelt kodiert.
|
||||
if($bytes === null || !preg_match('//u', $bytes) || !preg_match('/[^\x00-\x7F]/', $bytes))
|
||||
break;
|
||||
$aktuell = $bytes;
|
||||
$runden++;
|
||||
}
|
||||
|
||||
if($runden == 1)
|
||||
return array("repariert", $aktuell);
|
||||
if($runden > 1)
|
||||
return array("mehrfach", $aktuell);
|
||||
|
||||
// Typische Reste doppelter Kodierung neben Zeichen, die nicht aus
|
||||
// latin1 stammen können: gemischter Wert, nicht automatisch lösbar.
|
||||
if(preg_match('/[\x{00C2}\x{00C3}][\x{0080}-\x{00BF}\x{0152}\x{0153}\x{0160}\x{0161}\x{0178}\x{017D}\x{017E}\x{0192}\x{02C6}\x{02DC}\x{2013}\x{2014}\x{2018}-\x{201E}\x{2020}-\x{2022}\x{2026}\x{2030}\x{2039}\x{203A}\x{20AC}\x{2122}]/u', $wert))
|
||||
return array("unklar", $wert);
|
||||
|
||||
return array("korrekt", $wert);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Aufruf und Verbindung
|
||||
* ------------------------------------------------------------------ */
|
||||
|
||||
$modus = null;
|
||||
$zielDb = null;
|
||||
$optionen = array();
|
||||
foreach(array_slice($argv, 1) as $arg)
|
||||
{
|
||||
if(preg_match('/^--(server|user|db)=(.*)$/', $arg, $m))
|
||||
$optionen[$m[1]] = $m[2];
|
||||
elseif($modus === null)
|
||||
$modus = $arg;
|
||||
elseif($zielDb === null)
|
||||
$zielDb = $arg;
|
||||
else
|
||||
fehler("Unbekanntes Argument: ".$arg);
|
||||
}
|
||||
|
||||
if($modus != "pruefen" && $modus != "migrieren")
|
||||
fehler("Aufruf: php update/migration-utf8mb4.php pruefen | migrieren <zieldatenbank>");
|
||||
if($modus == "migrieren" && !preg_match('/^[A-Za-z0-9_]+$/', (string)$zielDb))
|
||||
fehler("Zieldatenbank fehlt oder enthält unzulässige Zeichen.");
|
||||
|
||||
if(isset($optionen["db"]))
|
||||
{
|
||||
$server = isset($optionen["server"]) ? $optionen["server"] : "localhost";
|
||||
$user = isset($optionen["user"]) ? $optionen["user"] : "";
|
||||
$pw = (string)getenv("MIGRATION_PW");
|
||||
$quellDb = $optionen["db"];
|
||||
}
|
||||
else
|
||||
{
|
||||
require_once(__DIR__."/../incs/constants.php");
|
||||
require_once(__DIR__."/../incs/settings.php");
|
||||
if(readsettings() != "valid")
|
||||
fehler("Konfiguration ".CONFIG_PATH.CONFIG_FILE." nicht lesbar. Im Installationsverzeichnis der Instanz aufrufen.");
|
||||
$server = $mysql_server;
|
||||
$user = $mysql_user;
|
||||
$pw = $mysql_pw;
|
||||
$quellDb = $mysql_db;
|
||||
}
|
||||
|
||||
if($modus == "migrieren" && strcasecmp($zielDb, $quellDb) == 0)
|
||||
fehler("Quelle und Ziel sind dieselbe Datenbank.");
|
||||
|
||||
// Lesen immer als utf8mb4: Der Server wandelt dabei nur um, die Reparatur
|
||||
// passiert ausschließlich hier im Skript.
|
||||
$quelle = db_verbinden($server, $user, $pw, $quellDb) or fehler("Keine Verbindung zu ".$quellDb.": ".mysqli_connect_error());
|
||||
|
||||
/* Spalten einer Datenbank: tabelle(klein) => array(name, spalten) */
|
||||
function tabellen($dbconn, $db)
|
||||
{
|
||||
$tabellen = array();
|
||||
$zeilen = db_zeilen($dbconn, "SELECT table_name AS t, column_name AS c, data_type AS typ, is_nullable AS nullbar, column_default AS standard, character_set_name AS zeichensatz, extra
|
||||
FROM information_schema.columns WHERE table_schema = ? ORDER BY table_name, ordinal_position", array($db));
|
||||
foreach($zeilen as $z)
|
||||
{
|
||||
$schluessel = strtolower($z["t"]);
|
||||
if(!isset($tabellen[$schluessel]))
|
||||
$tabellen[$schluessel] = array("name" => $z["t"], "spalten" => array());
|
||||
$tabellen[$schluessel]["spalten"][$z["c"]] = $z;
|
||||
}
|
||||
return $tabellen;
|
||||
}
|
||||
|
||||
$quellTabellen = tabellen($quelle, $quellDb);
|
||||
if(!$quellTabellen)
|
||||
fehler("Datenbank ".$quellDb." enthält keine Tabellen.");
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Zielschema anlegen
|
||||
* ------------------------------------------------------------------ */
|
||||
|
||||
$ziel = null;
|
||||
if($modus == "migrieren")
|
||||
{
|
||||
$vorhanden = db_wert($quelle, "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = ?", array($zielDb));
|
||||
if($vorhanden > 0)
|
||||
fehler("Zieldatenbank ".$zielDb." existiert und ist nicht leer.");
|
||||
mysqli_query($quelle, "CREATE DATABASE IF NOT EXISTS `".$zielDb."` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci")
|
||||
or fehler("Zieldatenbank nicht anlegbar: ".mysqli_error($quelle));
|
||||
|
||||
$ziel = db_verbinden($server, $user, $pw, $zielDb) or fehler("Keine Verbindung zu ".$zielDb.": ".mysqli_connect_error());
|
||||
$schema = file_get_contents(__DIR__."/schema.sql") or fehler("update/schema.sql nicht lesbar.");
|
||||
if(!mysqli_multi_query($ziel, $schema))
|
||||
fehler("Schema: ".mysqli_error($ziel));
|
||||
do {
|
||||
if($r = mysqli_store_result($ziel))
|
||||
mysqli_free_result($r);
|
||||
} while(mysqli_more_results($ziel) && mysqli_next_result($ziel));
|
||||
if(mysqli_errno($ziel))
|
||||
fehler("Schema: ".mysqli_error($ziel));
|
||||
|
||||
// Beim Kopieren: ids 0 behalten, Fremdschlüssel erst hinterher prüfen.
|
||||
mysqli_query($ziel, "SET SESSION sql_mode = 'STRICT_ALL_TABLES,NO_AUTO_VALUE_ON_ZERO,NO_ENGINE_SUBSTITUTION'");
|
||||
mysqli_query($ziel, "SET FOREIGN_KEY_CHECKS = 0");
|
||||
$zielTabellen = tabellen($ziel, $zielDb);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Im Prüfmodus zählt das Schema aus der Datei nicht - geprüft wird,
|
||||
// was in der Quelle steht.
|
||||
$zielTabellen = $quellTabellen;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Tabellen durchgehen
|
||||
* ------------------------------------------------------------------ */
|
||||
|
||||
/* Wert für eine Spalte, die es in der Quelle nicht gibt */
|
||||
function ersatzwert($spalte)
|
||||
{
|
||||
if(stripos($spalte["extra"], "auto_increment") !== false)
|
||||
return null; // Spalte weglassen, die Datenbank vergibt die Werte
|
||||
if($spalte["standard"] !== null && strtoupper($spalte["standard"]) !== "NULL")
|
||||
return null; // Spalte weglassen, DEFAULT greift
|
||||
if($spalte["nullbar"] == "YES")
|
||||
return array(null);
|
||||
return array(leerwert($spalte));
|
||||
}
|
||||
|
||||
/* Was der alte, nicht strikte Modus für einen fehlenden Wert eingesetzt hätte */
|
||||
function leerwert($spalte)
|
||||
{
|
||||
switch($spalte["typ"])
|
||||
{
|
||||
case "date": return "0000-00-00";
|
||||
case "datetime": case "timestamp": return "0000-00-00 00:00:00";
|
||||
case "time": return "00:00:00";
|
||||
case "char": case "varchar": case "text": case "tinytext": case "mediumtext": case "longtext": case "enum": case "set":
|
||||
return "";
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
$bericht = array();
|
||||
$hinweise = array();
|
||||
|
||||
foreach($quellTabellen as $schluessel => $q)
|
||||
if(!isset($zielTabellen[$schluessel]))
|
||||
$hinweise[] = "Tabelle ".$q["name"]." gibt es im neuen Schema nicht, sie wird nicht übernommen.";
|
||||
|
||||
foreach($zielTabellen as $schluessel => $z)
|
||||
{
|
||||
if(!isset($quellTabellen[$schluessel]))
|
||||
{
|
||||
$hinweise[] = "Tabelle ".$z["name"]." fehlt in der Quelle und bleibt leer.";
|
||||
continue;
|
||||
}
|
||||
$q = $quellTabellen[$schluessel];
|
||||
|
||||
$gemeinsam = array();
|
||||
$ergaenzt = array();
|
||||
foreach($z["spalten"] as $name => $spalte)
|
||||
{
|
||||
if(isset($q["spalten"][$name]))
|
||||
$gemeinsam[] = $name;
|
||||
elseif(($ersatz = ersatzwert($spalte)) !== null)
|
||||
$ergaenzt[$name] = $ersatz[0];
|
||||
}
|
||||
foreach(array_diff(array_keys($q["spalten"]), array_keys($z["spalten"])) as $name)
|
||||
$hinweise[] = "Spalte ".$q["name"].".".$name." gibt es im neuen Schema nicht, sie wird nicht übernommen.";
|
||||
foreach($ergaenzt as $name => $wert)
|
||||
$hinweise[] = "Spalte ".$z["name"].".".$name." fehlt in der Quelle und wird mit ".var_export($wert, true)." gefüllt.";
|
||||
|
||||
// Im Ziel Pflicht, in der Quelle darf NULL stehen: dort den Leerwert
|
||||
// einsetzen, sonst lehnt der strikte Modus die Zeile ab.
|
||||
$nullErsatz = array();
|
||||
foreach($gemeinsam as $name)
|
||||
if($z["spalten"][$name]["nullbar"] == "NO" && $q["spalten"][$name]["nullbar"] == "YES")
|
||||
$nullErsatz[$name] = 0;
|
||||
|
||||
$textSpalten = array();
|
||||
foreach($gemeinsam as $name)
|
||||
if($q["spalten"][$name]["zeichensatz"] !== null)
|
||||
$textSpalten[] = $name;
|
||||
|
||||
$liste = implode(", ", array_map(function($n) { return "`".$n."`"; }, $gemeinsam));
|
||||
$res = mysqli_query($quelle, "SELECT ".$liste." FROM `".$q["name"]."`", MYSQLI_USE_RESULT)
|
||||
or fehler($q["name"].": ".mysqli_error($quelle));
|
||||
|
||||
$stmt = null;
|
||||
if($ziel)
|
||||
{
|
||||
$spaltenZiel = array_merge($gemeinsam, array_keys($ergaenzt));
|
||||
$sql = "INSERT INTO `".$z["name"]."` (".implode(", ", array_map(function($n) { return "`".$n."`"; }, $spaltenZiel)).") VALUES (".implode(", ", array_fill(0, count($spaltenZiel), "?")).")";
|
||||
$stmt = mysqli_prepare($ziel, $sql) or fehler($z["name"].": ".mysqli_error($ziel));
|
||||
mysqli_begin_transaction($ziel);
|
||||
}
|
||||
|
||||
$zeilen = 0;
|
||||
while($zeile = mysqli_fetch_assoc($res))
|
||||
{
|
||||
$zeilen++;
|
||||
foreach($textSpalten as $name)
|
||||
{
|
||||
if($zeile[$name] === null)
|
||||
continue;
|
||||
list($kategorie, $neu) = pruefeText($zeile[$name]);
|
||||
if(!isset($bericht[$q["name"]][$name]))
|
||||
$bericht[$q["name"]][$name] = array("ascii" => 0, "korrekt" => 0, "repariert" => 0, "mehrfach" => 0, "unklar" => 0, "unklar_ids" => array());
|
||||
$bericht[$q["name"]][$name][$kategorie]++;
|
||||
if($kategorie == "unklar" && isset($zeile["id"]) && count($bericht[$q["name"]][$name]["unklar_ids"]) < 20)
|
||||
$bericht[$q["name"]][$name]["unklar_ids"][] = $zeile["id"];
|
||||
$zeile[$name] = $neu;
|
||||
}
|
||||
foreach($nullErsatz as $name => $anzahl)
|
||||
{
|
||||
if($zeile[$name] === null)
|
||||
{
|
||||
$zeile[$name] = leerwert($z["spalten"][$name]);
|
||||
$nullErsatz[$name]++;
|
||||
}
|
||||
}
|
||||
if($stmt)
|
||||
{
|
||||
$werte = array_merge(array_values($zeile), array_values($ergaenzt));
|
||||
mysqli_stmt_execute($stmt, $werte)
|
||||
or fehler($z["name"].", Zeile ".$zeilen.(isset($zeile["id"]) ? " (id ".$zeile["id"].")" : "").": ".mysqli_stmt_error($stmt));
|
||||
}
|
||||
}
|
||||
mysqli_free_result($res);
|
||||
foreach($nullErsatz as $name => $anzahl)
|
||||
if($anzahl > 0)
|
||||
$hinweise[] = "Spalte ".$z["name"].".".$name.": ".$anzahl." Zeilen mit NULL, im neuen Schema Pflichtfeld, gefüllt mit ".var_export(leerwert($z["spalten"][$name]), true).".";
|
||||
|
||||
if($stmt)
|
||||
{
|
||||
mysqli_commit($ziel);
|
||||
mysqli_stmt_close($stmt);
|
||||
$anzahl = db_wert($ziel, "SELECT COUNT(*) FROM `".$z["name"]."`");
|
||||
if($anzahl != $zeilen)
|
||||
fehler($z["name"].": ".$zeilen." Zeilen gelesen, aber ".$anzahl." im Ziel.");
|
||||
}
|
||||
$bericht[$q["name"]]["_zeilen"] = $zeilen;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Fremdschlüssel prüfen (nur Ziel)
|
||||
* ------------------------------------------------------------------ */
|
||||
|
||||
$verwaist = array();
|
||||
if($ziel)
|
||||
{
|
||||
mysqli_query($ziel, "SET FOREIGN_KEY_CHECKS = 1");
|
||||
$fks = db_zeilen($ziel, "SELECT table_name AS t, column_name AS c, referenced_table_name AS rt, referenced_column_name AS rc
|
||||
FROM information_schema.key_column_usage WHERE table_schema = ? AND referenced_table_name IS NOT NULL", array($zielDb));
|
||||
foreach($fks as $fk)
|
||||
{
|
||||
$anzahl = db_wert($ziel, "SELECT COUNT(*) FROM `".$fk["t"]."` k LEFT JOIN `".$fk["rt"]."` e ON e.`".$fk["rc"]."` = k.`".$fk["c"]."` WHERE k.`".$fk["c"]."` IS NOT NULL AND e.`".$fk["rc"]."` IS NULL");
|
||||
if($anzahl > 0)
|
||||
$verwaist[] = sprintf("%s.%s -> %s.%s: %d Zeilen ohne Gegenstück", $fk["t"], $fk["c"], $fk["rt"], $fk["rc"], $anzahl);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Bericht
|
||||
* ------------------------------------------------------------------ */
|
||||
|
||||
echo "Migration utf8mb4 - ".($modus == "pruefen" ? "Prüfmodus (nichts geändert)" : "Migration nach ".$zielDb)."\n";
|
||||
echo "Quelle: ".$quellDb."\n\n";
|
||||
|
||||
$summe = array("repariert" => 0, "mehrfach" => 0, "unklar" => 0, "korrekt" => 0);
|
||||
printf("%-40s %8s %8s %9s %8s %7s\n", "Spalte", "Zeilen", "korrekt", "repariert", "mehrfach", "unklar");
|
||||
foreach($bericht as $tabelle => $spalten)
|
||||
{
|
||||
$zeilen = $spalten["_zeilen"];
|
||||
unset($spalten["_zeilen"]);
|
||||
foreach($spalten as $spalte => $w)
|
||||
{
|
||||
foreach($summe as $k => $v)
|
||||
$summe[$k] += $w[$k];
|
||||
if($w["korrekt"] + $w["repariert"] + $w["mehrfach"] + $w["unklar"] == 0)
|
||||
continue; // reine ASCII-Spalte
|
||||
printf("%-40s %8d %8d %9d %8d %7d\n", $tabelle.".".$spalte, $zeilen, $w["korrekt"], $w["repariert"], $w["mehrfach"], $w["unklar"]);
|
||||
if($w["unklar_ids"])
|
||||
echo " unklar bei id: ".implode(", ", $w["unklar_ids"]).(count($w["unklar_ids"]) == 20 ? ", ..." : "")."\n";
|
||||
}
|
||||
}
|
||||
printf("\nSumme: %d korrekt, %d repariert, %d mehrfach kodiert, %d unklar\n", $summe["korrekt"], $summe["repariert"], $summe["mehrfach"], $summe["unklar"]);
|
||||
|
||||
if($hinweise)
|
||||
echo "\nHinweise:\n - ".implode("\n - ", $hinweise)."\n";
|
||||
if($ziel)
|
||||
echo "\nFremdschlüssel: ".($verwaist ? "\n - ".implode("\n - ", $verwaist) : "alle Verweise gültig")."\n";
|
||||
@@ -72,10 +72,8 @@ else
|
||||
$settings=readsettings();
|
||||
if($settings == "valid")
|
||||
{
|
||||
if(!$dbconn = @mysqli_connect($mysql_server, $mysql_user, $mysql_pw))
|
||||
$err = error("Verbindung zur Datenbank fehlgeschlagen!!");
|
||||
if(!@mysqli_select_db($dbconn,$mysql_db))
|
||||
$err = error("Datenbank nicht gefunden!!");
|
||||
if(!$dbconn = db_verbinden($mysql_server, $mysql_user, $mysql_pw, $mysql_db))
|
||||
$err = error("Verbindung zur Datenbank fehlgeschlagen: ".htmlspecialchars(mysqli_connect_error()));
|
||||
|
||||
|
||||
if(!$err)
|
||||
|
||||
@@ -0,0 +1,672 @@
|
||||
-- Schema der Kundenverwaltung
|
||||
--
|
||||
-- Maßgeblich ist die Datenbank der Instanz kunden; project und work
|
||||
-- stammen aus ingwa, weil sie dort fehlen, der Code sie aber braucht.
|
||||
-- Einheitlich utf8mb4. Die Anwendung verbindet sich im strikten sql_mode
|
||||
-- (siehe db_verbinden() in incs/db.php).
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
CREATE TABLE `accesstype` (
|
||||
`id` tinyint(3) NOT NULL AUTO_INCREMENT,
|
||||
`typ` varchar(20) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `addKey` (
|
||||
`accesskey` int(11) NOT NULL,
|
||||
`datetime` datetime NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `adresse` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`partner_id` int(11) NOT NULL,
|
||||
`anrede_id` int(5) NOT NULL,
|
||||
`anrede2_id` int(5) NOT NULL,
|
||||
`titel_id` int(5) NOT NULL,
|
||||
`titel2_id` int(5) NOT NULL,
|
||||
`vname` varchar(50) NOT NULL,
|
||||
`vname2` varchar(50) NOT NULL,
|
||||
`nname` varchar(50) NOT NULL,
|
||||
`nname2` varchar(50) NOT NULL,
|
||||
`firma` varchar(50) NOT NULL,
|
||||
`str_id` int(11) NOT NULL,
|
||||
`typ_id` int(2) NOT NULL,
|
||||
`hnr` varchar(10) NOT NULL,
|
||||
`zusatz` varchar(100) NOT NULL,
|
||||
`gebdat` date NOT NULL,
|
||||
`gebdat2` date NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_partner_titel_id` (`titel_id`),
|
||||
KEY `fk_partner_anrede_id` (`anrede_id`),
|
||||
KEY `fk_adr_str_id` (`str_id`),
|
||||
KEY `fk_adr_typ_id` (`typ_id`),
|
||||
KEY `onlyoneadresstype` (`partner_id`,`typ_id`),
|
||||
CONSTRAINT `fk_adr_partner_id` FOREIGN KEY (`partner_id`) REFERENCES `partner` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_adr_str_id` FOREIGN KEY (`str_id`) REFERENCES `strasse` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_adr_typ_id` FOREIGN KEY (`typ_id`) REFERENCES `adresstyp` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_partner_anrede_id` FOREIGN KEY (`anrede_id`) REFERENCES `anrede` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_partner_titel_id` FOREIGN KEY (`titel_id`) REFERENCES `titel` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `adresstyp` (
|
||||
`id` int(2) NOT NULL AUTO_INCREMENT,
|
||||
`typ` varchar(20) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `altlasten` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`vacationdays` int(11) NOT NULL,
|
||||
`hours` decimal(8,4) NOT NULL,
|
||||
`ma_id` int(11) NOT NULL,
|
||||
`last_generated` date NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_altlasten_user_id` (`ma_id`),
|
||||
CONSTRAINT `fk_altlasten_user_id` FOREIGN KEY (`ma_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `anrede` (
|
||||
`id` int(5) NOT NULL AUTO_INCREMENT,
|
||||
`anrede` varchar(20) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `artikel` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`bezeichn` varchar(150) NOT NULL,
|
||||
`typ_id` int(5) NOT NULL,
|
||||
`datetime` datetime NOT NULL,
|
||||
`user_id` int(11) NOT NULL,
|
||||
`einheit_id` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_artikel_typ_id` (`typ_id`),
|
||||
KEY `fk_art_rech_einheit_id` (`einheit_id`),
|
||||
KEY `fk_artikel_user_id` (`user_id`),
|
||||
CONSTRAINT `fk_art_rech_einheit_id` FOREIGN KEY (`einheit_id`) REFERENCES `einheit` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_artikel_typ_id` FOREIGN KEY (`typ_id`) REFERENCES `artikeltyp` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_artikel_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `artikel_eigensch` (
|
||||
`art_id` int(11) NOT NULL,
|
||||
`eig_id` int(11) NOT NULL,
|
||||
`rech_id` int(11) NOT NULL,
|
||||
`posnr` int(5) NOT NULL,
|
||||
`artposnr` int(11) NOT NULL,
|
||||
KEY `fk_art_eig_art_id` (`art_id`),
|
||||
KEY `fk_art_eig_rech_id` (`rech_id`),
|
||||
KEY `fk_art_eig_eig_id` (`eig_id`),
|
||||
CONSTRAINT `fk_art_eig_art_id` FOREIGN KEY (`art_id`) REFERENCES `artikel` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_art_eig_eig_id` FOREIGN KEY (`eig_id`) REFERENCES `eigensch` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_art_eig_rech_id` FOREIGN KEY (`rech_id`) REFERENCES `rechnung` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `artikel_rechn` (
|
||||
`art_id` int(11) NOT NULL,
|
||||
`rech_id` int(11) NOT NULL,
|
||||
`posnr` int(5) NOT NULL,
|
||||
`rabatt` int(3) NOT NULL,
|
||||
`rabatttyp` int(2) NOT NULL,
|
||||
`menge` decimal(6,3) NOT NULL,
|
||||
`preis` decimal(10,2) DEFAULT NULL,
|
||||
`angtyp` int(1) NOT NULL,
|
||||
`artmwst` int(3) NOT NULL,
|
||||
`wanr` varchar(100) NOT NULL,
|
||||
`pagebreak` int(1) NOT NULL,
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_art_rech_art_id` (`art_id`),
|
||||
KEY `fk_art_rech_rech_id` (`rech_id`),
|
||||
CONSTRAINT `fk_art_rech_art_id` FOREIGN KEY (`art_id`) REFERENCES `artikel` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_art_rech_rech_id` FOREIGN KEY (`rech_id`) REFERENCES `rechnung` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `artikel_termin` (
|
||||
`art_id` int(11) NOT NULL,
|
||||
`termin_id` int(11) NOT NULL,
|
||||
`menge` decimal(6,3) NOT NULL,
|
||||
`rabatt` int(3) NOT NULL,
|
||||
`wanr` varchar(100) NOT NULL,
|
||||
KEY `fk_art_term_art_id` (`art_id`),
|
||||
KEY `fk_art_term_ang_id` (`termin_id`),
|
||||
CONSTRAINT `fk_art_term_ang_id` FOREIGN KEY (`termin_id`) REFERENCES `termin` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_art_term_art_id` FOREIGN KEY (`art_id`) REFERENCES `artikel` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `artikelsks` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`rechnr` int(11) NOT NULL,
|
||||
`bezeichn1` varchar(60) NOT NULL,
|
||||
`bezeichn2` varchar(60) NOT NULL,
|
||||
`menge` decimal(6,3) NOT NULL,
|
||||
`beschr` text DEFAULT NULL,
|
||||
`pos` tinyint(3) NOT NULL,
|
||||
`rabatt` tinyint(3) NOT NULL,
|
||||
`preis` decimal(10,2) DEFAULT NULL,
|
||||
`datetime` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_artikelsks_rech_id` (`rechnr`),
|
||||
CONSTRAINT `fk_artikelsks_rech_id` FOREIGN KEY (`rechnr`) REFERENCES `rechnung` (`rechnr`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `artikeltyp` (
|
||||
`id` int(5) NOT NULL AUTO_INCREMENT,
|
||||
`bezeichn` varchar(50) NOT NULL,
|
||||
`dropdown` tinyint(1) NOT NULL,
|
||||
`list` tinyint(1) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `ausgabe` (
|
||||
`id` int(11) NOT NULL,
|
||||
`user_id` int(11) NOT NULL,
|
||||
`partner_id` int(11) NOT NULL,
|
||||
`rec_kto_id` int(11) NOT NULL,
|
||||
`send_kto_id` int(11) NOT NULL,
|
||||
`betr` decimal(12,3) NOT NULL,
|
||||
`rabatt` decimal(4,1) NOT NULL,
|
||||
KEY `fk_ausg_user_id` (`user_id`),
|
||||
KEY `fk_ausg_reckto_id` (`rec_kto_id`),
|
||||
KEY `fk_ausg_sendkto_id` (`send_kto_id`),
|
||||
KEY `fk_ausg_partner_id` (`partner_id`),
|
||||
CONSTRAINT `fk_ausg_partner_id` FOREIGN KEY (`partner_id`) REFERENCES `partner` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_ausg_reckto_id` FOREIGN KEY (`rec_kto_id`) REFERENCES `konto` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_ausg_sendkto_id` FOREIGN KEY (`send_kto_id`) REFERENCES `konto` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_ausg_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `bank` (
|
||||
`id` int(5) NOT NULL AUTO_INCREMENT,
|
||||
`blz` varchar(30) NOT NULL,
|
||||
`bank` varchar(100) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `buchungsKontos` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`kto` int(11) NOT NULL,
|
||||
`name` varchar(100) NOT NULL,
|
||||
`descr` text NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `eigensch` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`bezeichn` varchar(100) NOT NULL,
|
||||
`wert` varchar(50) NOT NULL,
|
||||
`einheit_id` int(11) NOT NULL,
|
||||
`datetime` datetime NOT NULL,
|
||||
`user_id` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_eigensch_user_id` (`user_id`),
|
||||
KEY `fk_eigensch_einheit_id` (`einheit_id`),
|
||||
CONSTRAINT `fk_eigensch_einheit_id` FOREIGN KEY (`einheit_id`) REFERENCES `einheit` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_eigensch_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `einheit` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`einheit` varchar(10) NOT NULL,
|
||||
`si` tinyint(1) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `kontakt` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`partner_id` int(11) NOT NULL,
|
||||
`typ_id` int(3) NOT NULL,
|
||||
`kontakt` varchar(100) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_kontakt_typ_id` (`typ_id`),
|
||||
KEY `fk_kontakt_partner_id` (`partner_id`),
|
||||
CONSTRAINT `fk_kontakt_partner_id` FOREIGN KEY (`partner_id`) REFERENCES `partner` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_kontakt_typ_id` FOREIGN KEY (`typ_id`) REFERENCES `kontakttyp` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `kontakttyp` (
|
||||
`id` int(3) NOT NULL AUTO_INCREMENT,
|
||||
`typ` varchar(20) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `konto` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`bank_id` int(5) NOT NULL,
|
||||
`partner_id` int(11) NOT NULL,
|
||||
`inhaber` varchar(50) NOT NULL,
|
||||
`iban` varchar(30) NOT NULL,
|
||||
`swift` varchar(15) NOT NULL,
|
||||
`ktonr` varchar(20) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_kto_partner_id` (`partner_id`),
|
||||
KEY `fk_kto_bank_id` (`bank_id`),
|
||||
CONSTRAINT `fk_kto_bank_id` FOREIGN KEY (`bank_id`) REFERENCES `bank` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_kto_partner_id` FOREIGN KEY (`partner_id`) REFERENCES `partner` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `land` (
|
||||
`id` int(5) NOT NULL AUTO_INCREMENT,
|
||||
`land_short` varchar(5) NOT NULL,
|
||||
`land` varchar(30) NOT NULL,
|
||||
`datetime` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `log` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`typ_id` tinyint(3) NOT NULL,
|
||||
`user_id` int(11) NOT NULL,
|
||||
`datetime` datetime NOT NULL,
|
||||
`qry` text NOT NULL,
|
||||
`undo_qry` text DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_log_accesstype_id` (`typ_id`),
|
||||
KEY `fk_log_user_id` (`user_id`),
|
||||
CONSTRAINT `fk_log_accesstype_id` FOREIGN KEY (`typ_id`) REFERENCES `accesstype` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_log_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `message` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`send_id` int(11) NOT NULL,
|
||||
`rec_id` int(11) NOT NULL,
|
||||
`head` varchar(50) DEFAULT NULL,
|
||||
`msg` text NOT NULL,
|
||||
`rd` tinyint(1) NOT NULL,
|
||||
`datetime` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_msg_senduser_id` (`send_id`),
|
||||
KEY `fk_msg_recuser_id` (`rec_id`),
|
||||
CONSTRAINT `fk_msg_recuser_id` FOREIGN KEY (`rec_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_msg_senduser_id` FOREIGN KEY (`send_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `mwst` (
|
||||
`id` int(3) NOT NULL AUTO_INCREMENT,
|
||||
`mwst` decimal(4,1) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `mykonto` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`bank_id` int(5) NOT NULL,
|
||||
`inhaber` varchar(50) NOT NULL,
|
||||
`iban` varchar(30) NOT NULL,
|
||||
`swift` varchar(15) NOT NULL,
|
||||
`ktonr` varchar(20) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_mykto_bank_id` (`bank_id`),
|
||||
CONSTRAINT `fk_mykto_bank_id` FOREIGN KEY (`bank_id`) REFERENCES `bank` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `notiz` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`partner_id` int(11) NOT NULL,
|
||||
`notiz` text NOT NULL,
|
||||
`datetime` datetime NOT NULL,
|
||||
`color` varchar(6) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_notizen_partner_id` (`partner_id`),
|
||||
CONSTRAINT `fk_notizen_partner_id` FOREIGN KEY (`partner_id`) REFERENCES `partner` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `ort` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`ort` varchar(30) NOT NULL,
|
||||
`ortsteil` varchar(30) NOT NULL,
|
||||
`plz` varchar(15) NOT NULL,
|
||||
`vwahl` varchar(15) NOT NULL,
|
||||
`land_id` int(5) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_ort_land_id` (`land_id`),
|
||||
CONSTRAINT `fk_ort_land_id` FOREIGN KEY (`land_id`) REFERENCES `land` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `partner` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`datetime_new` datetime NOT NULL,
|
||||
`datetime_lastchange` datetime NOT NULL,
|
||||
`user_id` int(11) NOT NULL,
|
||||
`typ_id` int(2) NOT NULL,
|
||||
`zahlziel_id` int(3) NOT NULL,
|
||||
`rabatt` int(3) NOT NULL,
|
||||
`sks_not_checked` int(1) NOT NULL,
|
||||
`sks_kdnotiz` text NOT NULL,
|
||||
`updated_by` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_partner_typ_id` (`typ_id`),
|
||||
KEY `fk_partner_zahlziel_id` (`zahlziel_id`),
|
||||
KEY `fk_partner_user_id` (`user_id`),
|
||||
CONSTRAINT `fk_partner_typ_id` FOREIGN KEY (`typ_id`) REFERENCES `partnertyp` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_partner_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_partner_zahlziel_id` FOREIGN KEY (`zahlziel_id`) REFERENCES `zahlziel` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `partnertyp` (
|
||||
`id` int(2) NOT NULL AUTO_INCREMENT,
|
||||
`typ` varchar(15) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `passkeys` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`lastAuth` datetime NOT NULL,
|
||||
`name` varchar(40) NOT NULL,
|
||||
`userId` int(11) NOT NULL,
|
||||
`credentialId` varchar(1023) NOT NULL,
|
||||
`credentialPublicKey` text NOT NULL,
|
||||
`signatureCounter` text NOT NULL,
|
||||
`authKey` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `project` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(150) NOT NULL,
|
||||
`name2` varchar(150) NOT NULL,
|
||||
`partner_id` int(11) NOT NULL,
|
||||
`changetime` datetime NOT NULL,
|
||||
`changeuser` int(11) NOT NULL,
|
||||
`datetime` datetime NOT NULL,
|
||||
`intro` text NOT NULL,
|
||||
`outro` text NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fek_proj_partner_id` (`partner_id`),
|
||||
CONSTRAINT `fek_proj_partner_id` FOREIGN KEY (`partner_id`) REFERENCES `partner` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `rechnr` (
|
||||
`rechnr` int(11) NOT NULL,
|
||||
`typ_id` int(5) NOT NULL,
|
||||
PRIMARY KEY (`rechnr`,`typ_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `rechnung` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`adressfields` varchar(12) NOT NULL,
|
||||
`anrede1` varchar(150) NOT NULL,
|
||||
`anrede2` varchar(150) NOT NULL,
|
||||
`partner_id` int(11) NOT NULL,
|
||||
`mwst_id` int(3) NOT NULL,
|
||||
`user_id` int(11) NOT NULL,
|
||||
`typ_id` int(2) NOT NULL,
|
||||
`zahlziel_id` int(3) NOT NULL,
|
||||
`adresse_id` int(11) NOT NULL,
|
||||
`wahrung_id` tinyint(3) NOT NULL,
|
||||
`changetime` datetime NOT NULL,
|
||||
`changeuser` int(11) NOT NULL,
|
||||
`datetime` datetime NOT NULL,
|
||||
`rechnr` int(11) NOT NULL,
|
||||
`rabatt` int(3) NOT NULL,
|
||||
`rabattdesc` varchar(100) NOT NULL,
|
||||
`intro` text NOT NULL,
|
||||
`outro` text NOT NULL,
|
||||
`sks` tinyint(1) NOT NULL,
|
||||
`sub_mwst` int(1) NOT NULL,
|
||||
`kommission` int(11) NOT NULL,
|
||||
`lieferdatum` varchar(100) NOT NULL,
|
||||
`adresserweiterung` varchar(100) NOT NULL,
|
||||
`storno` int(1) NOT NULL DEFAULT 0,
|
||||
`stornodate` datetime NOT NULL,
|
||||
`buchungsKto_id` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fek_rech_partner_id` (`partner_id`),
|
||||
KEY `fek_rech_adresse_id` (`adresse_id`),
|
||||
KEY `fek_rech_mwst_id` (`mwst_id`),
|
||||
KEY `fek_rech_user_id` (`user_id`),
|
||||
KEY `fek_rech_zahlziehl_id` (`zahlziel_id`),
|
||||
KEY `fek_rech_typ_id` (`typ_id`),
|
||||
KEY `fek_rech_wahrung_id` (`wahrung_id`),
|
||||
KEY `rechnr` (`rechnr`),
|
||||
KEY `fk_rech_buchungsKto_id` (`buchungsKto_id`),
|
||||
CONSTRAINT `fek_rech_adresse_id` FOREIGN KEY (`adresse_id`) REFERENCES `adresse` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fek_rech_mwst_id` FOREIGN KEY (`mwst_id`) REFERENCES `mwst` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fek_rech_partner_id` FOREIGN KEY (`partner_id`) REFERENCES `partner` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fek_rech_typ_id` FOREIGN KEY (`typ_id`) REFERENCES `rechtyp` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fek_rech_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fek_rech_wahrung_id` FOREIGN KEY (`wahrung_id`) REFERENCES `wahrung` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fek_rech_zahlziehl_id` FOREIGN KEY (`zahlziel_id`) REFERENCES `zahlziel` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_rech_buchungsKto_id` FOREIGN KEY (`buchungsKto_id`) REFERENCES `buchungsKontos` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `rechtyp` (
|
||||
`id` int(3) NOT NULL AUTO_INCREMENT,
|
||||
`typ` varchar(20) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `setting` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(11) NOT NULL,
|
||||
`opt` varchar(10) NOT NULL,
|
||||
`val` text NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_settings_user_id` (`user_id`),
|
||||
CONSTRAINT `fk_settings_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `strasse` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`str` varchar(50) NOT NULL,
|
||||
`ort_id` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_str_ort_id` (`ort_id`),
|
||||
CONSTRAINT `fk_str_ort_id` FOREIGN KEY (`ort_id`) REFERENCES `ort` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `tel` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`ort_id` int(11) NOT NULL,
|
||||
`partner_id` int(11) NOT NULL,
|
||||
`typ_id` int(3) NOT NULL,
|
||||
`nr` varchar(20) NOT NULL,
|
||||
`name` varchar(30) NOT NULL,
|
||||
`adresse_id` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_tel_ort_id` (`ort_id`),
|
||||
KEY `fk_tel_typ_id` (`typ_id`),
|
||||
KEY `fk_tel_partner_id` (`partner_id`),
|
||||
CONSTRAINT `fk_tel_ort_id` FOREIGN KEY (`ort_id`) REFERENCES `ort` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_tel_partner_id` FOREIGN KEY (`partner_id`) REFERENCES `partner` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_tel_typ_id` FOREIGN KEY (`typ_id`) REFERENCES `teltyp` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `teltyp` (
|
||||
`id` int(3) NOT NULL AUTO_INCREMENT,
|
||||
`typ` varchar(20) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `termin` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`typ` int(2) NOT NULL,
|
||||
`adresse_id` int(11) NOT NULL,
|
||||
`text` text NOT NULL,
|
||||
`changetime` datetime NOT NULL,
|
||||
`done` tinyint(1) NOT NULL,
|
||||
`user` int(11) NOT NULL,
|
||||
`changeuser` int(11) NOT NULL,
|
||||
`datetime` datetime NOT NULL,
|
||||
`termtime` datetime NOT NULL,
|
||||
`termdauer` time NOT NULL,
|
||||
`followed_by` int(11) NOT NULL,
|
||||
`act_date` datetime NOT NULL,
|
||||
`head` varchar(100) NOT NULL,
|
||||
`main_id` int(11) NOT NULL,
|
||||
`user2` int(11) NOT NULL,
|
||||
`user3` int(11) NOT NULL,
|
||||
`user4` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_termin_typ_termtyp_id` (`typ`),
|
||||
CONSTRAINT `fk_termin_typ_termtyp_id` FOREIGN KEY (`typ`) REFERENCES `termtyp` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `termtyp` (
|
||||
`id` int(2) NOT NULL AUTO_INCREMENT,
|
||||
`typ` varchar(20) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `titel` (
|
||||
`id` int(5) NOT NULL AUTO_INCREMENT,
|
||||
`titel` varchar(50) NOT NULL,
|
||||
`datetime` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `tmp_artikel` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`bezeichn` varchar(150) NOT NULL,
|
||||
`typ_id` int(5) NOT NULL,
|
||||
`einheit_id` int(11) NOT NULL,
|
||||
`preis` decimal(10,2) DEFAULT NULL,
|
||||
`datetime` datetime NOT NULL,
|
||||
`posnr` int(5) NOT NULL,
|
||||
`rabatt` int(3) NOT NULL,
|
||||
`rabatttyp` int(2) NOT NULL,
|
||||
`menge` decimal(6,3) NOT NULL,
|
||||
`angtyp` int(1) NOT NULL,
|
||||
`mwst_id` int(3) NOT NULL,
|
||||
`rech_id` int(11) NOT NULL,
|
||||
`wanr` varchar(100) NOT NULL,
|
||||
`pagebreak` int(1) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_tmp_artikel_typ_id` (`typ_id`),
|
||||
KEY `fk_tmp_art_mwst_id` (`mwst_id`),
|
||||
KEY `fk_tmp_art_rech_id` (`rech_id`),
|
||||
KEY `fk_tmp_artikel_einheit_id` (`einheit_id`),
|
||||
CONSTRAINT `fk_tmp_art_mwst_id` FOREIGN KEY (`mwst_id`) REFERENCES `mwst` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_tmp_art_rech_id` FOREIGN KEY (`rech_id`) REFERENCES `tmp_rechnung` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_tmp_artikel_einheit_id` FOREIGN KEY (`einheit_id`) REFERENCES `einheit` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_tmp_artikel_typ_id` FOREIGN KEY (`typ_id`) REFERENCES `artikeltyp` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `tmp_eigensch` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`bezeichn` varchar(100) NOT NULL,
|
||||
`wert` varchar(50) NOT NULL,
|
||||
`einheit_id` int(11) NOT NULL,
|
||||
`art_id` int(11) NOT NULL,
|
||||
`datetime` datetime NOT NULL,
|
||||
`posnr` int(5) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_tmp_eigensch_art_id` (`art_id`),
|
||||
KEY `fk_tmp_eigensch_einheit_id` (`einheit_id`),
|
||||
CONSTRAINT `fk_tmp_eigensch_art_id` FOREIGN KEY (`art_id`) REFERENCES `tmp_artikel` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_tmp_eigensch_einheit_id` FOREIGN KEY (`einheit_id`) REFERENCES `einheit` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `tmp_rechnung` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`adressfields` varchar(12) NOT NULL,
|
||||
`partner_id` int(11) NOT NULL,
|
||||
`anrede1` varchar(150) NOT NULL,
|
||||
`anrede2` varchar(150) NOT NULL,
|
||||
`mwst_id` int(3) NOT NULL,
|
||||
`user_id` int(11) NOT NULL,
|
||||
`rechnr` int(11) NOT NULL,
|
||||
`typ_id` int(2) NOT NULL,
|
||||
`zahlziel_id` int(3) NOT NULL,
|
||||
`adresse_id` int(11) NOT NULL,
|
||||
`wahrung_id` tinyint(3) NOT NULL,
|
||||
`datetime` datetime NOT NULL,
|
||||
`rabatt` int(3) NOT NULL,
|
||||
`rabattdesc` varchar(100) NOT NULL,
|
||||
`intro` text NOT NULL,
|
||||
`outro` text NOT NULL,
|
||||
`sub_mwst` int(1) NOT NULL,
|
||||
`kommission` int(11) NOT NULL,
|
||||
`lieferdatum` varchar(100) NOT NULL,
|
||||
`adresserweiterung` varchar(100) NOT NULL,
|
||||
`storno` int(1) NOT NULL DEFAULT 0,
|
||||
`buchungsKto_id` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_tmp_rech_partner_id` (`partner_id`),
|
||||
KEY `fk_tmp_rech_adresse_id` (`adresse_id`),
|
||||
KEY `fk_tmp_rech_mwst_id` (`mwst_id`),
|
||||
KEY `fk_tmp_rech_user_id` (`user_id`),
|
||||
KEY `fk_tmp_rech_zahlziehl_id` (`zahlziel_id`),
|
||||
KEY `fk_tmp_rech_typ_id` (`typ_id`),
|
||||
KEY `fk_tmp_rech_wahrung_id` (`wahrung_id`),
|
||||
KEY `fek_rech_buchungsKto_id` (`buchungsKto_id`),
|
||||
CONSTRAINT `fek_rech_buchungsKto_id` FOREIGN KEY (`buchungsKto_id`) REFERENCES `buchungsKontos` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_tmp_rech_adresse_id` FOREIGN KEY (`adresse_id`) REFERENCES `adresse` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_tmp_rech_mwst_id` FOREIGN KEY (`mwst_id`) REFERENCES `mwst` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_tmp_rech_partner_id` FOREIGN KEY (`partner_id`) REFERENCES `partner` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_tmp_rech_typ_id` FOREIGN KEY (`typ_id`) REFERENCES `rechtyp` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_tmp_rech_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_tmp_rech_wahrung_id` FOREIGN KEY (`wahrung_id`) REFERENCES `wahrung` (`id`) ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_tmp_rech_zahlziehl_id` FOREIGN KEY (`zahlziel_id`) REFERENCES `zahlziel` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `user` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`vname` varchar(50) NOT NULL,
|
||||
`nname` varchar(50) NOT NULL,
|
||||
`nick` varchar(50) NOT NULL,
|
||||
`pass` varchar(150) NOT NULL,
|
||||
`mail` varchar(50) NOT NULL,
|
||||
`salt` varchar(50) NOT NULL,
|
||||
`tel_priv` varchar(30) NOT NULL,
|
||||
`tel_gesch` varchar(30) NOT NULL,
|
||||
`tel_mobil` varchar(30) NOT NULL,
|
||||
`lastlogin` datetime NOT NULL,
|
||||
`numlogins` int(11) NOT NULL,
|
||||
`logedout` tinyint(2) NOT NULL,
|
||||
`wrongpw` tinyint(3) NOT NULL,
|
||||
`notizen` text NOT NULL,
|
||||
`blocked` tinyint(1) NOT NULL,
|
||||
`rights` varchar(6) NOT NULL,
|
||||
`weekly_hours` int(11) NOT NULL,
|
||||
`rfid` varchar(10) NOT NULL,
|
||||
`color` varchar(8) NOT NULL,
|
||||
`weekhours` decimal(6,3) NOT NULL,
|
||||
`vacationdays` int(4) NOT NULL,
|
||||
`sahours` decimal(3,1) NOT NULL,
|
||||
`timelog_start` date NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `nick` (`nick`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `wahrung` (
|
||||
`id` tinyint(3) NOT NULL AUTO_INCREMENT,
|
||||
`wahrung` varchar(20) NOT NULL,
|
||||
`kurs` decimal(8,4) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `work` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`bezeichn` varchar(150) NOT NULL,
|
||||
`bezeichn2` varchar(150) NOT NULL,
|
||||
`project_id` int(11) NOT NULL,
|
||||
`changetime` datetime NOT NULL,
|
||||
`changeuser` int(11) NOT NULL,
|
||||
`datetime` datetime NOT NULL,
|
||||
`std` decimal(6,3) NOT NULL,
|
||||
`rechn` int(11) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fek_work_partner_id` (`project_id`),
|
||||
CONSTRAINT `fek_work_partner_id` FOREIGN KEY (`project_id`) REFERENCES `project` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `zahlziel` (
|
||||
`id` int(3) NOT NULL AUTO_INCREMENT,
|
||||
`ziel` varchar(150) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE `zeiten` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`ma_id` int(11) NOT NULL,
|
||||
`kommen` datetime NOT NULL,
|
||||
`gehen` datetime NOT NULL,
|
||||
`pause_mins` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_zeiten_user_id` (`ma_id`),
|
||||
CONSTRAINT `fk_zeiten_user_id` FOREIGN KEY (`ma_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
Reference in New Issue
Block a user