Compare commits
No commits in common. "900dbe3b6c29c631051b62bf5f980527040a52de" and "1af61143220587efa19b24a925a4670effaa74bf" have entirely different histories.
900dbe3b6c
...
1af6114322
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,5 +1,4 @@
|
||||
vendor/
|
||||
composer.json
|
||||
composer.lock
|
||||
composer.sync
|
||||
|
||||
@ -9,5 +8,3 @@ composer.sync
|
||||
|
||||
test_code.php
|
||||
modules/
|
||||
|
||||
requirements.txt
|
||||
|
||||
@ -3,9 +3,7 @@ cd "$(dirname ${BASH_SOURCE[0]})"
|
||||
while [[ 1 ]]
|
||||
do
|
||||
killall DbContinuousIntegrationWrapper.sh
|
||||
/usr/bin/php composer.json.php > composer.json
|
||||
touch -t $(/usr/bin/mysql -se "SELECT DATE_FORMAT(LastUpdated, '%Y%m%d%H%i.%s') FROM SYS_PRD_BND.Composer ORDER BY LastUpdated DESC LIMIT 1") composer.json
|
||||
make
|
||||
/usr/bin/php DbContinuousIntegration.php
|
||||
make
|
||||
sleep 10
|
||||
done
|
||||
|
||||
4
Makefile
4
Makefile
@ -1,10 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
composer.sync: composer.json
|
||||
COMPOSER_ALLOW_SUPERUSER=1 composer update > $@ 2>&1
|
||||
COMPOSER_ALLOW_SUPERUSER=1 composer update 2>&1 > $@
|
||||
|
||||
requirements.sync: requirements.txt
|
||||
pip install -r requirements.txt $@
|
||||
install:
|
||||
echo "Add this line to crontab -e"
|
||||
echo '@reboot /bin/bash /root/DbContinuousIntegration/DbContinuousIntegrationWrapper.sh 2> /dev/null > /dev/null &'
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
{
|
||||
"require": {
|
||||
"psr/log": "*",
|
||||
"symfony/console": "*"
|
||||
"denpa\/php-bitcoinrpc": "^2.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
// Setup PDO
|
||||
$dsn = "mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=SYS_PRD_BND;charset=utf8mb4";
|
||||
$options = [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
];
|
||||
|
||||
try {
|
||||
$pdo = new PDO($dsn, "root", "", $options);
|
||||
|
||||
// Fetch dependencies
|
||||
$stmt = $pdo->query("SELECT VendorName, PackageName, VersionOrBranch FROM Composer ORDER BY VendorName, PackageName");
|
||||
$require = [];
|
||||
foreach ($stmt as $row) {
|
||||
$require["{$row['VendorName']}/{$row['PackageName']}"] = $row['VersionOrBranch'];
|
||||
}
|
||||
|
||||
// Fetch repositories
|
||||
$stmt = $pdo->query("SELECT RepositoryType, RepositoryUrl FROM Composer WHERE RepositoryUrl IS NOT NULL ORDER BY VendorName, PackageName");
|
||||
$repositories = [];
|
||||
foreach ($stmt as $row) {
|
||||
$repositories[] = [
|
||||
'type' => $row['RepositoryType'],
|
||||
'url' => $row['RepositoryUrl'],
|
||||
];
|
||||
}
|
||||
|
||||
// Build composer.json content
|
||||
$composerJson = [
|
||||
'require' => $require,
|
||||
];
|
||||
if (!empty($repositories)) {
|
||||
$composerJson['repositories'] = $repositories;
|
||||
}
|
||||
|
||||
// Write to file
|
||||
file_put_contents('php://stdout', json_encode($composerJson, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
||||
file_put_contents("php://stderr", "✅ composer.json generated successfully.\n");
|
||||
|
||||
} catch (PDOException $e) {
|
||||
file_put_contents("php://stderr","❌ Database error: " . $e->getMessage() . "\n");
|
||||
}
|
||||
@ -9,9 +9,6 @@
|
||||
* @return string The complete PHP code ready for sandbox execution.
|
||||
*/
|
||||
function generatePHPTriggerCode($functionName, $onUpdate_phpCode, $row) {
|
||||
// Fix code if redundant opening PHP tag
|
||||
if (substr($onUpdate_phpCode,0,5) == "<"."?"."php") $onUpdate_phpCode = substr($onUpdate_phpCode,5);
|
||||
|
||||
// Prepare the constants definition from the database
|
||||
$constants = getConstantsDefinition();
|
||||
|
||||
|
||||
@ -14,13 +14,10 @@ function handleTriggerExecutionResult($result, $stdout, $stderr, $originalRow, $
|
||||
if ($result !== 0) {
|
||||
// Update table error status and notify via Telegram if execution failed
|
||||
updateTriggerError($tableName, $stderr);
|
||||
} else {
|
||||
} else {
|
||||
// Decode the output from JSON to array
|
||||
$newRowValue = json_decode($stdout, true);
|
||||
|
||||
// Ignore the hydrate columns
|
||||
$newRowValue = array_filter($newRowValue, fn($k) => !str_ends_with($k, '_ref'), ARRAY_FILTER_USE_KEY);
|
||||
|
||||
if ($newRowValue === null) {
|
||||
updateTriggerError($tableName, 'Invalid JSON output from sandboxed execution.');
|
||||
return;
|
||||
|
||||
@ -85,7 +85,7 @@ function processActiveTable($activeTable) {
|
||||
|
||||
ensureLastUpdatedColumnExists($Name);
|
||||
|
||||
$rowsToProcess = sql_read_and_hydrate("SELECT * FROM $Name WHERE LastUpdated > '$LastUpdated'");
|
||||
$rowsToProcess = sql("SELECT * FROM $Name WHERE LastUpdated > '$LastUpdated'");
|
||||
|
||||
foreach ($rowsToProcess as $unprocessedRow) {
|
||||
processTableRow($activeTable, $unprocessedRow);
|
||||
@ -166,7 +166,7 @@ function updateDatabaseRow($tableName, $originalRow, $newRowValue) {
|
||||
|
||||
$setStatements = [];
|
||||
foreach ($newRowValue as $k => $v) {
|
||||
$value = is_numeric($v) ? $v : "'" . str_replace("'", "''", is_string($v)?$v:json_encode($v)) . "'";
|
||||
$value = is_numeric($v) ? $v : "'" . str_replace("'", "''", $v) . "'";
|
||||
$setStatements[] = "$k = $value";
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,6 @@
|
||||
function runSandboxedPython($code, &$stdout = null, &$stderr = null) {
|
||||
// Create a temporary file to hold the Python code
|
||||
$tempFile = tempnam(sys_get_temp_dir(), 'sandboxed_') . '.py';
|
||||
echo "Creating ".redText("python temp code file")." for sandboxed execution at: $tempFile \n";
|
||||
|
||||
// Write the generated Python code to the temporary file
|
||||
file_put_contents($tempFile, $code);
|
||||
|
||||
66
sys.php
66
sys.php
@ -66,69 +66,3 @@ function getTblPrimaryKeyColName($tblName) {
|
||||
return $cols;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a SELECT query and hydrates any foreign key columns with the
|
||||
* referenced row data.
|
||||
*
|
||||
* The query should target a single table (e.g., "SELECT * FROM db.table WHERE …").
|
||||
* For each foreign key in that table, an additional key named
|
||||
* `<column>_ref` is added to each returned row containing the referenced row
|
||||
* from the foreign table.
|
||||
*
|
||||
* @param string $query SQL SELECT statement for a single table.
|
||||
* @return array Result set with hydrated foreign key data.
|
||||
*/
|
||||
function sql_read_and_hydrate($query) {
|
||||
$rows = sql_read($query);
|
||||
if (empty($rows)) {
|
||||
return $rows;
|
||||
}
|
||||
|
||||
if (!preg_match('/FROM\s+([`\w\.]+)/i', $query, $m)) {
|
||||
return $rows; // Unable to determine table
|
||||
}
|
||||
|
||||
$table = str_replace('`', '', $m[1]);
|
||||
if (strpos($table, '.') !== false) {
|
||||
list($dbName, $tblName) = explode('.', $table, 2);
|
||||
} else {
|
||||
$dbName = DB_NAME;
|
||||
$tblName = $table;
|
||||
}
|
||||
|
||||
$fks = sql_read(
|
||||
"SELECT COLUMN_NAME, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, " .
|
||||
"REFERENCED_COLUMN_NAME FROM information_schema.KEY_COLUMN_USAGE " .
|
||||
"WHERE TABLE_SCHEMA = '$dbName' AND TABLE_NAME = '$tblName' " .
|
||||
"AND REFERENCED_TABLE_NAME IS NOT NULL"
|
||||
);
|
||||
|
||||
if (empty($fks)) {
|
||||
return $rows; // no foreign keys
|
||||
}
|
||||
|
||||
foreach ($rows as &$row) {
|
||||
foreach ($fks as $fk) {
|
||||
$col = $fk['COLUMN_NAME'];
|
||||
if (!isset($row[$col])) continue;
|
||||
|
||||
$val = $row[$col];
|
||||
if ($val === null) {
|
||||
$row[$col . '_ref'] = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
$refTable = $fk['REFERENCED_TABLE_SCHEMA'] . '.' . $fk['REFERENCED_TABLE_NAME'];
|
||||
$refCol = $fk['REFERENCED_COLUMN_NAME'];
|
||||
$condition = is_numeric($val)
|
||||
? "$refCol = $val"
|
||||
: "$refCol = '" . str_replace("'", "''", $val) . "'";
|
||||
$refRow = sql_read("SELECT * FROM $refTable WHERE $condition LIMIT 1");
|
||||
$row[$col . '_ref'] = $refRow[0] ?? null;
|
||||
}
|
||||
}
|
||||
unset($row);
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user