Repository: libsql/libsql
File: libsql-server/src/namespace/configurator/helpers.rs (Rust)

Code before:
    // take place, so we can afford to poll it very often for simplicity
    let mut interval = tokio::time::interval(tokio::time::Duration::from_millis(1000));
    interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);

    loop {
        interval.tick().await;
        let handle = BLOCKING_RT.spawn_blocking(enclose! {(logger) move || {
            logger.maybe_compact()
        }});
        handle
            .await
            .expect("Compaction task crashed")
            .context("Compaction failed")?;
    }
}

async fn load_dump<S>(dump: S, conn: PrimaryConnection) -> crate::Result<(), LoadDumpError>
where
    S: Stream<Item = std::io::Result<Bytes>> + Unpin,
{
    let mut reader = tokio::io::BufReader::new(StreamReader::new(dump));
    let mut curr = String::new();
    let mut line = String::new();
    let mut skipped_wasm_table = false;
    let mut n_stmt = 0;
    let mut line_id = 0;

    while let Ok(n) = reader.read_line(&mut curr).await {
        line_id += 1;
        if n == 0 {
            break;
        }
        let trimmed = curr.trim();
        if trimmed.is_empty() || trimmed.starts_with("--") {
            curr.clear();
            continue;
        }
        // FIXME: it's well known bug that comment ending with semicolon will be handled incorrectly by currend dump processing code
        let statement_end = trimmed.ends_with(';');

        // we want to concat original(non-trimmed) lines as trimming will join all them in one
        // single-line statement which is incorrect if comments in the end are present
        line.push_str(&curr);
        curr.clear();

        // This is a hack to ignore the libsql_wasm_func_table table because it is already created
        // by the system.
        if !skipped_wasm_table && line.trim() == WASM_TABLE_CREATE {
            skipped_wasm_table = true;
            line.clear();
            continue;

Review comment (suggestion):
I'm aware of the memory allocation here, but given that we need to provide the object from the heap to `sqlite3_parser` I decided to go with this option. Not sure if it is the best one though.

Code after:
    // take place, so we can afford to poll it very often for simplicity
    let mut interval = tokio::time::interval(tokio::time::Duration::from_millis(1000));
    interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);

    loop {
        interval.tick().await;
        let handle = BLOCKING_RT.spawn_blocking(enclose! {(logger) move || {
            logger.maybe_compact()
        }});
        handle
            .await
            .expect("Compaction task crashed")
            .context("Compaction failed")?;
    }
}

async fn load_dump<S>(dump: S, conn: PrimaryConnection) -> crate::Result<(), LoadDumpError>
where
    S: Stream<Item = std::io::Result<Bytes>> + Unpin,
{
    let mut reader = tokio::io::BufReader::new(StreamReader::new(dump));
    let mut dump_content = String::new();
    reader
        .read_to_string(&mut dump_content)
        .await
        .map_err(|e| LoadDumpError::Internal(format!("Failed to read dump content: {}", e)))?;

    if dump_content.to_lowercase().contains("attach") {
        return Err(LoadDumpError::InvalidSqlInput(
            "attach statements are not allowed in dumps".to_string(),
        ));
    }

    let mut parser = Box::new(Parser::new(dump_content.as_bytes()));
    let mut skipped_wasm_table = false;
    let mut n_stmt = 0;

    loop {
        match parser.next() {
            Ok(Some(cmd)) => {
                n_stmt += 1;

                if !skipped_wasm_table {
                    if let Cmd::Stmt(Stmt::CreateTable { tbl_name, .. }) = &cmd {
                        if tbl_name.name.0 == "libsql_wasm_func_table" {
                            skipped_wasm_table = true;
                            tracing::debug!("Skipping WASM table creation");
                            continue;
                        }
                    }
                }