Как получить информацию о самоанализе движка SQLite через Rust SQLx?

При попытке выполнить запросы самоанализа SQLite в Rust SQLx я получаю:

ошибка: ошибка возвращена из базы данных: (код: 1) нет такого столбца таблицы: pragma_module_list.rowid

let recs = sqlx::query!(
    r#"
        SELECT rowid AS id, name
        FROM pragma_module_list()
        ORDER BY id
    "#
);

Как я могу обойти это ограничение SQLx?

🤔 А знаете ли вы, что...
SQL используется для создания, изменения и управления данными в базах данных.


70
1

Ответ:

Решено

Ниже приведен расширенный запрос, который извлекает версию SQLite и списки pragma/function/module/compile_option и возвращает скалярное строковое значение, содержащее форматированную информацию (при печати на консоли или использовании шрифта фиксированной ширины).

WITH
    version AS (
        SELECT concat_ws(x'0A',
            replace(printf('. %20s .', ''), ' ', '_'),
            '|    SQLite Version    |',
            replace(printf('| %20s |', ''), ' ', '-'),
            printf('| %20s |', sqlite_version()),
            replace(printf('| %20s |', ''), ' ', '_'),
            x'0A'
        ) AS info
    ),
    ids AS (
        SELECT concat_ws(x'0A',
            replace(printf('. %20s _ %20s _ %20s .', '', '', ''), ' ', '_'),
            '|    application_id    |     user_version     |    schema_version    |',
            replace(printf('| %20s | %20s | %20s |', '', '', ''), ' ', '-'),
            printf('| %20d | %20d | %20d |',
                   application_id, user_version, schema_version),
            replace(printf('| %20s | %20s | %20s |', '', '', ''), ' ', '_'),
            x'0A'
        ) AS info
        FROM pragma_application_id(), pragma_user_version(),
             pragma_schema_version()
    ),
    modules AS (
        SELECT concat_ws(x'0A',
            replace(printf('. %25s .', ''), ' ', '_'),
            '|           Modules         |',
            replace(printf('| %25s |', ''), ' ', '-'),
            group_concat(
                printf('| %-25s |', name), x'0A' ORDER BY name
            ),
            replace(printf('| %25s |', ''), ' ', '_'),
            x'0A'
        ) AS info
        FROM pragma_module_list()
    ),
    pragmas AS (
        SELECT concat_ws(x'0A',
            replace(printf('. %25s .', ''), ' ', '_'),
            '|           PRAGMA          |',
            replace(printf('| %25s |', ''), ' ', '-'),
            group_concat(
                printf('| %-25s |', name), x'0A' ORDER BY name
            ),
            replace(printf('| %25s |', ''), ' ', '_'),
            x'0A'
        ) AS info
        FROM pragma_pragma_list()
    ),
    compile_options AS (
        SELECT concat_ws(x'0A',
            replace(printf('. %35s .', ''), ' ', '_'),
            '|          Compile Options            |',
            replace(printf('| %35s |', ''), ' ', '-'),
            group_concat(
                printf('| %-35s |', compile_options),
                x'0A' ORDER BY compile_options
            ),
            replace(printf('| %35s |', ''), ' ', '_'),
            x'0A'
        ) AS info
        FROM pragma_compile_options()
    ),
    functions AS (
        SELECT concat_ws(x'0A',
            replace(printf('. %76s .', ''), ' ', '_'),
            printf('| %30s Function List  %30s |', '', ''),
            printf('| %30s -------------  %30s |', '', ''),
            '|              name              | builtin | type  | encoding | narg |  flags  |',
            replace(printf('| %76s |', ''), ' ', '-'),
            group_concat(printf('| %-30s |    %d    |   %s   |  %-7s |  %2d  | %7d |',
                name,
                builtin,
                type,
                enc,
                narg,
                flags
            ), x'0A' ORDER BY name, narg),
            replace(printf('| %30s | %7s | %5s | %8s | %4s | %7s |',
                '', '', '', '', '', ''), ' ', '_'),
            x'0A'
        ) AS info
        FROM pragma_function_list()
    ),
    info_schema AS (
        SELECT concat_ws(x'0A',
                version.info,
                ids.info,
                modules.info,
                pragmas.info,
                functions.info,
                compile_options .info
            ) AS info
        FROM version, ids, modules, pragmas, functions, compile_options 
    )
SELECT *
FROM info_schema;

Этот запрос может быть выполнен в оболочке SQLite (например, в официальной скрипте SQLite), а также работает с sqlx. Например, поместите запрос в файл «queries/intro.sql», а следующий код — в «src/main.rs»:

use std::env;
use sqlx::sqlite::SqlitePool;


#[tokio::main(flavor = "current_thread")]
async fn main() -> anyhow::Result<()> {
    let pool = SqlitePool::connect(&env::var("DATABASE_URL")?).await?;

    println!("\nSQLite Introspection Information");
    exec(&pool).await?;

    Ok(())
}


async fn exec(pool: &SqlitePool) -> anyhow::Result<()> {
    let recs = sqlx::query_file!("queries/intro.sql")
        .fetch_all(pool)
        .await?;
    
    for rec in recs {
        println!(
            "{}",
            rec.info.unwrap(),
        );
    }

    Ok(())
}

Интересные вопросы для изучения