Wire Protocols
>
Postgres

POSTGRES

The postgres protocol allows for using Postgres clients available for most programming languages.

Here's an example in Python using the psycopg client.

import psycopg

# Connect to Pogocache
conn = psycopg.connect("host=localhost port=9401")

# Insert some values
conn.execute("SET first Tom")
conn.execute("SET last Anderson")
conn.execute("SET age 37")
conn.execute("SET city %s", ["Phoenix"])

# Get the values back
print(conn.execute("GET first").fetchone()[0])
print(conn.execute("GET last").fetchone()[0])
print(conn.execute("GET age").fetchone()[0])
print(conn.execute("GET %s", ["city"]).fetchone()[0])

# Loop over multiple values
for row in conn.execute("MGET first last city"):
    print(row[0], row[1])

conn.close()

# Output:
# Tom
# Anderson
# 37
# first Tom
# last Anderson
# city Phoenix

Using psql

psql -h localhost -p 9401
=> SET first Tom;
=> SET last Anderson;
=> SET age 37;

Binary data with Postgres client

The default Postgres output format in Pogocache is ::text. This is generally the perferred format and allows for the most seamless text translations between client and server.

But occasionally storing binary is needed, such as with image, PDFs, or other special data formats. While Pogocache can transparently handle both text and binary, some client libraries may have problems convering text <-> binary due to strict type rules.

Pogocache provides the ::text and ::bytea command directives that will switch the output format for the client session.

While in ::bytea mode, it becomes the programmers responsibility to convert between binary and text.

import psycopg

conn = psycopg.connect("host=localhost port=9401")

conn.execute("SET name %s", ["Tom"])
conn.execute("SET binary %s", [b'\x00\x01\x02hello\xff'])

conn.execute("::bytea")
print(conn.execute("GET name").fetchone()[0])
print(conn.execute("GET binary").fetchone()[0])

conn.execute("::text")
print(conn.execute("GET name").fetchone()[0])

# Output:
# b'Tom'
# b'\x00\x01\x02hello\xff'
# Tom

Postgres parameterize queries

Parameterize queries are allowed with Pogocache. The example above shows how the psycopg uses the %s as a placeholder for a parameter. Other client may use the standard Postgres placeholders, such as $1, $2, $3.

For example, with the popular jackc/pgx client for Go:

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/jackc/pgx/v5"
)

func main() {
	// Connect to Pogocache
	url := "postgres://127.0.0.1:9401"
	conn, err := pgx.Connect(context.Background(), url)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to connect to cache: %v\n", err)
		os.Exit(1)
	}
	defer conn.Close(context.Background())

	conn.Exec(context.Background(), "SET $1 $2", "first", "Tom")
	row := conn.QueryRow(context.Background(), "GET $1", "first")

	var value string
	row.Scan(&value)
	println(value)

	userID := "1287"
	conn.Exec(context.Background(), "SET user:$1:first $2", userID, "Tom")
	conn.Exec(context.Background(), "SET user:$1:last $2", userID, "Anderson")
	conn.Exec(context.Background(), "SET user:$1:age $2", userID, "37")

	var first, last, age string

	conn.QueryRow(context.Background(), "GET user:$1:first", userID).Scan(&first)
	conn.QueryRow(context.Background(), "GET user:$1:last", userID).Scan(&last)
	conn.QueryRow(context.Background(), "GET user:$1:age", userID).Scan(&age)

	println(first)
	println(last)
	println(age)
}

// Output:
// Tom
// Tom
// Anderson
// 37