> ## Documentation Index
> Fetch the complete documentation index at: https://bunny.net/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Go

> Get started with Bunny Database and Go using the libSQL client

In this Go quickstart you will learn how to:

* Retrieve database credentials
* Install the libSQL client
* Connect to a remote Bunny Database
* Execute a query using SQL

## Quickstart

**1. Retrieve database credentials**

You will need an existing database to continue. If you don't have one, [create one](/docs/database/quickstart).

Navigate to **Dashboard > Edge Platform > Database > \[Select Database] > Access** to find your database URL and generate an access token.

> [!NOTE]
>
> You should store these as environment variables to keep them secure.

**2. Install libsql-client-go**

Install the libSQL client package:

```bash theme={null}
go get github.com/tursodatabase/libsql-client-go/libsql
```

**3. Initialize a new client**

Create a database connection with your database URL and auth token:

```go theme={null}
package main

import (
	"database/sql"
	"fmt"
	"os"

	_ "github.com/tursodatabase/libsql-client-go/libsql"
)

func main() {
	url := fmt.Sprintf("%s?authToken=%s",
		os.Getenv("BUNNY_DATABASE_URL"),
		os.Getenv("BUNNY_DATABASE_AUTH_TOKEN"),
	)

	db, err := sql.Open("libsql", url)
	if err != nil {
		fmt.Fprintf(os.Stderr, "failed to open db %s: %s", url, err)
		os.Exit(1)
	}
	defer db.Close()
}
```

**4. Execute a query using SQL**

You can execute a SQL query against your database using `Query()` for reads or `Exec()` for writes:

```go theme={null}
rows, err := db.Query("SELECT * FROM users")
if err != nil {
	fmt.Fprintf(os.Stderr, "failed to execute query: %v\n", err)
	os.Exit(1)
}
defer rows.Close()

for rows.Next() {
	var id int
	var name string
	if err := rows.Scan(&id, &name); err != nil {
		fmt.Fprintf(os.Stderr, "failed to scan row: %v\n", err)
		os.Exit(1)
	}
	fmt.Printf("id: %d, name: %s\n", id, name)
}

if err := rows.Err(); err != nil {
	fmt.Fprintf(os.Stderr, "error during iteration: %v\n", err)
	os.Exit(1)
}
```

If you need to use placeholders for values, you can do that:

```go Positional theme={null}
rows, err := db.Query("SELECT * FROM users WHERE id = ?", 1)
```

```go Named theme={null}
rows, err := db.Query("SELECT * FROM users WHERE id = :id", sql.Named("id", 1))
```

## Placeholders

libSQL supports the use of positional and named placeholders within SQL statements:

```go Positional theme={null}
rows, err := db.Query("SELECT * FROM users WHERE id = ?", 1)
```

```go Named theme={null}
rows, err := db.Query("SELECT * FROM users WHERE id = :id", sql.Named("id", 1))
```

> [!NOTE]
>
> libSQL supports the same named placeholder characters as SQLite — `:`, `@` and
> `$`.

## Executing Writes

Use `Exec()` for INSERT, UPDATE, and DELETE statements:

```go theme={null}
result, err := db.Exec("INSERT INTO users (name) VALUES (?)", "Kit")
if err != nil {
	fmt.Fprintf(os.Stderr, "failed to insert: %v\n", err)
	os.Exit(1)
}

rowsAffected, _ := result.RowsAffected()
lastInsertId, _ := result.LastInsertId()

fmt.Printf("rows affected: %d, last insert id: %d\n", rowsAffected, lastInsertId)
```

## Transactions

You can use transactions to execute multiple statements atomically:

```go theme={null}
tx, err := db.Begin()
if err != nil {
	fmt.Fprintf(os.Stderr, "failed to begin transaction: %v\n", err)
	os.Exit(1)
}

_, err = tx.Exec("INSERT INTO users (name) VALUES (?)", "Kit")
if err != nil {
	tx.Rollback()
	fmt.Fprintf(os.Stderr, "failed to insert: %v\n", err)
	os.Exit(1)
}

_, err = tx.Exec("INSERT INTO users (name) VALUES (?)", "Sam")
if err != nil {
	tx.Rollback()
	fmt.Fprintf(os.Stderr, "failed to insert: %v\n", err)
	os.Exit(1)
}

if err := tx.Commit(); err != nil {
	fmt.Fprintf(os.Stderr, "failed to commit: %v\n", err)
	os.Exit(1)
}
```

## Prepared Statements

For repeated queries, you can use prepared statements for better performance:

```go theme={null}
stmt, err := db.Prepare("SELECT * FROM users WHERE id = ?")
if err != nil {
	fmt.Fprintf(os.Stderr, "failed to prepare statement: %v\n", err)
	os.Exit(1)
}
defer stmt.Close()

rows, err := stmt.Query(1)
if err != nil {
	fmt.Fprintf(os.Stderr, "failed to execute query: %v\n", err)
	os.Exit(1)
}
defer rows.Close()
```

## Context Support

The libSQL client supports Go's context for timeout and cancellation:

```go theme={null}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

rows, err := db.QueryContext(ctx, "SELECT * FROM users")
if err != nil {
	fmt.Fprintf(os.Stderr, "failed to execute query: %v\n", err)
	os.Exit(1)
}
defer rows.Close()
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.