Repository: libsql/libsql
File: libsql-server/src/database/schema.rs (Rust)

Code before:
    config: MetaStoreHandle,
}

impl SchemaConnection {
    pub(crate) fn connection(&self) -> &PrimaryConnection {
        &self.connection
    }
}

#[async_trait::async_trait]
impl crate::connection::Connection for SchemaConnection {
    async fn execute_program<B: crate::query_result_builder::QueryResultBuilder>(
        &self,
        migration: Program,
        ctx: RequestContext,
        builder: B,
        replication_index: Option<crate::replication::FrameNo>,
    ) -> crate::Result<B> {
        if migration.is_read_only() {
            let res = self
                .connection
                .execute_program(migration, ctx, builder, replication_index)
                .await;

            // If the query was okay, verify if the connection is left in a txn state
            if res.is_ok() && !self.connection.is_autocommit().await? {
                return Err(crate::Error::Migration(
                    crate::schema::Error::ConnectionInTxnState,
                ));
            }

            res
        } else {
            check_program_auth(&ctx, &migration, &self.config.get())?;
            let connection = self.connection.clone();
            validate_migration(&migration)?;
            let migration = Arc::new(migration);
            let builder = tokio::task::spawn_blocking({
                let migration = migration.clone();
                move || {
                    let res = connection.with_raw(|conn| -> crate::Result<_> {
                        let mut txn = conn
                            .transaction_with_behavior(rusqlite::TransactionBehavior::Immediate)
                            .map_err(|_| {
                                crate::Error::Migration(
                                    crate::schema::Error::InteractiveTxnNotAllowed,
                                )
                            })?;
                        // TODO: pass proper config
                        let (ret, _) = perform_migration(
                            &mut txn,

Review comment (suggestion):
```suggestion
            // If the query was okay, verify if the connection is not in a txn state
            if res.is_ok() && self.connection.is_autocommit().await? {
```

Code after:
    config: MetaStoreHandle,
}

impl SchemaConnection {
    pub(crate) fn connection(&self) -> &PrimaryConnection {
        &self.connection
    }
}

#[async_trait::async_trait]
impl crate::connection::Connection for SchemaConnection {
    async fn execute_program<B: crate::query_result_builder::QueryResultBuilder>(
        &self,
        migration: Program,
        ctx: RequestContext,
        builder: B,
        replication_index: Option<crate::replication::FrameNo>,
    ) -> crate::Result<B> {
        if migration.is_read_only() {
            let res = self
                .connection
                .execute_program(migration, ctx, builder, replication_index)
                .await;

            // If the query was okay, verify if the connection is not in a txn state
            if res.is_ok() && self.connection.is_autocommit().await? {
                return Err(crate::Error::Migration(
                    crate::schema::Error::ConnectionInTxnState,
                ));
            }

            res
        } else {
            check_program_auth(&ctx, &migration, &self.config.get())?;
            let connection = self.connection.clone();
            validate_migration(&migration)?;
            let migration = Arc::new(migration);
            let builder = tokio::task::spawn_blocking({
                let migration = migration.clone();
                move || {
                    let res = connection.with_raw(|conn| -> crate::Result<_> {
                        let mut txn = conn
                            .transaction_with_behavior(rusqlite::TransactionBehavior::Immediate)
                            .map_err(|_| {
                                crate::Error::Migration(
                                    crate::schema::Error::InteractiveTxnNotAllowed,
                                )
                            })?;
                        // TODO: pass proper config
                        let (ret, _) = perform_migration(
                            &mut txn,