IMPROVEMENT: new use-cases for InputArgs_json

This commit is contained in:
root 2025-12-04 09:20:05 +00:00
parent f4038ff3b1
commit 9663a1360d
3 changed files with 162 additions and 10 deletions

View File

@ -4,7 +4,7 @@ require_once __DIR__."/.env.php";
require __DIR__."/app.php"; require __DIR__."/app.php";
require __DIR__."/plt/index.php"; require __DIR__."/plt/index.php";
require __DIR__."/sys.php"; require __DIR__."/sys/sys.php";
main(); main();

View File

@ -0,0 +1,79 @@
function getSupportFunctionsDefinition() {
// EXAMPLE of InputArgs_json
// {
// "simpleArg": "string",
// "argWithDefault": {
// "type": "int",
// "default": 10
// },
// "argByReference": {
// "type": "array",
// "reference": true
// },
// "optionalComplex": {
// "type": "?string",
// "default": null
// }
// }
$supportFunctions = "";
foreach (sql("SELECT Name, InputArgs_json, PhpCode FROM SYS_PRD_BND.SupportFunctions WHERE PhpCode IS NOT NULL") as $f) {
$inputArgs = json_decode($f["InputArgs_json"], true);
$compiledArgs = [];
if (is_array($inputArgs)) {
foreach ($inputArgs as $name => $config) {
$parts = [
'type' => '',
'ref' => '',
'name' => '$' . $name,
'default' => ''
];
// Case A: Expanded Object Configuration
if (is_array($config)) {
// 1. Type Hinting (e.g., "string", "?int", "MyClass")
if (!empty($config['type'])) {
$parts['type'] = $config['type'] . ' ';
}
// 2. Pass by Reference
if (!empty($config['reference']) && $config['reference'] === true) {
$parts['ref'] = '&';
}
// 3. Variadic Arguments (...$args)
if (!empty($config['variadic']) && $config['variadic'] === true) {
$parts['ref'] = '...';
}
// 4. Default Values
// We use array_key_exists so we can detect if the default is actually NULL
if (array_key_exists('default', $config)) {
// var_export converts the value to parsable PHP code (adds quotes to strings, preserves arrays)
$parts['default'] = ' = ' . var_export($config['default'], true);
}
}
// Case B: Simple Key-Value pair (Backward Compatibility / Simple Type)
// Example: "endpoint": "string"
elseif (is_string($config) && !empty($config)) {
$parts['type'] = $config . ' ';
}
// Assemble definition: "string &$name = 'value'"
$compiledArgs[] = "{$parts['type']}{$parts['ref']}{$parts['name']}{$parts['default']}";
}
}
$argsString = implode(", ", $compiledArgs);
$supportFunctions .= "function {$f['Name']}($argsString) {\n{$f['PhpCode']}\n}\n";
}
return $supportFunctions;
}

View File

@ -96,6 +96,66 @@ function processActiveTable($activeTable) {
} }
} }
/**
* Processes all cron jobs that match the current time.
* Uses a temp file to ensure jobs run only once per minute,
* even if the script crashes and restarts.
*/
function processCronJobs() {
$lockFile = '/tmp/cron_last_run.json';
$currentTimeKey = date("Y-m-d H:i"); // Unique ID for this specific minute
// 1. CHECK PREVIOUS RUN (File Persistence)
if (file_exists($lockFile)) {
$data = json_decode(file_get_contents($lockFile), true);
// If the stored time matches right now, we already ran.
if (($data['last_run'] ?? '') === $currentTimeKey) {
return;
}
}
// 2. UPDATE TRACKER IMMEDIATELY
// We write to the file now to "claim" this minute.
file_put_contents($lockFile, json_encode(['last_run' => $currentTimeKey]));
echo "Scanning all the cron jobs that need to be run...\n";
// 3. FETCH JOBS
// We check for an exact match OR a wildcard (-1)
$sql = "SELECT id, PhpCode
FROM SYS_PRD_BND.CronJobs
WHERE
(Minute = MINUTE(NOW()) OR Minute = -1)
AND (Hour = HOUR(NOW()) OR Hour = -1)
AND (DayOfMonth = DAY(NOW()) OR DayOfMonth = -1)
AND (Month = MONTH(NOW()) OR Month = -1)
AND (DayOfWeek = DAYOFWEEK(NOW()) OR DayOfWeek = -1)";
// 4. EXECUTION LOOP
$jobs = sql($sql);
if ($jobs) {
foreach ($jobs as $cronJob) {
if (!empty($cronJob["PhpCode"])) {
// Pass a unique identifier (cronJob_ID) to the sandbox runner
runPHPCronCode("cronJob_" . $cronJob["id"], $cronJob["PhpCode"], $cronJob["id"]);
}
}
}
}
/**
* Executes database-level dynamic PHP trigger code.
*/
function runPHPCronCode($functionName,$code,$cronJobId) {
echo "Running PHP CRON code for cronJobId $cronJobId...\n";
$phpCode = generatePHPCronCode($functionName, $code,$cronJobId);
$result = runSandboxedPHP($phpCode,$stdout,$stderr);
handleCronJobExecutionResult($result, $stdout,$stderr,$cronJobId);
}
/** /**
* Ensures the 'LastUpdated' column exists, adding it if missing. * Ensures the 'LastUpdated' column exists, adding it if missing.
*/ */
@ -237,6 +297,28 @@ function updateTriggerError($tableName, $error) {
function clearTriggerError($tableName) { function clearTriggerError($tableName) {
sql("UPDATE SYS_PRD_BND.Tables SET LastError = '', LastUpdated = NOW() WHERE Name = '$tableName'"); sql("UPDATE SYS_PRD_BND.Tables SET LastError = '', LastUpdated = NOW() WHERE Name = '$tableName'");
} }
function updateCronError($cronJobId, $error) {
// Sanitize single quotes to prevent SQL breakage
$safeError = str_replace("'", '"', $error);
// Update the CronJobs table with the error
sql("UPDATE SYS_PRD_BND.CronJobs
SET LastError = '$safeError',
LastUpdated = NOW()
WHERE id = '$cronJobId'"); // Ensure 'id' matches your actual primary key column name
// Send the alert
sendTelegramMessage("*ERROR* on Cron Job #$cronJobId : " . $error, "DatabaseGroup");
}
function clearCronError($cronJobId) {
// Clear the error field
sql("UPDATE SYS_PRD_BND.CronJobs
SET LastError = '',
LastUpdated = NOW()
WHERE id = '$cronJobId'");
}
function getConstantsDefinition() { function getConstantsDefinition() {
$constants = ""; $constants = "";
@ -247,15 +329,6 @@ function getConstantsDefinition() {
return $constants; return $constants;
} }
function getSupportFunctionsDefinition() {
$supportFunctions = "";
foreach (sql("SELECT Name, InputArgs_json, PhpCode FROM SYS_PRD_BND.SupportFunctions WHERE PhpCode IS NOT NULL") as $f) {
$args = implode(", ", array_map(fn($s) => "\$$s", array_keys(json_decode($f["InputArgs_json"], true))));
$supportFunctions .= "function {$f['Name']}($args) {\n{$f['PhpCode']}\n}\n";
}
return $supportFunctions;
}
function getPythonImports() { function getPythonImports() {
$imports = ""; $imports = "";
foreach (sql("SELECT LibName, AliasName FROM SYS_PRD_BND.PyPi") as $module) { foreach (sql("SELECT LibName, AliasName FROM SYS_PRD_BND.PyPi") as $module) {