commit d9b752dc9e927aa74abb54f61aecc0f7244852a4 Author: sheychen Date: Tue Feb 27 19:03:23 2018 +0100 Initial-Final Commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..e15bbcd --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# DB-Xplorer + +### A minimal, unsafe and maybe usefull sql database explorer + +Please don't use that *really* \ No newline at end of file diff --git a/config.php b/config.php new file mode 100644 index 0000000..cb254e3 --- /dev/null +++ b/config.php @@ -0,0 +1,4 @@ + 10, + 'display_length' => 50 +); \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000..5d95daa --- /dev/null +++ b/index.php @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/model.php b/model.php new file mode 100644 index 0000000..b53c5d2 --- /dev/null +++ b/model.php @@ -0,0 +1,150 @@ + PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC + )); + } catch (PDOException $e) { + $_error = $e->getMessage(); + $_page = 'fail'; + } +}else{ + if($_page != 'disconnect') + $_page = 'connect'; +} + +function getQuery($query){ + global $db; + return $db->query($query)->fetchall(); +} + +function getPrepareQuery($query, $args){ + global $db; + $sth = $db->prepare($query); + $sth->execute($args); + return $sth->fetchAll(); +} + +function getSchemasList(){ + $schemas = array(); + foreach (getQuery('SELECT schema_name FROM information_schema.schemata') as $schema) { + $schemas[] = $schema['schema_name']; + } + return $schemas; +} + +function getTablesList(){ + global $db; + return $db->query("SELECT table_schema, table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema NOT IN ('pg_catalog', 'information_schema')")->fetchall(); +} + +function getTablesListBySchema($schema){ + $tables = array(); + foreach (getPrepareQuery("SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema = ?", array($schema)) as $table) { + $tables[] = $table['table_name']; + } + return $tables; +} + +function getTableColumnsList($schema, $table){ + return getPrepareQuery("SELECT column_name, column_default, is_nullable, data_type, character_maximum_length, numeric_precision, numeric_scale, datetime_precision FROM information_schema.columns WHERE table_schema = ? AND table_name = ? ORDER BY ordinal_position", array($schema, $table)); +} + +function getTableColumnsNames($schema, $table){ + $columns = array(); + foreach (getPrepareQuery("SELECT column_name FROM information_schema.columns WHERE table_schema = ? AND table_name = ? ORDER BY ordinal_position", array($schema, $table)) as $column) { + $columns[] = $column['column_name']; + } + return $columns; +} + +function getTableContentList($schema, $table, $offset = 0){ + global $config; + //Note: check schema and table before !!! + return getPrepareQuery("SELECT * FROM \"$schema\".\"$table\" LIMIT ".$config["limit_size"]." OFFSET ?", array($offset)); +} + +function getTableCount($schema, $table){ + //Note: check schema and table before !!! + return getQuery("SELECT COUNT(*) count FROM \"$schema\".\"$table\"")[0]["count"]; +} + +function insertTableLine($schema, $table, $data){ + //REALLY UNSAFE + //Note: check schema and table before !!! + global $db; + $sql = "INSERT INTO \"$schema\".\"$table\"("; + $first = key($data); + foreach ($data as $key => $value) { + if($key !== $first) $sql .= ", "; + $sql .= "\"$key\""; + } + $sql .= ") VALUES ("; + foreach ($data as $key => $value) { + if($key !== $first) $sql .= ", "; + $sql .= $db->quote($value); + } + $sql .= ")"; + return getQuery($sql); +} + +//render +function printAssocTable($data, $fn){ + $str = ''; + $str .= ''; + foreach($data as $row){ + $str .= ''.($fn != null ? fn($row) : '').''; + } + return $str.'
'.implode('', array_keys($data[0])).'
'.implode('', $row).'
'; +} + +function checkSchema($schema){ + if($schema == null) + return '

Any schema selected

'; + + if(!in_array($schema, getSchemasList())) + return '

Unknown schema

'; + + return true; +} + +function checkTable($schema, $table){ + $check_schema = checkSchema($schema); + if($check_schema !== true) + return $check_schema; + + if ($table == null) + return '

Any base selected

'; + + if (!in_array($table, getTablesListBySchema($schema))) + return '

Unknown base

'; + + return true; +} + +function printCheck($check){ + if($check !== true) + echo $check; + + return $check === true; +} + + +function endsWith($haystack, $needle) +{ + $length = strlen($needle); + + return $length === 0 || + (substr($haystack, -$length) === $needle); +} \ No newline at end of file diff --git a/pages/connect.php b/pages/connect.php new file mode 100644 index 0000000..7a5ad13 --- /dev/null +++ b/pages/connect.php @@ -0,0 +1,31 @@ + +

Connect

+
+

+ + +

+

+ + +

+

+ + +

+

+ + +

+

+ +

+
\ No newline at end of file diff --git a/pages/disconnect.php b/pages/disconnect.php new file mode 100644 index 0000000..8e21d51 --- /dev/null +++ b/pages/disconnect.php @@ -0,0 +1,5 @@ + +

Disconnected

\ No newline at end of file diff --git a/pages/fail.php b/pages/fail.php new file mode 100644 index 0000000..a61777c --- /dev/null +++ b/pages/fail.php @@ -0,0 +1,2 @@ +

Connection failed:

+

Try reconnect

\ No newline at end of file diff --git a/pages/schema.php b/pages/schema.php new file mode 100644 index 0000000..cd4d3d6 --- /dev/null +++ b/pages/schema.php @@ -0,0 +1,10 @@ +

Schema

+ +

+ + + + + +
Table
+ \ No newline at end of file diff --git a/pages/schemas.php b/pages/schemas.php new file mode 100644 index 0000000..187ade8 --- /dev/null +++ b/pages/schemas.php @@ -0,0 +1,7 @@ +

Schemas

+ + + + + +
Schema
\ No newline at end of file diff --git a/pages/sql.php b/pages/sql.php new file mode 100644 index 0000000..ad83f3d --- /dev/null +++ b/pages/sql.php @@ -0,0 +1,13 @@ +

SQL

+".$e->getMessage()."

"; + } ?> + +
+

+

+
+ \ No newline at end of file diff --git a/pages/table.php b/pages/table.php new file mode 100644 index 0000000..3541efd --- /dev/null +++ b/pages/table.php @@ -0,0 +1,19 @@ +

Table

+ +

:

+ + + + + + + + + + +
ColumnTypeNullableDefault
+ + \ No newline at end of file diff --git a/pages/table_display.php b/pages/table_display.php new file mode 100644 index 0000000..2555040 --- /dev/null +++ b/pages/table_display.php @@ -0,0 +1,35 @@ +

Table Display

+ $pageCount): ?> +

Offset out of range

+ +

:

+
+

0): ?> + < + + > + +

+
+ + + + + + + + + */ ?> + + +
', array_keys($content[0])) ?>
NULL" : substr($value, 0, $config["display_length"]).(strlen($value) > $config["display_length"] ? '...' : '') ?>
+ + \ No newline at end of file diff --git a/pages/table_insert.php b/pages/table_insert.php new file mode 100644 index 0000000..bdf927a --- /dev/null +++ b/pages/table_insert.php @@ -0,0 +1,38 @@ +

Table Insert

+ +

:

+ $value) { + if(!endsWith($key, "-null")){ + if(!in_array($key, $columns)) + throw new Exception("Wrong column name : ".htmlspecialchars($key)); + + if(!isset($_POST[$key.'-null'])) + $data[$key] = $value; + } + } + insertTableLine($_schema, $_table, $data); + echo "

Insertion complete

"; + }catch(Exception $e){ + echo "

".$e->getMessage()."

"; + } ?> + +
+ +

+ + +
NULL +

+ + +
+ + + \ No newline at end of file diff --git a/pages/tables.php b/pages/tables.php new file mode 100644 index 0000000..7c04e53 --- /dev/null +++ b/pages/tables.php @@ -0,0 +1,10 @@ +

Tables

+ + + + + + + + +
SchemaTable
\ No newline at end of file diff --git a/router.php b/router.php new file mode 100644 index 0000000..bf6b319 --- /dev/null +++ b/router.php @@ -0,0 +1,35 @@ + + + + + + + + DB Xplorer - <?= $_page ?> + +
+
+

🚪

+

DB Xplorer

+
+ +
+ A minimal, unsafe and maybe usefull sql database explorer

"; + ?> +
+ +
+ \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..f8e7211 --- /dev/null +++ b/style.css @@ -0,0 +1,99 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +a { + color: black; + text-decoration: none; +} + +.error { + color: red; + font-weight: bold; +} + +.null-val { + font-style: italic; +} + +html, +body { + height: 100%; + text-align: center; +} + +#content { + display: flex; + flex-flow: column; + height: 100%; +} + +header, footer, nav { + background: #333; + padding: 10px; + color: white; +} +header a, footer a, nav a { + color: white; +} + +header .logout { + float: right; + text-align: right; +} + +nav { + border-top: 2px solid #555; +} +nav ul, section .nav { + display: flex; + justify-content: space-around; + padding: 0 10%; + list-style: none; +} + +section { + flex: 1; + margin: 20px; + height: 100%; + display: flex; + flex-direction: column; +} +section a { + text-decoration: underline; + text-decoration-style: dotted; +} +section p { + margin: 5px; +} +section a:hover { + text-decoration-style: dashed; +} +section table{ + margin: 20px auto; + border-collapse: collapse; +} +section td, section th { + border: 1px solid black; + padding: 2px 5px; +} +section label { + display: inline-block; + min-width: 10%; + text-align: right; + padding: 2px; +} +section [type="submit"] { + padding: 2px 10px; +} +section .nav{ + flex: 1; + display: flex; + flex-direction: column; +} +section .nav:before{ + content: ""; + flex: 1; +} \ No newline at end of file