/
live-server-data.php
executable file
·207 lines (174 loc) · 7.85 KB
/
live-server-data.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
<?php
/* author: vsercu@intec.ugent.be
*
*****
* This page serves as an adapter between the VIVI JS frontend and a MySQL or PostGres DB.
* It executes queries as the user passed in parameter, without any checking, just as if you were working on the DB locally.
* And returns the data in JSON format.
apt-get install php5-pgsql
+ apache restart (duh)
*
* if things go ERR 500 internal server error, check /var/log/apache2/error.log
*/
// get the parameters
error_reporting(E_ERROR);
header('Access-Control-Allow-Origin: *');
header('Content-type: application/json');
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
try {
if (!isset($_GET['callback'])) {
//throw new Exception("Callback is not set.");
}
$callback = $_GET['callback'];
if (!preg_match('/^[a-zA-Z0-9_]+$/', $callback)) {
//throw new Exception("Invalid callback name: '" . $callback . "'");
}
if (! isset($_POST['dbinfo'])){
throw new Exception("No database information given.");
}
$dbinfo = json_decode($_POST['dbinfo'], true);
$DBTYPE = 'POSTGRES';
if (array_key_exists('dbtype', $dbinfo)){
$DBTYPE = $dbinfo['dbtype'];
}
if (! array_key_exists('username', $dbinfo)){
throw new Exception("No username in 'dbinfo'-parameter.");
}
if (! array_key_exists('password', $dbinfo)){
throw new Exception("No password in 'dbinfo'-parameter.");
}
if (! array_key_exists('dbhost', $dbinfo)){
throw new Exception("No database hostname in 'dbinfo'-parameter.");
}
if (! array_key_exists('dbname', $dbinfo)){
throw new Exception("No database name in 'dbinfo'-parameter.");
}
// connect to DB
$sqls = json_decode($_POST['sqls'], true);
$usr = $dbinfo['username'];
$pass = $dbinfo['password'];
$dbip = $dbinfo['dbhost'];
$dbname = $dbinfo['dbname'];
$response = "";
// +++++++++++++++++++++++++++++++++++++++++ MYSQL HANDLER ++++++++++++++++++++++++++++++++++++++++++++++++++
if (strtoupper($DBTYPE) == 'MYSQL'){
// DB connectings
//Set mysql connection timeout to a few seconds.
ini_set('mysql.connect_timeout', 3);
$con = mysql_connect($dbip, $usr, $pass);
if (!$con) {
throw new Exception('Could not connect to MySQL database: <br/>' . mysql_error());
}
mysql_select_db($dbname, $con);
if (mysql_error()){
throw new Exception('When selecting MySQL database: <br/>' . mysql_error());
}
$response = array();
foreach ($sqls as $name => $sql) {
// for every sequel in the hash
$sql = trim($sql);
if (! preg_match("/.*LIMIT\s+\d+\s*;?$/i", $sql)){
//throw new Exception("No trailing LIMIT-clause found for serie '$name'...<br/>SQL: '$sql'<br/>Example: add 'LIMIT 1000' at the end...");
}
$sql = preg_replace('/\s*?--\s*?.*/', '', $sql); // remove comments
//$sql = str_replace(array("\n", "\t"), ' ', $sql); // remove newlines en tabs
$queries = split_sql($sql);
$nested = 0;
foreach ($queries as $query){
if (strlen(trim($query)) > 0){
$escaped_query = $query; //mysql_real_escape_string ( $query, $con );
$result = mysql_query($escaped_query);
$nested_suffix = ($nested == 0 ? "" : "_" . $nested);
if (mysql_error()){
throw new Exception("When executing (MySQL) SQL for serie '" . $name . $nested_suffix . "':<br/><span class='erroneous-sql'>$escaped_query</span> caused an SQL-error: <br/>" . mysql_error());
}
$resultset = array();
while ($row = mysql_fetch_row($result)) {
array_push($resultset, array(
$row[0],
$row[1]
));
}
if (count($resultset) != 0){
$response[$name . $nested_suffix] = $resultset;
}
}
}
}//foreach sqls
mysql_close($con);
// +++++++++++++++++++++++++++++++++++++++++ PG HANDLER ++++++++++++++++++++++++++++++++++++++++++++++++++
} else if (strtoupper($DBTYPE) == 'POSTGRES'){
set_error_handler("exception_error_handler");
$con = pg_connect("host=$dbip dbname=$dbname user=$usr password=$pass connect_timeout=3");
if (pg_last_error()){
throw new Exception('When trying to connect to POSTGRES database: <br/>' . pg_last_error());
}
$response = array();
foreach ($sqls as $name => $sql) {
// for every sequel in the hash
$sql = trim($sql);
if (! preg_match("/.*LIMIT\s+\d+\s*;?$/i", $sql)){
//throw new Exception("No trailing LIMIT-clause found for serie '$name'...<br/>SQL: '$sql'<br/>Example: add 'LIMIT 1000' at the end...");
}
$sql = preg_replace('/\s*?--\s*?.*/', '', $sql); // remove comments
$sql = str_replace(array("\n", "\t"), '', $sql); // remove newlines en tabs
$queries = split_sql($sql);
$nested = 0;
foreach ($queries as $query){
if (strlen(trim($query)) > 0){
$escaped_query = $query; //pg_escape_string($con, $query);
$result = pg_query($con, $query);
$nested_suffix = ($nested == 0 ? "" : "_" . $nested);
if (pg_last_error()){
throw new Exception('When executing POSTGRES query: <br/>' . pg_last_error() . '<br/><br/>Make sure you doublequote your tablename, and check case sensitivity.');
}
$resultset = array();
while ($row = pg_fetch_row($result)) {
array_push($resultset, array(
$row[0],
$row[1]
));
}
if (count($resultset) != 0){
$response[$name . $nested_suffix] = $resultset;
}
}
}
}// end foreach
pg_close($con);
} else {
throw new Exception("No database type $DBTYPE unkown. Use MYSQL or POSTGRES.");
}
echo $callback . "(" . json_encode(array(
'data' => $response,
'msg' => ''
), JSON_NUMERIC_CHECK) . ");";
} catch (Exception $e) {
$arr = array('data' => "", 'msg' => str_replace("\n", "<br/>", $e->getMessage()));
echo $callback . "(" . json_encode( $arr ) . ")";
}
function split_sql($sql_text) {
// Return array of ; terminated SQL statements in $sql_text.
$re = '% # Match an SQL record ending with ";"
\s* # Discard leading whitespace.
( # $1: Trimmed non-empty SQL record.
(?: # Group for content alternatives.
\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' # Either a single quoted string,
| "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" # or a double quoted string,
| /*[^*]*\*+([^*/][^*]*\*+)*/ # or a multi-line comment,
| \#.* # or a # single line comment,
| --.* # or a -- single line comment,
| [^"\';#] # or one non-["\';#-]
)+ # One or more content alternatives
(?:;|$) # Record end is a ; or string end.
) # End $1: Trimmed SQL record.
%x';
$matches = array();
if (preg_match_all($re, $sql_text, $matches)) {
return $matches[1];
}
return array();
}
?>