From fec361f664d62e293c01eb0b5738630691bd06bb Mon Sep 17 00:00:00 2001 From: James Dong Date: Mon, 14 Sep 2020 14:26:39 +0000 Subject: [PATCH] Add Golang SQLite demo --- demos/golang/go_sqlite/.gitignore | 2 + demos/golang/go_sqlite/README.md | 10 ++ demos/golang/go_sqlite/run_go_sqlite_demo.sh | 31 ++++ demos/golang/go_sqlite/simple_demo.go | 162 +++++++++++++++++++ 4 files changed, 205 insertions(+) create mode 100644 demos/golang/go_sqlite/.gitignore create mode 100644 demos/golang/go_sqlite/README.md create mode 100755 demos/golang/go_sqlite/run_go_sqlite_demo.sh create mode 100644 demos/golang/go_sqlite/simple_demo.go diff --git a/demos/golang/go_sqlite/.gitignore b/demos/golang/go_sqlite/.gitignore new file mode 100644 index 00000000..bffb487f --- /dev/null +++ b/demos/golang/go_sqlite/.gitignore @@ -0,0 +1,2 @@ +simple_demo +simple_demo_instance/ diff --git a/demos/golang/go_sqlite/README.md b/demos/golang/go_sqlite/README.md new file mode 100644 index 00000000..2f46d5d9 --- /dev/null +++ b/demos/golang/go_sqlite/README.md @@ -0,0 +1,10 @@ +# Use Golang and SQLite with Occlum + +This project demonstrates how Occlum enables [Golang](https://golang.org) programs with [SQLite](https://www.sqlite.org/index.html) library calls running in SGX enclaves. The way to use a SQL (or SQL-like) database in Go is through the [database/sql](https://golang.org/pkg/database/sql/) package. The SQL package exposes an ideal set of generic APIs for a variety of SQL or SQL-like databases. The SQL package itself must be used in conjunction with a [database driver](https://github.com/golang/go/wiki/SQLDrivers) package. + +The demo program is based on a widely used [sqlite3 driver](https://github.com/mattn/go-sqlite3) conforming to the built-in database/sql interface and passing the compatibility test suite at [https://github.com/bradfitz/go-sql-test](https://github.com/bradfitz/go-sql-test). You can run the Golang SQLite demo on Occlum via +``` +./run_go_sqlite_demo.sh +``` + +The demo program adds a database source file golang_sql_driver.db, creates a table SqlDrivers, inserts a list of Golang SQL database driver records, queries all records, and prints them out. diff --git a/demos/golang/go_sqlite/run_go_sqlite_demo.sh b/demos/golang/go_sqlite/run_go_sqlite_demo.sh new file mode 100755 index 00000000..1076e397 --- /dev/null +++ b/demos/golang/go_sqlite/run_go_sqlite_demo.sh @@ -0,0 +1,31 @@ +#!/bin/bash +set -e + +BLUE='\033[1;34m' +NC='\033[0m' + +# Install SQLite with occlum-go +occlum-go get -u -v github.com/mattn/go-sqlite3 + +# Build the Golang SQLite demo program using the Occlum Golang toolchain (i.e., occlum-go) +occlum-go build -o simple_demo simple_demo.go + +# Init Occlum Workspace +rm -rf simple_demo_instance && mkdir simple_demo_instance +cd simple_demo_instance +occlum init +new_json="$(jq '.resource_limits.user_space_size = "2560MB" | + .resource_limits.kernel_space_heap_size="320MB" | + .resource_limits.kernel_space_stack_size="10MB" | + .process.default_stack_size = "40MB" | + .process.default_heap_size = "320MB" | + .process.default_mmap_size = "960MB" ' Occlum.json)" && \ +echo "${new_json}" > Occlum.json + +# Copy program into Occlum Workspace and build +cp ../simple_demo image/bin +occlum build + +# Run the Golang SQLite demo +echo -e "${BLUE}occlum run /bin/simple_demo${NC}" +time occlum run /bin/simple_demo diff --git a/demos/golang/go_sqlite/simple_demo.go b/demos/golang/go_sqlite/simple_demo.go new file mode 100644 index 00000000..c86c9236 --- /dev/null +++ b/demos/golang/go_sqlite/simple_demo.go @@ -0,0 +1,162 @@ +package main + +import ( + "database/sql" + "fmt" + _ "github.com/mattn/go-sqlite3" + "os" + "time" +) + +type GolangDbDriver struct { + dbName string + pkgLink string + testSuite string +} + +var DbDriverList = []GolangDbDriver { + GolangDbDriver { + dbName: "Apache Ignite/GridGain", + pkgLink: "https://github.com/amsokol/ignite-go-client", + testSuite: "Unknown", + }, + GolangDbDriver { + dbName: "Amazon AWS Athena", + pkgLink: "https://github.com/uber/athenadriver", + testSuite: "Unknown", + }, + GolangDbDriver { + dbName: "Google Cloud Spanner", + pkgLink: "https://github.com/rakyll/go-sql-driver-spanner", + testSuite: "Unknown", + }, + GolangDbDriver { + dbName: "MS SQL Server (pure go)", + pkgLink: "https://github.com/denisenkom/go-mssqldb", + testSuite: "Unknown", + }, + GolangDbDriver { + dbName: "MySQL", + pkgLink: "https://github.com/go-sql-driver/mysql/", + testSuite: "pass the compatibility test suite at https://github.com/bradfitz/go-sql-test", + }, + GolangDbDriver { + dbName: "MySQL", + pkgLink: "https://github.com/siddontang/go-mysql/", + testSuite: "pass the compatibility test suite but are not currently included in it", + }, + GolangDbDriver { + dbName: "Oracle (uses cgo)", + pkgLink: "https://github.com/mattn/go-oci8", + testSuite: "Unknown", + }, + GolangDbDriver { + dbName: "Postgres (pure Go)", + pkgLink: "https://github.com/lib/pq", + testSuite: "pass the compatibility test suite at https://github.com/bradfitz/go-sql-test", + }, + GolangDbDriver { + dbName: "Postgres (uses cgo)", + pkgLink: "https://github.com/jbarham/gopgsqldriver", + testSuite: "Unknown", + }, + GolangDbDriver { + dbName: "Snowflake (pure Go)", + pkgLink: "https://github.com/snowflakedb/gosnowflake", + testSuite: "Unknown", + }, + GolangDbDriver { + dbName: "SQLite (uses cgo)", + pkgLink: "https://github.com/mattn/go-sqlite3", + testSuite: "pass the compatibility test suite at https://github.com/bradfitz/go-sql-test", + }, + GolangDbDriver { + dbName: "SQLite (uses cgo)", + pkgLink: "https://github.com/gwenn/gosqlite", + testSuite: "Unknown", + }, + GolangDbDriver { + dbName: "Apache Hive", + pkgLink: "https://github.com/sql-machine-learning/gohive", + testSuite: "Unknown", + }, +} + +func main() { + previousTime := time.Now() + fmt.Printf("Starting the Golang SQLite demo: at %s\n", previousTime.Format("2006-01-02T15:04:05.999999999Z07:00")) + + dbSourceName := "golang_sql_driver.db" + os.Remove(dbSourceName) + + dbDriverName := "sqlite3" + db, err := sql.Open(dbDriverName, dbSourceName) + if err != nil { + fmt.Println("Failed to open the database:", err) + } + defer db.Close() + + if err = db.Ping(); err != nil { + fmt.Println("Failed to establish a connection to the database:", err) + } + + tx, err := db.Begin() + if err != nil { + fmt.Println("Failed to start a database transaction:", err) + } + + sqlStatement := ` + create table if not exists SqlDrivers (dbName varchar(255), pkgLink varchar(255), testSuite varchar(255)); + delete from SqlDrivers; + ` + _, err = db.Exec(sqlStatement) + if err != nil { + fmt.Println("Failed to create table:", sqlStatement, err) + return + } + + statement, err := tx.Prepare("insert into SqlDrivers(dbName, pkgLink, testSuite) values(?, ?, ?)") + if err != nil { + fmt.Println("Failed to prepare SQL statements:", err) + } + defer statement.Close() + for _, entry := range DbDriverList { + _, err = statement.Exec(entry.dbName, entry.pkgLink, entry.testSuite) + if err != nil { + fmt.Println("Failed to prepare SQL statements:", err) + } + } + + tx.Commit() + + rows, err := db.Query("select dbName, pkgLink, testSuite from SqlDrivers") + if err != nil { + fmt.Println("Failed to query the database:", err) + } + defer rows.Close() + for rows.Next() { + var dbName sql.NullString + var pkgLink sql.NullString + var testSuite sql.NullString + err = rows.Scan(&dbName, &pkgLink, &testSuite) + if err != nil { + fmt.Println("Failed to Scan the query results:", err) + } + fmt.Printf("dbName=%v;\n pkgLink=%v;\n testSuite=%v\n", dbName.String, pkgLink.String, testSuite.String) + } + err = rows.Err() + if err != nil { + fmt.Println("Error was encountered during query result iteration:", err) + } + + _, err = db.Exec("delete from SqlDrivers") + if err != nil { + fmt.Println("Failed to delete all records in the database:", err) + } + + currentTime := time.Now() + fmt.Printf("Total running time: %f Seconds\n", currentTime.Sub(previousTime).Seconds()) + + os.Remove(dbSourceName) +} +