Skip to content

Commit

Permalink
feat: support pgwire (#213)
Browse files Browse the repository at this point in the history
* feat: support pgwire

* chore: publish 0.0.1

* chore: docs
  • Loading branch information
KKould authored Aug 11, 2024
1 parent a9e799e commit c8e9dd1
Show file tree
Hide file tree
Showing 8 changed files with 533 additions and 77 deletions.
41 changes: 27 additions & 14 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[package]
name = "fnck_sql"
version = "0.0.1-alpha.15"
edition = "2021"
authors = ["Kould <[email protected]>", "Xwg <[email protected]>"]
description = "SQL as a Function for Rust"
license = "Apache-2.0"
repository = "https://github.com/KipData/KipSQL"
readme = "README.md"
keywords = ["sql", "sqlite", "database", "mysql"]
categories = ["development-tools", "database"]
default-run = "fnck_sql"
name = "fnck_sql"
version = "0.0.2"
edition = "2021"
authors = ["Kould <[email protected]>", "Xwg <[email protected]>"]
description = "SQL as a Function for Rust"
documentation = "https://docs.rs/fnck_sql/latest/fnck_sql/"
license = "Apache-2.0"
repository = "https://github.com/KipData/KipSQL"
readme = "README.md"
keywords = ["sql", "sqlite", "database", "mysql"]
categories = ["development-tools", "database"]
default-run = "fnck_sql"

[[bin]]
name = "fnck_sql"
path = "src/bin/server.rs"
required-features = ["net"]

[lib]
doctest = false

[features]
default = ["marcos"]
marcos = []
net = ["dep:pgwire", "dep:async-trait", "dep:clap", "dep:env_logger", "dep:futures", "dep:log", "dep:tokio"]

[[bench]]
name = "query_bench"
Expand All @@ -27,35 +34,41 @@ harness = false

[dependencies]
ahash = { version = "0.8" }
async-trait = { version = "0.1", optional = true }
bincode = { version = "1" }
bytes = { version = "1" }
chrono = { version = "0.4" }
clap = { version = "4" }
clap = { version = "4.5", features = ["derive"], optional = true }
comfy-table = { version = "7" }
csv = { version = "1" }
dirs = { version = "5" }
env_logger = { version = "0.11", optional = true }
futures = { version = "0.3", optional = true }
integer-encoding = { version = "3" }
itertools = { version = "0.12" }
lazy_static = { version = "1" }
log = { version = "0.4", optional = true }
ordered-float = { version = "4" }
paste = { version = "1" }
parking_lot = { version = "0.12", features = ["arc_lock"] }
petgraph = { version = "0.6" }
pgwire = { version = "0.19", optional = true }
rand = { version = "0.9.0-alpha" }
regex = { version = "1" }
rocksdb = { git = "https://github.com/rust-rocksdb/rust-rocksdb", rev = "1cf906dc4087f06631820f13855e6b27bd21b972" }
rocksdb = { version = "0.22.0" }
rust_decimal = { version = "1" }
serde = { version = "1", features = ["derive", "rc"] }
siphasher = { version = "1", features = ["serde"] }
sqlparser = { version = "0.34", features = ["serde"] }
strum_macros = { version = "0.26.2" }
thiserror = { version = "1" }
tokio = { version = "1.36", features = ["full"], optional = true }
tracing = { version = "0.1" }
typetag = { version = "0.2" }

[dev-dependencies]
cargo-tarpaulin = { version = "0.27" }
criterion = { version = "0.5", features = ["async_tokio", "html_reports"] }
criterion = { version = "0.5", features = ["html_reports"] }
indicatif = { version = "0.17" }
rand_distr = { version = "0.4" }
tempfile = { version = "3.10" }
Expand Down
41 changes: 34 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Built by @KipData
<p align="center">
<a href="https://github.com/KipData/KipSQL/actions/workflows/ci.yml"><img src="https://github.com/KipData/KipSQL/actions/workflows/ci.yml/badge.svg" alt="CI"></img></a>
<a href="https://crates.io/crates/fnck_sql/"><img src="https://img.shields.io/crates/v/fnck_sql.svg"></a>
<a href="https://hub.docker.com/r/kould23333/fncksql"><img src="https://img.shields.io/badge/Docker-fncksql-2496ED?logo=docker"></a>
</p>
<p align="center">
<a href="https://github.com/KipData/KipSQL" target="_blank">
Expand All @@ -35,9 +36,10 @@ Built by @KipData

### What is FnckSQL

FnckSQL individual developers independently implemented LSM KV-based SQL DBMS out of hobby. This SQL database will prove to you that anyone can write a database (even the core author cannot find a job). If you are also a database-related Enthusiastic, let us give this "beautiful" industry a middle finger🖕.

Welcome to our WebSite, Power By FnckSQL: **http://www.kipdata.site/**
FnckSQL is a high-performance SQL database
that can be embedded in Rust code (based on RocksDB by default),
making it possible to call SQL just like calling a function.
It supports most of the syntax of SQL 2016.

### Quick Started
Tips: Install rust toolchain and llvm first.
Expand All @@ -46,23 +48,48 @@ Clone the repository
``` shell
git clone https://github.com/KipData/FnckSQL.git
```

Using FnckSQL in code
#### Using FnckSQL in code
```rust
let fnck_sql = DataBaseBuilder::path("./data")
.build()?;
let fnck_sql = DataBaseBuilder::path("./data").build()?;
let tuples = fnck_sql.run("select * from t1")?;
```

#### PG Wire Service
run `cargo run --features="net"` to start server
![start](./static/images/start.gif)
then use `psql` to enter sql
![pg](./static/images/pg.gif)

Storage Support:
- RocksDB

### Docker
#### Pull Image
```shell
docker pull kould23333/fncksql:latest
```
#### Build From Source
~~~shell
git clone https://github.com/KipData/FnckSQL.git
cd FnckSQL
docker build -t kould23333/fncksql:latest .
~~~

#### Run
We installed the `psql` tool in the image for easy debug.

You can use `psql -h 127.0.0.1 -p 5432` to do this.

~~~shell
docker run -d \
--name=fncksql \
-p 5432:5432 \
--restart=always \
-v fncksql-data:/fnck_sql/fncksql_data \
-v /etc/localtime:/etc/localtime:ro \
kould23333/fncksql:latest
~~~

### Features
- ORM Mapping: `features = ["marcos"]`
```rust
Expand Down
61 changes: 24 additions & 37 deletions benchmarks/query_benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,24 @@ fn query_cases() -> Vec<(&'static str, &'static str)> {
]
}

async fn init_fncksql_query_bench() -> Result<(), DatabaseError> {
fn init_fncksql_query_bench() -> Result<(), DatabaseError> {
let database = DataBaseBuilder::path(QUERY_BENCH_FNCK_SQL_PATH)
.build()
.await
.unwrap();
database
.run("create table t1 (c1 int primary key, c2 int)")
.await?;
database.run("create table t1 (c1 int primary key, c2 int)")?;
let pb = ProgressBar::new(TABLE_ROW_NUM);
pb.set_style(
ProgressStyle::default_bar()
.template("[{elapsed_precise}] {bar:40.cyan/white} {pos}/{len} {msg}")
.unwrap(),
);
for i in 0..TABLE_ROW_NUM {
let _ = database
.run(format!("insert into t1 values({}, {})", i, i + 1).as_str())
.await?;
let _ = database.run(format!("insert into t1 values({}, {})", i, i + 1).as_str())?;
pb.set_position(i + 1);
}
pb.finish_with_message("Insert completed!");

let _ = database.run("analyze table t1").await?;
let _ = database.run("analyze table t1")?;

Ok(())
}
Expand Down Expand Up @@ -79,45 +74,37 @@ fn path_exists_and_is_directory(path: &str) -> bool {
}

fn query_on_execute(c: &mut Criterion) {
let rt = tokio::runtime::Builder::new_multi_thread()
.worker_threads(8)
.enable_all()
if !Path::new(QUERY_BENCH_SQLITE_PATH).exists() {
println!(
"SQLITE: The table is not initialized and data insertion is started. => {}",
TABLE_ROW_NUM
);

init_sqlite_query_bench().unwrap();
}
if !path_exists_and_is_directory(QUERY_BENCH_FNCK_SQL_PATH) {
println!(
"FnckSQL: The table is not initialized and data insertion is started. => {}",
TABLE_ROW_NUM
);

init_fncksql_query_bench().unwrap();
}
let database = DataBaseBuilder::path(QUERY_BENCH_FNCK_SQL_PATH)
.build()
.unwrap();
let database = rt.block_on(async {
if !Path::new(QUERY_BENCH_SQLITE_PATH).exists() {
println!(
"SQLITE: The table is not initialized and data insertion is started. => {}",
TABLE_ROW_NUM
);

init_sqlite_query_bench().unwrap();
}
if !path_exists_and_is_directory(QUERY_BENCH_FNCK_SQL_PATH) {
println!(
"FnckSQL: The table is not initialized and data insertion is started. => {}",
TABLE_ROW_NUM
);

init_fncksql_query_bench().await.unwrap();
}
DataBaseBuilder::path(QUERY_BENCH_FNCK_SQL_PATH)
.build()
.await
.unwrap()
});
println!("Table initialization completed");

for (name, case) in query_cases() {
c.bench_function(format!("FnckSQL: {} by '{}'", name, case).as_str(), |b| {
b.to_async(&rt).iter(|| async {
let _tuples = database.run(case).await.unwrap();
b.iter(|| {
let _tuples = database.run(case).unwrap();
})
});

let connection = sqlite::open(QUERY_BENCH_SQLITE_PATH.to_owned()).unwrap();
c.bench_function(format!("SQLite: {} by '{}'", name, case).as_str(), |b| {
b.to_async(&rt).iter(|| async {
b.iter(|| {
let _tuples = connection
.prepare(case)
.unwrap()
Expand Down
Loading

0 comments on commit c8e9dd1

Please sign in to comment.