mirror of
https://github.com/fluencelabs/examples
synced 2024-12-04 19:20:17 +00:00
fix: SQL REPL, SQLite module version bump and SQLite Readme update [Fixes VM-225] (#426)
This commit is contained in:
parent
d302f269ad
commit
742ae5c3b8
@ -5,15 +5,7 @@ name = "sqlite3"
|
|||||||
max_heap_size = "100 KiB"
|
max_heap_size = "100 KiB"
|
||||||
logger_enabled = false
|
logger_enabled = false
|
||||||
|
|
||||||
[module.wasi]
|
|
||||||
preopened_files = ["/tmp"]
|
|
||||||
mapped_dirs = { "tmp" = "/tmp" }
|
|
||||||
|
|
||||||
[[module]]
|
[[module]]
|
||||||
name = "sqlite_test"
|
name = "sqlite_test"
|
||||||
max_heap_size = "10 KiB"
|
max_heap_size = "10 KiB"
|
||||||
logger_enabled = false
|
logger_enabled = false
|
||||||
|
|
||||||
[module.wasi]
|
|
||||||
preopened_files = ["/tmp"]
|
|
||||||
mapped_dirs = { "tmp" = "/tmp" }
|
|
@ -1,115 +1,112 @@
|
|||||||
# SQLite Example
|
# SQLite Example
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
[SQLite](https://www.sqlite.org/index.html) is an ubiquitous persistence solution also available on the Fluence stack. Unlike basic compute modules, using SQLite in a service is a little more intricate. In order to create the service, we need two dependencies: An SQLite Wasm module and an SQLite adapter, where the adapter is a [WASM IT compliant](https://crates.io/crates/marine-sqlite-connector) [sqlite](https://github.com/stainless-steel/sqlite) package implementation. The SQLite Wasm module can be obtain from the repo as a [release](https://github.com/fluencelabs/sqlite/releases/tag/v0.15.0_w) or compiled from [code](https://github.com/fluencelabs/sqlite). For the purpose of this example, we use the release version -- see `build.sh`.
|
|
||||||
|
|
||||||
As a result, our service is comprised of two modules: the SQLite Wasm module and our sqlite module.
|
|
||||||
|
|
||||||
## Build
|
[SQLite](https://www.sqlite.org/index.html) is ubiquitous persistence solution also available in the Fluence stack. Unlike basic compute modules, using SQLite in a service is a little more intricate. In order to create a service, one needs two dependencies:
|
||||||
|
- SQLite Wasm module that one can get either in a form of a [released module](https://github.com/fluencelabs/sqlite/releases/tag/v0.17.1_w) or build it from scratch following [this](https://github.com/fluencelabs/sqlite) readme.
|
||||||
|
- SQLite connector that is [WASM IT compliant](https://crates.io/crates/marine-sqlite-connector) [sqlite](https://github.com/fluencelabs/sqlite-wasm-connector) package implementation.
|
||||||
|
|
||||||
|
For the purpose of this example, we use the release version -- see `build.sh`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
As a result, our service is comprised of two modules: the SQLite Wasm module and our sqlite module.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## How to build
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
To build the Wasm modules needed run the following command:
|
||||||
|
|
||||||
|
|
||||||
To build the required artifacts, please run the following command:
|
|
||||||
|
|
||||||
```
|
|
||||||
./build.sh
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Upon a successful build it results a couple of wasm modules:
|
$build.sh
|
||||||
|
|
||||||
```
|
|
||||||
➜ sqlite git:(main) ls artifacts
|
|
||||||
sqlite3.wasm sqlite_test.wasm
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Run
|
|
||||||
|
|
||||||
To check how it works, we need to run `mrepl`:
|
|
||||||
|
Upon a successful build there will be a pair of wasm modules:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
➜ sqlite git:(main) mrepl Config.toml
|
$ls artifacts
|
||||||
Welcome to the Marine REPL (version 0.16.1)
|
|
||||||
Minimal supported versions
|
|
||||||
sdk: 0.6.0
|
|
||||||
interface-types: 0.20.0
|
|
||||||
|
|
||||||
New version is available! 0.16.1 -> 0.16.2
|
sqlite3.wasm sqlite_test.wasm
|
||||||
To update run: cargo +nightly install mrepl
|
|
||||||
|
|
||||||
app service was created with service id = e593c776-494a-4012-9020-5b50f44409d8
|
|
||||||
elapsed time 2.555104035s
|
|
||||||
|
|
||||||
1> i
|
|
||||||
Loaded modules interface:
|
|
||||||
data DBOpenDescriptor:
|
|
||||||
ret_code: i32
|
|
||||||
db_handle: u32
|
|
||||||
data DBPrepareDescriptor:
|
|
||||||
ret_code: i32
|
|
||||||
stmt_handle: u32
|
|
||||||
tail: u32
|
|
||||||
data DBExecDescriptor:
|
|
||||||
ret_code: i32
|
|
||||||
err_msg: string
|
|
||||||
|
|
||||||
sqlite_test:
|
|
||||||
fn test2(age: i64)
|
|
||||||
fn test1(age: i64)
|
|
||||||
fn test3()
|
|
||||||
fn test_last_rowid() -> i64
|
|
||||||
sqlite3:
|
|
||||||
fn sqlite3_errmsg(db_handle: u32) -> string
|
|
||||||
fn sqlite3_open_v2(filename: string, flags: i32, vfs: string) -> DBOpenDescriptor
|
|
||||||
fn sqlite3_bind_double(stmt_handle: u32, pos: i32, value: f64) -> i32
|
|
||||||
fn sqlite3_column_count(stmt_handle: u32) -> i32
|
|
||||||
fn sqlite3_bind_text(stmt_handle: u32, pos: i32, text: string, xDel: i32) -> i32
|
|
||||||
fn sqlite3_errcode(db: u32) -> i32
|
|
||||||
fn sqlite3_busy_timeout(db_handle: u32, ms: u32) -> i32
|
|
||||||
fn sqlite3_changes(db_handle: u32) -> i32
|
|
||||||
fn sqlite3_column_name(stmt_handle: u32, N: u32) -> string
|
|
||||||
fn sqlite3_column_int64(stmt_handle: u32, icol: u32) -> i64
|
|
||||||
fn sqlite3_bind_blob(stmt_handle: u32, pos: i32, blob: []u8, xDel: i32) -> i32
|
|
||||||
fn sqlite3_finalize(stmt_handle: u32) -> i32
|
|
||||||
fn sqlite3_column_type(stmt_handle: u32, icol: u32) -> i32
|
|
||||||
fn sqlite3_prepare_v2(db_handle: u32, sql: string) -> DBPrepareDescriptor
|
|
||||||
fn sqlite3_column_bytes(stmt_handle: u32, icol: u32) -> i32
|
|
||||||
fn sqlite3_column_text(stmt_handle: u32, icol: u32) -> string
|
|
||||||
fn sqlite3_column_blob(stmt_handle: u32, icol: i32) -> []u8
|
|
||||||
fn sqlite3_column_double(stmt_handle: u32, icol: i32) -> f64
|
|
||||||
fn sqlite3_close(db_handle: u32) -> i32
|
|
||||||
fn sqlite3_exec(db_handle: u32, sql: string, callback_id: i32, callback_arg: i32) -> DBExecDescriptor
|
|
||||||
fn sqlite3_total_changes(db_handle: u32) -> i32
|
|
||||||
fn sqlite3_bind_null(stmt_handle: u32, pos: i32) -> i32
|
|
||||||
fn sqlite3_libversion_number() -> i32
|
|
||||||
fn sqlite3_reset(stmt_handle: u32) -> i32
|
|
||||||
fn sqlite3_step(stmt_handle: u32) -> i32
|
|
||||||
fn sqlite3_bind_int64(stmt_handle: u32, pos: i32, value: i64) -> i32
|
|
||||||
|
|
||||||
2> call sqlite_test test1 [20]
|
|
||||||
name = Alice
|
|
||||||
age = 42
|
|
||||||
name = Bob
|
|
||||||
age = 69
|
|
||||||
result: Null
|
|
||||||
elapsed time: 37.443512ms
|
|
||||||
|
|
||||||
3> call sqlite_test test2 [20]
|
|
||||||
name = Alice
|
|
||||||
age = 42
|
|
||||||
name = Bob
|
|
||||||
age = 69
|
|
||||||
result: Null
|
|
||||||
elapsed time: 1.715774ms
|
|
||||||
|
|
||||||
4> call sqlite_test test3 []
|
|
||||||
table size is: 2
|
|
||||||
result: Null
|
|
||||||
elapsed time: 110.686235ms
|
|
||||||
|
|
||||||
5> call sqlite_test test_last_rowid []
|
|
||||||
result: Number(4)
|
|
||||||
elapsed time: 39.816385ms
|
|
||||||
|
|
||||||
6> q
|
|
||||||
```
|
```
|
||||||
|
|
||||||
For more detailed and in depth reading on the example please refer to the [Marine Examples Readme](../README.md#sqlite-example)
|
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Here is a simple 'CREATE-INSERT-SELECT' scenario using the Wasm modules in the artifacts directory. To follow along, you need marine and mrepl installed.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$cargo install marine mrepl
|
||||||
|
...
|
||||||
|
$mrepl -q Config.toml
|
||||||
|
|
||||||
|
1> call sqlite_test sql_repl []
|
||||||
|
For exit type QUIT;
|
||||||
|
SQL> CREATE VIRTUAL TABLE demo_index USING rtree(
|
||||||
|
id,
|
||||||
|
minX, maxX,
|
||||||
|
minY, maxY
|
||||||
|
);
|
||||||
|
CREATE VIRTUAL TABLE demo_index USING rtree( id, minX, maxX, minY, maxY )
|
||||||
|
|
||||||
|
SQL> INSERT INTO demo_index VALUES
|
||||||
|
(28215, -80.781227, -80.604706, 35.208813, 35.297367),
|
||||||
|
(28216, -80.957283, -80.840599, 35.235920, 35.367825),
|
||||||
|
(28217, -80.960869, -80.869431, 35.133682, 35.208233),
|
||||||
|
(28226, -80.878983, -80.778275, 35.060287, 35.154446),
|
||||||
|
(28227, -80.745544, -80.555382, 35.130215, 35.236916),
|
||||||
|
(28244, -80.844208, -80.841988, 35.223728, 35.225471),
|
||||||
|
(28262, -80.809074, -80.682938, 35.276207, 35.377747),
|
||||||
|
(28269, -80.851471, -80.735718, 35.272560, 35.407925),
|
||||||
|
(28270, -80.794983, -80.728966, 35.059872, 35.161823),
|
||||||
|
(28273, -80.994766, -80.875259, 35.074734, 35.172836),
|
||||||
|
(28277, -80.876793, -80.767586, 35.001709, 35.101063),
|
||||||
|
(28278, -81.058029, -80.956375, 35.044701, 35.223812),
|
||||||
|
(28280, -80.844208, -80.841972, 35.225468, 35.227203),
|
||||||
|
(28282, -80.846382, -80.844193, 35.223972, 35.225655);
|
||||||
|
INSERT INTO demo_index VALUES (28215, -80.781227, -80.604706, 35.208813, 35.297367), (28216, -80.957283, -80.840599, 35.235920, 35.367825), (28217, -80.960869, -80.869431, 35.133682, 35.208233), (28226, -80.878983, -80.778275, 35.060287, 35.154446), (28227, -80.745544, -80.555382, 35.130215, 35.236916), (28244, -80.844208, -80.841988, 35.223728, 35.225471), (28262, -80.809074, -80.682938, 35.276207, 35.377747), (28269, -80.851471, -80.735718, 35.272560, 35.407925), (28270, -80.794983, -80.728966, 35.059872, 35.161823), (28273, -80.994766, -80.875259, 35.074734, 35.172836), (28277, -80.876793, -80.767586, 35.001709, 35.101063), (28278, -81.058029, -80.956375, 35.044701, 35.223812), (28280, -80.844208, -80.841972, 35.225468, 35.227203), (28282, -80.846382, -80.844193, 35.223972, 35.225655)
|
||||||
|
|
||||||
|
SQL> SELECT A.id FROM demo_index AS A, demo_index AS B
|
||||||
|
WHERE A.maxX>=B.minX AND A.minX<=B.maxX
|
||||||
|
AND A.maxY>=B.minY AND A.minY<=B.maxY
|
||||||
|
AND B.id=28269 ORDER BY 1;
|
||||||
|
SELECT A.id FROM demo_index AS A, demo_index AS B WHERE A.maxX>=B.minX AND A.minX<=B.maxX AND A.maxY>=B.minY AND A.minY<=B.maxY AND B.id=28269 ORDER BY 1
|
||||||
|
28215 28216 28262 28269
|
||||||
|
|
||||||
|
SQL> quit;
|
||||||
|
quit
|
||||||
|
result: null
|
||||||
|
elapsed time: 33.303383112s
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
Please, [file an issue](https://github.com/fluencelabs/marine/issues) if you find a bug. You can also contact us at [Discord](https://discord.com/invite/5qSnPZKh7u) or [Telegram](https://t.me/fluence_project). We will do our best to resolve the issue ASAP.
|
||||||
|
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Any interested person is welcome to contribute to the project. Please, make sure you read and follow some basic [rules](https://github.com/fluencelabs/rust-peer/blob/master/CONTRIBUTING.md).
|
||||||
|
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
All software code is copyright (c) Fluence Labs, Inc. under the [Apache-2.0](https://github.com/fluencelabs/rust-peer/blob/master/LICENSE) license.
|
@ -8,5 +8,5 @@ marine build --release
|
|||||||
mkdir -p artifacts
|
mkdir -p artifacts
|
||||||
rm -f artifacts/*.wasm
|
rm -f artifacts/*.wasm
|
||||||
cp target/wasm32-wasi/release/sqlite_test.wasm artifacts/
|
cp target/wasm32-wasi/release/sqlite_test.wasm artifacts/
|
||||||
wget https://github.com/fluencelabs/sqlite/releases/download/v0.15.0_w/sqlite3.wasm
|
wget https://github.com/fluencelabs/sqlite/releases/download/v0.17.1_w/sqlite3.wasm
|
||||||
mv sqlite3.wasm artifacts/
|
mv sqlite3.wasm artifacts/
|
||||||
|
@ -13,9 +13,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use marine_rs_sdk::marine;
|
use marine_rs_sdk::marine;
|
||||||
use marine_rs_sdk::module_manifest;
|
use marine_rs_sdk::module_manifest;
|
||||||
|
use std::io::{self, Write};
|
||||||
|
|
||||||
use marine_sqlite_connector;
|
use marine_sqlite_connector;
|
||||||
use marine_sqlite_connector::{State, Value};
|
use marine_sqlite_connector::{State, Value};
|
||||||
@ -24,6 +24,58 @@ module_manifest!();
|
|||||||
|
|
||||||
pub fn main() {}
|
pub fn main() {}
|
||||||
|
|
||||||
|
#[marine]
|
||||||
|
pub fn sql_repl() {
|
||||||
|
let connection = marine_sqlite_connector::open(":memory:").unwrap();
|
||||||
|
let delimiter = ';';
|
||||||
|
println!("For exit type QUIT;");
|
||||||
|
loop {
|
||||||
|
print!("SQL> ");
|
||||||
|
io::stdout().flush().unwrap();
|
||||||
|
|
||||||
|
let mut input_lines = io::stdin().lines();
|
||||||
|
let mut sql_string: String = String::new();
|
||||||
|
while let Some(line) = input_lines.next() {
|
||||||
|
let l = line.unwrap();
|
||||||
|
let l_no_spaces = l.trim();
|
||||||
|
if let Some(pos) = l_no_spaces.find(delimiter) {
|
||||||
|
sql_string.push_str(&l_no_spaces[..pos]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sql_string.push_str(l_no_spaces);
|
||||||
|
sql_string.push(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{}", sql_string);
|
||||||
|
if let Some(first_word) = sql_string.split_whitespace().next() {
|
||||||
|
match first_word.to_uppercase().as_str() {
|
||||||
|
"SELECT" => {
|
||||||
|
let mut cursor = connection.prepare(sql_string).unwrap().cursor();
|
||||||
|
while let Some(row) = cursor.next().unwrap() {
|
||||||
|
for column in row.iter() {
|
||||||
|
match column {
|
||||||
|
Value::Binary(_) => print!(
|
||||||
|
"bin {:}",
|
||||||
|
String::from_utf8_lossy(column.as_binary().unwrap())
|
||||||
|
),
|
||||||
|
Value::Float(_) => print!("{} ", column.as_float().unwrap()),
|
||||||
|
Value::Integer(_) => print!("{} ", column.as_integer().unwrap()),
|
||||||
|
Value::String(_) => print!("{} ", column.as_string().unwrap()),
|
||||||
|
Value::Null => print!("NULL "),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
"QUIT" => break,
|
||||||
|
_ => connection.execute(sql_string).unwrap(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[marine]
|
#[marine]
|
||||||
pub fn test1(age: i64) {
|
pub fn test1(age: i64) {
|
||||||
let connection = marine_sqlite_connector::open(":memory:").unwrap();
|
let connection = marine_sqlite_connector::open(":memory:").unwrap();
|
||||||
@ -141,8 +193,6 @@ pub fn test_last_rowid() -> i64 {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use marine_rs_sdk_test::marine_test;
|
use marine_rs_sdk_test::marine_test;
|
||||||
use marine_rs_sdk_test::CallParameters;
|
|
||||||
use marine_rs_sdk_test::SecurityTetraplet;
|
|
||||||
|
|
||||||
#[marine_test(config_path = "../Config.toml", modules_dir = "../artifacts")]
|
#[marine_test(config_path = "../Config.toml", modules_dir = "../artifacts")]
|
||||||
fn test(sqlite_test: marine_test_env::sqlite_test::ModuleInterface) {
|
fn test(sqlite_test: marine_test_env::sqlite_test::ModuleInterface) {
|
||||||
|
Loading…
Reference in New Issue
Block a user