Skip to content

Feat: Add(sqlite)#147

Closed
jtenner wants to merge 10 commits into
lunatic-solutions:mainfrom
jtenner:main
Closed

Feat: Add(sqlite)#147
jtenner wants to merge 10 commits into
lunatic-solutions:mainfrom
jtenner:main

Conversation

@jtenner

@jtenner jtenner commented Oct 18, 2022

Copy link
Copy Markdown
Contributor

This pull request aims to add sqlite capabilities to the lunatic host. Any comments and help would be appreciated!

.or_trap("lunatic::sqlite::execute")?
.lock()
.or_trap("lunatic::sqlite::execute")?
.execute(exec)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to return here the error to the guest, instead of just trapping.

Comment thread crates/lunatic-sqlite-api/src/lib.rs Outdated
Comment on lines +96 to +97
data_ptr: u32,
data_len: u32,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of query taking the data_*, I think it would be better if it returned just the length and buffered the data. There could be another function (query_result?) that just copies the data into the guest.

That way the guest has a chance to allocate the right space and doesn't need to hope that the data is going to fit into a pre-allocated buffer.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was originally for this idea. We can talk about it on Monday for sure.

.or_trap("lunatic::sqlite::query_prepare::read_binary")?;

let len = bytes.len();
let mut result = vec![ColumnType::Binary as u8];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this also needs to be .to_le_bytes encoded.

Comment on lines +173 to +176
let mut result = vec![ColumnType::String as u8];
result.append(&mut (len as u32).to_le_bytes().to_vec());
result.append(&mut bytes.as_bytes().to_vec());
result

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of appending to a temporary vector (result), we could here directly append to return_value.

return_value.append(&mut bytes);
}

return_value.push(ColumnType::NewRow as u8);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to leave a trailing NewRow marker, even there are no new rows. This is not a big issue, but the parser needs to be aware of it.

let memory = get_memory(&mut caller)?;
let (memory_slice, state) = memory.data_and_store_mut(&mut caller);

// get the vevtor

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo

@bkolobara

Copy link
Copy Markdown
Contributor

This approach looks good to me. Thanks @jtenner for pushing this effort forward!

I'm not that familiar with SQLite and am curious how useful features like "named parameters" are? At the moment we don't support something like:

let mut statement = connection.prepare("SELECT * FROM users WHERE name = :name")?;
statement.bind_by_name(":name", "Bob")?;

Should this also be part of the interface, or are people just working around this? I assume that doing manual escaping of user input without it would be an error-prone process. Should we include it in our API?

I'm also wondering about the security implications of the open call. Currently the vm only lets you access the current directory and sub-directories, but the open command here takes any path. Should this be configurable like directory access? And limited by default?

On a more future-proof note, tools like https://litestream.io that work together with SQLite often use the WAL (write ahead log) feature. This is also recommended for all production deployments of SQLite. If I'm not mistaken, this also allows for multithreaded writes. Should we maybe use it by default? This would allow for connections to be shared between processes running concurrently.

@withtypes

Copy link
Copy Markdown
Contributor

By the way, could this work as a plugin as in #154 ? Also @tqwewe

@tqwewe

tqwewe commented Nov 16, 2022

Copy link
Copy Markdown
Member

Absolutely. I haven't followed along with this PR, but after looking into it, it seems like it just adds host functions and stores state?
If so, then it'sa perfect fit for a plugin.

I actually wrote some host functions for using postgres for a personal project, and I'm planning to transition that code into a plugin too.

@jtenner

jtenner commented Dec 8, 2022

Copy link
Copy Markdown
Contributor Author

Closed in favor of #160

@jtenner jtenner closed this Dec 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants