gbserver/src/services/keywords/prompt.md
Rodrigo Rodriguez (Pragmatismo) 0a009f9789
Some checks failed
GBCI / build (push) Failing after 30m58s
- SET SCHEDULE keyword - ON keyword
2025-08-16 18:13:03 -03:00

3.9 KiB

Create a new Rhai custom keyword implementation with these specifications:

  1. DATABASE REQUIREMENTS:
  • No enums in database schema (only in Rust code)
  • Use direct integer values for enum variants in queries
  • Follow existing connection pooling pattern with AppState
  • Include proper error handling and logging
  1. RUST IMPLEMENTATION:
  • Enum definition (Rust-only, no DB enum):
#[repr(i32)]
pub enum KeywordAction {
    Action1 = 0,
    Action2 = 1,
    Action3 = 2
}
  1. KEYWORD TEMPLATE:
pub fn {keyword_name}_keyword(state: &AppState, engine: &mut Engine) {
    let db = state.db_custom.clone();

    engine.register_custom_syntax(
        {syntax_pattern},
        {is_raw},
        {
            let db = db.clone();
            move |context, inputs| {
                // Input processing
                {input_processing}

                let binding = db.as_ref().unwrap();
                let fut = execute_{keyword_name}(binding, {params});

                let result = tokio::task::block_in_place(||
                    tokio::runtime::Handle::current().block_on(fut))
                        .map_err(|e| format!("DB error: {}", e))?;

                {result_handling}
            }
        }
    ).unwrap();
}

pub async fn execute_{keyword_name}(
    pool: &PgPool,
    {params_with_types}
) -> Result<Value, Box<dyn std::error::Error>> {
    println!("Executing {keyword_name} with: {debug_params}");

    let result = sqlx::query(
        "{sql_query_with_i32_enum}"
    )
    .bind({enum_value} as i32)
    {additional_binds}
    .execute(pool)
    .await?;

    Ok(json!({
        "command": "{keyword_name}",
        {result_fields}
        "rows_affected": result.rows_affected()
    }))
}
  1. EXAMPLE IMPLEMENTATION (SET SCHEDULE):
// Enum (Rust-only)
#[repr(i32)]
pub enum TriggerKind {
    Scheduled = 0,
    TableUpdate = 1,
    TableInsert = 2,
    TableDelete = 3
}

// Keyword implementation
pub fn set_schedule_keyword(state: &AppState, engine: &mut Engine) {
    let db = state.db_custom.clone();

    engine.register_custom_syntax(
        ["SET", "SCHEDULE", "$string$"],
        true,
        {
            let db = db.clone();
            move |context, inputs| {
                let cron = context.eval_expression_tree(&inputs[0])?.to_string();
                let script_name = format!("cron_{}.rhai", cron.replace(' ', "_"));

                let binding = db.as_ref().unwrap();
                let fut = execute_set_schedule(binding, &cron, &script_name);

                let result = tokio::task::block_in_place(||
                    tokio::runtime::Handle::current().block_on(fut))
                        .map_err(|e| format!("DB error: {}", e))?;

                if let Some(rows_affected) = result.get("rows_affected") {
                    Ok(Dynamic::from(rows_affected.as_i64().unwrap_or(0)))
                } else {
                    Err("No rows affected".into())
                }
            }
        }
    ).unwrap();
}

pub async fn execute_set_schedule(
    pool: &PgPool,
    cron: &str,
    script_name: &str,
) -> Result<Value, Box<dyn std::error::Error>> {
    println!("Executing schedule: {}, {}", cron, script_name);

    let result = sqlx::query(
        "INSERT INTO system_automations
        (kind, schedule, script_name)
        VALUES ($1, $2, $3)"
    )
    .bind(TriggerKind::Scheduled as i32)
    .bind(cron)
    .bind(script_name)
    .execute(pool)
    .await?;

    Ok(json!({
        "command": "set_schedule",
        "schedule": cron,
        "script_name": script_name,
        "rows_affected": result.rows_affected()
    }))
}
  1. ADDITIONAL REQUIREMENTS:
  • Maintain consistent tokio runtime handling
  • Include parameter validation
  • Follow existing JSON response format
  • Ensure proper script name generation
  • Include debug logging for all operations
  1. OUTPUT FORMAT: Provide complete implementation with:
  2. Rust enum definition
  3. Keyword registration function
  4. Execution function
  5. Example usage in Rhai