Skip to content

updated sql.wit.md, and README.md #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jan 30, 2023
6 changes: 3 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: WebAssembly/wit-abi-up-to-date@v6
with:
wit-abi-tag: wit-abi-0.6.0
# - uses: WebAssembly/wit-abi-up-to-date@v6
# with:
# wit-abi-tag: wit-abi-0.6.0
65 changes: 42 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,22 @@
# [Example WASI proposal]

This template can be used to start a new proposal, which can then be proposed in the WASI Subgroup meetings.

The sections below are recommended. However, every proposal is different, and the community can help you flesh out the proposal, so don't block on having something filled in for each one of them.

Thank you to the W3C Privacy CG for the [inspiration](https://github.com/privacycg/template)!

# [Title]
# `wasi-sql`

A proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API.

### Current Phase

[Fill in the current phase, e.g. Phase 1]
`wasi-messaging` is currently in [Phase 1](https://github.com/WebAssembly/WASI/blob/main/Proposals.md#phase-1---feature-proposal-cg).

### Champions

- [Champion 1]
- [Champion 2]
- [etc.]
- [Dan Chiarlone](https://github.com/danbugs)
- [David Justice](https://github.com/devigned)
- [Jiaxiao Zhou](https://github.com/Mossaka)

### Phase 4 Advancement Criteria

TODO before entering Phase 2.
`wasi-sql` should have at least two implementations (i.e., from service providers, and or cloud providers), and, at the very minimum, pass the testsuite for Windows, Linux, and MacOS.

## Table of Contents [if the explainer is longer than one printed page]
## Table of Contents

- [Introduction](#introduction)
- [Goals [or Motivating Use Cases, or Scenarios]](#goals-or-motivating-use-cases-or-scenarios)
Expand All @@ -43,27 +35,54 @@ TODO before entering Phase 2.

### Introduction

[The "executive summary" or "abstract". Explain in a few sentences what the goals of the project are, and a brief overview of how the solution works. This should be no more than 1-2 paragraphs.]
The `wasi-sql` interface allows WebAssembly programs to interact with SQL databases in a generic and safe way. It provides functions for querying and modifying data, using prepared statements and handling errors. The interface is flexible and consistent, supporting various SQL flavors.

### Goals

### Goals [or Motivating Use Cases, or Scenarios]
The `wasi-sql` interface aims to provide a consistent and easy-to-use way for WebAssembly programs to access and manipulate data stored in SQL databases. It targets the features commonly used by 80% of user applications. By focusing on commonly used features, the interface aims to provide a simple and reliable way to build stateful services that access SQL databases.

[What is the end-user need which this project aims to address?]
The `wasi-sql` interface abstracts away specific SQL flavors and database APIs, allowing WebAssembly programs to be portable across different SQL databases that support the interface. It also abstracts away the network stack, allowing WebAssembly programs to access SQL databases without worrying about the specific network protocol used. This allows users to focus on building their applications, rather than communication details with the database.

### Non-goals

[If there are "adjacent" goals which may appear to be in scope but aren't, enumerate them here. This section may be fleshed out as your design progresses and you encounter necessary technical and other trade-offs.]
- The `wasi-sql` interface does not aim to provide support for every possible feature of SQL databases. Instead, it focuses on the features that are commonly used by 80% of user applications.
- The `wasi-sql` interface does not aim to provide support for specific database APIs or network protocols. It abstracts away these implementation details to allow WebAssembly programs to be portable across different SQL databases that support the interface.
- The `wasi-sql` interface does not aim to address control-plane behavior or functionality, such as cluster management, monitoring, data consistency, replication, or sharding. These are provider-specific and are not specified by the wasi-sql interface.

### API walk-through

[Walk through of how someone would use this API.]

#### [Use case 1]
#### Use case 1: Query data from a table

[Provide example code snippets and diagrams explaining how the API would be used to solve the given problem]
Imagine you have a WebAssembly program that needs to query data from a table in a SQL database. The following Rust code shows how you can use the `wasi-sql` interface to execute a SELECT statement and iterate over the resulting rows.

#### [Use case 2]
```rs
// Create a prepared statement
let stmt = sql::statement::prepare("SELECT * FROM users WHERE name = ? AND age = ?", vec!["John Doe", "32"])?;

[etc.]
// Execute the query and get the stream of rows
let result_stream = sql::query(stmt)?;

// Iterate over the rows in the stream
for row in result_stream {
// Print the column names and values for the current row
println!("Column name: {:?}", row.field_name);
println!("Value: {:?}", row.value);
}
```

#### Use case 2: Insert data into a table

Imagine you have a WebAssembly program that needs to insert a row into a table in a SQL database. The following Rust code shows how you can use the wasi-sql interface to execute an INSERT statement.

```rs
// Create a prepared statement
let stmt = sql::statement::prepare("INSERT INTO users (name, age) VALUES (?, ?)", vec!["Jane Doe", "30"])?;

// Execute the statement
sql::exec(stmt)?;
```

### Detailed design discussion

Expand Down
31 changes: 0 additions & 31 deletions proposal-template.abi.md

This file was deleted.

32 changes: 0 additions & 32 deletions proposal-template.wit.md

This file was deleted.

66 changes: 66 additions & 0 deletions sql.wit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# `wasi-sql` API

## Interfaces

```wit
interface "wasi:sql" {
// one single row item
record row {
field-name: string,
value: data-type,
}

// common data types
variant data-type {
int32(s32),
int64(s64),
uint32(u32),
uint64(u64),
float(float64),
double(float64),
str(string),
boolean(bool),
date(string),
Copy link

Choose a reason for hiding this comment

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

This is interesting... are you thinking the standard would define a canonical string format and implementations would adapt however they saw the database's DATE type into that string format? (I don't have a better plan.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's a good point. Initially, I was thinking of just relying on the format used by the underlying database. On the other hand, it might be a good idea to define a standardized format for storing dates in the interface itself for consistency's sake — we could use ISO 8601, or smt of the sort. That said, I'm not sure. How do you feel about just relying on the underlying format?

Copy link

@itowlson itowlson Dec 21, 2022

Choose a reason for hiding this comment

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

I'm not sure what "the underlying format" is. When I ask SQL Server for a datetimeoffset column, I assume it is stored in some opaque binary format, and surfaced as a System.DateTimeOffset or chrono::DateTime or whatever type by the driver. So we would probably need to format it anyway.

I could be wrong though - could you expand on your understanding of "underlying format"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@itowlson ~ I tried out implementing this interface for postgres, and here's what I did w/ regard to this:

                        "date" => {
                            let v: String = row.get(i);
                            let parsed = NaiveDate::parse_from_str(&v, "%Y-%m-%d").unwrap();
                            DataType::Date(parsed.to_string())
                        }
                        "time" => {
                            let v: String = row.get(i);
                            let parsed = NaiveTime::parse_from_str(&v, "%H:%M:%S").unwrap();
                            DataType::Time(parsed.to_string())
                        }
                        "timestamp" => {
                            let v: String = row.get(i);
                            let parsed =
                                NaiveDateTime::parse_from_str(&v, "%Y-%m-%d %H:%M:%S").unwrap();
                            DataType::Timestamp(parsed.to_string())
                        }

time(string),
timestamp(string),
binary(list<u8>),
null
}

// allows parameterized queries
resource statement {
// e.g., create("SELECT * FROM users WHERE name = ? AND age = ?", vec!["John Doe", "32"])
prepare: func(query: string, params: list<string>) -> result<statement, sql-error>
}

// query is optimized for querying data, and
// implementors can make use of that fact to optimize
// the performance of query execution (e.g., using
// indexes).
query: func(q: statement) -> result<list<row>, sql-error>

// exec is for modifying data in the database.
exec: func(q: statement) -> result<_, sql-error>

// common error types
variant sql-error {
syntax-error(string),
constraint-violation(string),
access-violation(string),
unexpected-error(string)
}
}
```

## Worlds

```wit
world "wasi:sql/http-sql" {
import sql: "wasi:sql"

export handle-create: "wasi:http/handler"
export handle-read: "wasi:http/handler"
export handle-update: "wasi:http/handler"
export handle-delete: "wasi:http/handler"
}
```