66 lines
9.0 KiB
PHP
Executable File
66 lines
9.0 KiB
PHP
Executable File
<?php
|
|
$pdo=new PDO("pgsql:host=localhost;dbname=adx_system","admin","admin123");
|
|
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
|
|
$tables=$pdo->query("SELECT tablename FROM pg_tables WHERE schemaname='public' ORDER BY tablename")->fetchAll(PDO::FETCH_COLUMN);
|
|
$current=$_GET['table']??'';
|
|
$msg='';$error='';$sqlresult=null;
|
|
if($_POST){
|
|
$act=$_POST['action']??'';
|
|
try{
|
|
if($act=='sql'&&trim($_POST['sql'])){$sqlresult=$pdo->query($_POST['sql'])->fetchAll(PDO::FETCH_ASSOC);$msg='Query executed: '.count($sqlresult).' rows';}
|
|
if($act=='insert'&&$current){$cols=[];$vals=[];$params=[];foreach($_POST['col'] as $k=>$v){if($v!==''){$cols[]="\"$k\"";$vals[]='?';$params[]=$v;}}if($cols){$pdo->prepare("INSERT INTO \"$current\" (".implode(',',$cols).") VALUES (".implode(',',$vals).")")->execute($params);$msg='Row inserted!';}}
|
|
if($act=='delete'&&$current){$pdo->prepare("DELETE FROM \"$current\" WHERE id=?")->execute([$_POST['id']]);$msg='Row deleted!';}
|
|
if($act=='truncate'&&$current){$pdo->exec("TRUNCATE TABLE \"$current\" RESTART IDENTITY");$msg='Table truncated!';}
|
|
}catch(Exception $e){$error=$e->getMessage();}
|
|
}
|
|
$data=[];$cols=[];$total=0;
|
|
if($current){
|
|
$cols=$pdo->query("SELECT column_name,data_type,is_nullable FROM information_schema.columns WHERE table_name='$current' ORDER BY ordinal_position")->fetchAll(PDO::FETCH_ASSOC);
|
|
$total=$pdo->query("SELECT COUNT(*) FROM \"$current\"")->fetchColumn();
|
|
$page=max(1,intval($_GET['page']??1));$limit=50;$offset=($page-1)*$limit;
|
|
$data=$pdo->query("SELECT * FROM \"$current\" ORDER BY 1 DESC LIMIT $limit OFFSET $offset")->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
$tblstats=[];foreach($tables as $t){try{$tblstats[$t]=$pdo->query("SELECT COUNT(*) FROM \"$t\"")->fetchColumn();}catch(Exception $e){$tblstats[$t]=0;}}
|
|
?><!DOCTYPE html><html><head><meta charset="UTF-8"><title>Database Manager</title>
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
|
<style>*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui;background:#0f172a;color:#e2e8f0;min-height:100vh}.header{background:linear-gradient(135deg,#0891b2,#06b6d4);padding:20px;color:#fff}.layout{display:grid;grid-template-columns:240px 1fr;min-height:calc(100vh - 80px)}.sidebar{background:#1e293b;padding:15px;overflow-y:auto;border-right:1px solid #334155}.sidebar h4{font-size:11px;color:#64748b;text-transform:uppercase;margin-bottom:10px}.tbl-item{display:flex;justify-content:space-between;align-items:center;padding:10px 12px;border-radius:6px;color:#94a3b8;text-decoration:none;font-size:13px;margin-bottom:4px}.tbl-item:hover{background:rgba(255,255,255,.05);color:#fff}.tbl-item.active{background:rgba(6,182,212,.2);color:#06b6d4}.tbl-count{font-size:11px;background:rgba(255,255,255,.1);padding:2px 8px;border-radius:10px}.main{padding:20px;overflow-x:auto}.card{background:#1e293b;border:1px solid #334155;border-radius:12px;margin-bottom:20px}.card-header{padding:15px 20px;border-bottom:1px solid #334155;display:flex;justify-content:space-between;align-items:center}.card-body{padding:20px}.sql-box{width:100%;background:#0f172a;border:1px solid #334155;border-radius:8px;padding:15px;color:#06b6d4;font-family:monospace;font-size:13px;min-height:80px;resize:vertical}.btn{padding:10px 16px;border:none;border-radius:8px;cursor:pointer;font-weight:600;font-size:13px}.btn-primary{background:#06b6d4;color:#fff}.btn-success{background:#10b981;color:#fff}.btn-danger{background:#ef4444;color:#fff}.btn-secondary{background:#334155;color:#94a3b8}.btn-sm{padding:6px 10px}table{width:100%;border-collapse:collapse;font-size:13px}th{background:#0f172a;padding:12px;text-align:left;color:#64748b;font-size:11px;text-transform:uppercase;position:sticky;top:0}td{padding:10px 12px;border-bottom:1px solid #334155;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}tr:hover{background:rgba(6,182,212,.05)}.alert{padding:12px;border-radius:8px;margin-bottom:15px}.alert-success{background:rgba(16,185,129,.2);color:#10b981;border:1px solid #10b981}.alert-error{background:rgba(239,68,68,.2);color:#ef4444;border:1px solid #ef4444}.form-row{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:10px}.form-row input{background:#0f172a;border:1px solid #334155;border-radius:6px;padding:8px;color:#fff;font-size:12px}.form-row label{font-size:10px;color:#64748b;display:block;margin-bottom:4px}.col-type{font-size:9px;color:#64748b}.pages{display:flex;gap:8px;justify-content:center;margin-top:15px}.pages a,.pages span{padding:8px 12px;border-radius:6px;background:#334155;color:#94a3b8;text-decoration:none;font-size:13px}.pages a:hover{background:#475569;color:#fff}.pages .active{background:#06b6d4;color:#fff}.result-table{max-height:300px;overflow:auto;margin-top:15px}</style>
|
|
</head>
|
|
<body><div class="header"><h1><i class="fas fa-database"></i> Database Manager</h1><p style="opacity:.8">PostgreSQL: adx_system • <?=count($tables)?> tables</p></div>
|
|
<div class="layout">
|
|
<div class="sidebar"><h4>Tables</h4>
|
|
<?php foreach($tables as $t):?><a href="?table=<?=$t?>" class="tbl-item <?=$t==$current?'active':''?>"><span><i class="fas fa-table" style="margin-right:8px;opacity:.5"></i><?=$t?></span><span class="tbl-count"><?=number_format($tblstats[$t])?></span></a><?php endforeach;?>
|
|
<?php if(empty($tables)):?><p style="color:#64748b;padding:20px;text-align:center">No tables</p><?php endif;?>
|
|
</div>
|
|
<div class="main">
|
|
<?php if($msg):?><div class="alert alert-success"><i class="fas fa-check"></i> <?=$msg?></div><?php endif;?>
|
|
<?php if($error):?><div class="alert alert-error"><i class="fas fa-times"></i> <?=$error?></div><?php endif;?>
|
|
|
|
<div class="card"><div class="card-header"><h3><i class="fas fa-terminal" style="color:#06b6d4"></i> SQL Query</h3></div><div class="card-body">
|
|
<form method="POST"><input type="hidden" name="action" value="sql">
|
|
<textarea name="sql" class="sql-box" placeholder="SELECT * FROM table_name LIMIT 100;"><?=$_POST['sql']??($current?"SELECT * FROM \"$current\" LIMIT 100":'')?></textarea>
|
|
<div style="margin-top:10px"><button class="btn btn-primary"><i class="fas fa-play"></i> Execute</button></div>
|
|
</form>
|
|
<?php if($sqlresult!==null):?><div class="result-table"><table><tr><?php if($sqlresult):foreach(array_keys($sqlresult[0]) as $c):?><th><?=$c?></th><?php endforeach;endif;?></tr>
|
|
<?php foreach($sqlresult as $row):?><tr><?php foreach($row as $v):?><td><?=htmlspecialchars(substr($v??'NULL',0,50))?></td><?php endforeach;?></tr><?php endforeach;?>
|
|
<?php if(empty($sqlresult)):?><tr><td style="text-align:center;padding:20px;color:#64748b">No results</td></tr><?php endif;?></table></div><?php endif;?>
|
|
</div></div>
|
|
|
|
<?php if($current):?>
|
|
<div class="card"><div class="card-header"><h3><i class="fas fa-plus" style="color:#10b981"></i> Insert Row</h3></div><div class="card-body">
|
|
<form method="POST"><input type="hidden" name="action" value="insert">
|
|
<div class="form-row"><?php foreach($cols as $c):?><div><label><?=$c['column_name']?> <span class="col-type"><?=$c['data_type']?></span></label><input name="col[<?=$c['column_name']?>]" placeholder="<?=$c['is_nullable']=='YES'?'nullable':'required'?>"></div><?php endforeach;?></div>
|
|
<button class="btn btn-success"><i class="fas fa-plus"></i> Insert</button>
|
|
</form></div></div>
|
|
|
|
<div class="card"><div class="card-header"><h3><i class="fas fa-table" style="color:#06b6d4"></i> <?=$current?> <span style="color:#64748b;font-weight:normal">(<?=number_format($total)?> rows)</span></h3>
|
|
<form method="POST" onsubmit="return confirm('TRUNCATE all data?')"><input type="hidden" name="action" value="truncate"><button class="btn btn-danger btn-sm"><i class="fas fa-trash"></i> Truncate</button></form></div>
|
|
<div style="overflow-x:auto"><table><tr><th>Actions</th><?php foreach($cols as $c):?><th><?=$c['column_name']?><br><span class="col-type"><?=$c['data_type']?></span></th><?php endforeach;?></tr>
|
|
<?php foreach($data as $row):?><tr><td><form method="POST" style="display:inline" onsubmit="return confirm('Delete?')"><input type="hidden" name="action" value="delete"><input type="hidden" name="id" value="<?=$row['id']??$row[array_key_first($row)]?>"><button class="btn btn-danger btn-sm"><i class="fas fa-trash"></i></button></form></td><?php foreach($row as $v):?><td title="<?=htmlspecialchars($v??'')?>"><?=htmlspecialchars(substr($v??'NULL',0,50))?></td><?php endforeach;?></tr><?php endforeach;?>
|
|
<?php if(empty($data)):?><tr><td colspan="<?=count($cols)+1?>" style="text-align:center;padding:40px;color:#64748b">No data</td></tr><?php endif;?></table></div>
|
|
<?php $pages=ceil($total/$limit);if($pages>1):?><div class="pages"><?php for($i=1;$i<=$pages&&$i<=10;$i++):?><a href="?table=<?=$current?>&page=<?=$i?>" class="<?=$i==$page?'active':''?>"><?=$i?></a><?php endfor;?></div><?php endif;?>
|
|
</div>
|
|
<?php else:?><div class="card"><div class="card-body" style="text-align:center;padding:60px;color:#64748b"><i class="fas fa-database" style="font-size:48px;opacity:.3;margin-bottom:15px;display:block"></i><p>Select a table from the sidebar</p></div></div><?php endif;?>
|
|
</div></div><?php include("includes/chatbot-widget.php"); ?>
|
|
|
|
</body></html>
|