带有额外参数的Eiffel sqlite调用

时间:2018-03-27 12:39:29

标签: database sqlite eiffel agents

我从一个示例中复制了一些用于访问sqlite数据库的代码。它使用代理来获取返回的行:

    check_db (input_line: STRING)

    local

        df_db:       SQLITE_DATABASE
        df_db_query: SQLITE_QUERY_STATEMENT

        test_val: STRING

    do

        test_val := "whatever"

        create df_db.make_open_read_write ("Large.db")

        create df_db_query.make ("SELECT * FROM test_table WHERE test_val =%
                    % :TEST_VAL%
                    % ;", df_db)

        check df_db_query_is_compiled: df_db_query.is_compiled
            end

        df_db_query.execute_with_arguments (agent (returned_row: SQLITE_RESULT_ROW): BOOLEAN
                do
                    if returned_row.is_null (1) then
                        insert_into_db
                    end
                end,
            << create {SQLITE_STRING_ARG}.make  (":TEST_VAL", test_val) >>)

    end -- check_db

我遇到的问题是我想将input_line传递给过程insert_into_db。 execute_with_arguments使用的内联过程不能查看其范围之外的任何变量,但我认为必须有一种方法可以向其传递一个额外的参数?我尝试过的所有内容都拒绝使用语法错误进行编译。

在这种情况下,我只是想添加一个数据库条目,如果它还不存在,但我可以很容易地看到我想将返回的行和一些额外的数据发送到另一个程序的情况,所以它必须是可行的。

1 个答案:

答案 0 :(得分:1)

正如您正确指出的那样,目前,Eiffel中的局部变量不会自动传递到内联代理。解决方案是向内联代理添加显式的形式参数,并将相应的实际参数传递给它。

示例中的内联代理可以按如下方式进行调整(为简洁起见,省略了带有参数input_line的外部上下文):

agent (returned_row: SQLITE_RESULT_ROW; s: STRING): BOOLEAN
    do
            -- `s` is attached to `input_line` here.
        if returned_row.is_null (1) then
            insert_into_db
        end
    end (?, input_line)

除了将获得s值的正式参数input_line之外,您还可以看到实际参数(?, input_line)的明确列表。问号表示一个开放的参数,它将像execute_with_arguments一样传递给代理。 input_line代表一个封闭的论点。

当列表没有关闭的参数时,如原始代码中那样,它可以省略。但是,可以在原始代码中的内联代理的关键字(?)之后编写end,以完全明确。