func (kv *KeyValue) Set(key, value string) error {
	if !kv.host.rawUTF8 {
		Encode(&value)
	}
	if _, err := kv.Get(key); err != nil {
		_, err = kv.host.db.Exec("INSERT INTO "+kv.table+" ("+keyCol+", "+valCol+") VALUES (?, ?)", key, value)
		return err
	}
	_, err := kv.host.db.Exec("UPDATE "+kv.table+" SET "+valCol+" = ? WHERE "+keyCol+" = ?", value, key)
	return err
}
Set a key and value
package simplemaria
import (
	"database/sql"
	"errors"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"log"
	"strconv"
	"strings"
)
const (
	Version = 3.2
)
type Host struct {
	db      *sql.DB
	dbname  string
	rawUTF8 bool
}
type dbDatastructure struct {
	host  *Host
	table string
}
type (
	List     dbDatastructure
	Set      dbDatastructure
	HashMap  dbDatastructure
	KeyValue dbDatastructure
)
const (
	defaultDatabaseServer = ""      
	defaultDatabaseName   = "test"  
	defaultStringType     = "TEXT"  
	defaultPort           = 3306
	charset = "utf8mb4"  
	listCol  = "a_list"
	setCol   = "a_set"
	keyCol   = "property"
	valCol   = "value"
	ownerCol = "owner"
)
func TestConnection() (err error) {
	return TestConnectionHost(defaultDatabaseServer)
}
func TestConnectionHost(connectionString string) (err error) {
	newConnectionString, _ := rebuildConnectionString(connectionString)
	db, err := sql.Open("mysql", newConnectionString)
	if err != nil {
		return err
	}
	defer db.Close()
	err = db.Ping()
	if Verbose {
		if err != nil {
			log.Println("Ping: failed")
		} else {
			log.Println("Ping: ok")
		}
	}
	return err
}
func TestConnectionHostWithDSN(connectionString string) (err error) {
	db, err := sql.Open("mysql", connectionString)
	if err != nil {
		return err
	}
	defer db.Close()
	err = db.Ping()
	if Verbose {
		if err != nil {
			log.Println("Ping: failed")
		} else {
			log.Println("Ping: ok")
		}
	}
	return err
}
func NewHost(connectionString string) *Host {
	newConnectionString, dbname := rebuildConnectionString(connectionString)
	db, err := sql.Open("mysql", newConnectionString)
	if err != nil {
		log.Fatalln("Could not connect to " + newConnectionString + "!")
	}
	host := &Host{db, dbname, false}
	if err := host.Ping(); err != nil {
		log.Fatalln("Host does not reply to ping: " + err.Error())
	}
	if err := host.createDatabase(); err != nil {
		log.Fatalln("Could not create database " + host.dbname + ": " + err.Error())
	}
	if err := host.useDatabase(); err != nil {
		panic("Could not use database " + host.dbname + ": " + err.Error())
	}
	return host
}
func NewHostWithDSN(connectionString string, dbname string) *Host {
	db, err := sql.Open("mysql", connectionString)
	if err != nil {
		log.Fatalln("Could not connect to " + connectionString + "!")
	}
	host := &Host{db, dbname, false}
	if err := host.Ping(); err != nil {
		log.Fatalln("Host does not reply to ping: " + err.Error())
	}
	if err := host.createDatabase(); err != nil {
		log.Fatalln("Could not create database " + host.dbname + ": " + err.Error())
	}
	if err := host.useDatabase(); err != nil {
		panic("Could not use database " + host.dbname + ": " + err.Error())
	}
	return host
}
func New() *Host {
	connectionString := defaultDatabaseServer + defaultDatabaseName
	if !strings.HasSuffix(defaultDatabaseServer, "/") {
		connectionString = defaultDatabaseServer + "/" + defaultDatabaseName
	}
	return NewHost(connectionString)
}
func (host *Host) SetRawUTF8(enabled bool) {
	host.rawUTF8 = enabled
}
func (host *Host) SelectDatabase(dbname string) error {
	host.dbname = dbname
	if err := host.createDatabase(); err != nil {
		return err
	}
	if err := host.useDatabase(); err != nil {
		return err
	}
	return nil
}
func (host *Host) createDatabase() error {
	if _, err := host.db.Exec("CREATE DATABASE IF NOT EXISTS " + host.dbname + " CHARACTER SET = " + charset); err != nil {
		return err
	}
	if Verbose {
		log.Println("Created database " + host.dbname)
	}
	return nil
}
func (host *Host) useDatabase() error {
	if _, err := host.db.Exec("USE " + host.dbname); err != nil {
		return err
	}
	if Verbose {
		log.Println("Using database " + host.dbname)
	}
	return nil
}
func (host *Host) Close() {
	host.db.Close()
}
func (host *Host) Ping() error {
	return host.db.Ping()
}
func NewList(host *Host, name string) (*List, error) {
	l := &List{host, name}
	if _, err := l.host.db.Exec("CREATE TABLE IF NOT EXISTS " + name + " (id INT PRIMARY KEY AUTO_INCREMENT, " + listCol + " " + defaultStringType + ")"); err != nil {
		return nil, err
	}
	if Verbose {
		log.Println("Created table " + name + " in database " + host.dbname)
	}
	return l, nil
}
func (l *List) Add(value string) error {
	if !l.host.rawUTF8 {
		Encode(&value)
	}
	_, err := l.host.db.Exec("INSERT INTO "+l.table+" ("+listCol+") VALUES (?)", value)
	return err
}
func (l *List) All() ([]string, error) {
	rows, err := l.host.db.Query("SELECT " + listCol + " FROM " + l.table + " ORDER BY id")
	if err != nil {
		return []string{}, err
	}
	defer rows.Close()
	var (
		values []string
		value  string
	)
	for rows.Next() {
		err = rows.Scan(&value)
		if !l.host.rawUTF8 {
			Decode(&value)
		}
		values = append(values, value)
		if err != nil {
			panic(err.Error())
		}
	}
	if err := rows.Err(); err != nil {
		panic(err.Error())
	}
	return values, nil
}
func (l *List) GetAll() ([]string, error) {
	return l.All()
}
func (l *List) Last() (string, error) {
	rows, err := l.host.db.Query("SELECT " + listCol + " FROM " + l.table + " WHERE id = (SELECT MAX(id) FROM " + l.table + ")")
	if err != nil {
		return "", err
	}
	defer rows.Close()
	var value string
	for rows.Next() {
		err = rows.Scan(&value)
		if err != nil {
			panic(err.Error())
		}
	}
	if err := rows.Err(); err != nil {
		panic(err.Error())
	}
	if !l.host.rawUTF8 {
		Decode(&value)
	}
	return value, nil
}
func (l *List) GetLast() (string, error) {
	return l.Last()
}
func (l *List) LastN(n int) ([]string, error) {
	rows, err := l.host.db.Query("SELECT " + listCol + " FROM (SELECT * FROM " + l.table + " ORDER BY id DESC limit " + strconv.Itoa(n) + ")sub ORDER BY id ASC")
	if err != nil {
		return []string{}, err
	}
	defer rows.Close()
	var (
		values []string
		value  string
	)
	for rows.Next() {
		err = rows.Scan(&value)
		if !l.host.rawUTF8 {
			Decode(&value)
		}
		values = append(values, value)
		if err != nil {
			panic(err.Error())
		}
	}
	if err := rows.Err(); err != nil {
		panic(err.Error())
	}
	if len(values) < n {
		return []string{}, errors.New("Too few elements in table at GetLastN")
	}
	return values, nil
}
func (l *List) GetLastN(n int) ([]string, error) {
	return l.LastN(n)
}
func (l *List) Remove() error {
	_, err := l.host.db.Exec("DROP TABLE " + l.table)
	return err
}
func (l *List) Clear() error {
	_, err := l.host.db.Exec("TRUNCATE TABLE " + l.table)
	return err
}
func NewSet(host *Host, name string) (*Set, error) {
	s := &Set{host, name}
	if _, err := s.host.db.Exec("CREATE TABLE IF NOT EXISTS " + name + " (" + setCol + " " + defaultStringType + ")"); err != nil {
		return nil, err
	}
	if Verbose {
		log.Println("Created table " + name + " in database " + host.dbname)
	}
	return s, nil
}
func (s *Set) Add(value string) error {
	originalValue := value
	if !s.host.rawUTF8 {
		Encode(&value)
	}
	has, err := s.Has(originalValue)
	if !has && (err == nil) {
		_, err = s.host.db.Exec("INSERT INTO "+s.table+" ("+setCol+") VALUES (?)", value)
	}
	return err
}
func (s *Set) Has(value string) (bool, error) {
	if !s.host.rawUTF8 {
		Encode(&value)
	}
	rows, err := s.host.db.Query("SELECT "+setCol+" FROM "+s.table+" WHERE "+setCol+" = ?", value)
	if err != nil {
		return false, err
	}
	defer rows.Close()
	var scanValue string
	counter := 0
	for rows.Next() {
		err = rows.Scan(&scanValue)
		if err != nil {
			panic(err.Error())
		}
		counter++
	}
	if err := rows.Err(); err != nil {
		panic(err.Error())
	}
	if counter > 1 {
		panic("Duplicate members in set! " + value)
	}
	return counter > 0, nil
}
func (s *Set) All() ([]string, error) {
	rows, err := s.host.db.Query("SELECT " + setCol + " FROM " + s.table)
	if err != nil {
		return []string{}, err
	}
	defer rows.Close()
	var (
		values []string
		value  string
	)
	for rows.Next() {
		err = rows.Scan(&value)
		if !s.host.rawUTF8 {
			Decode(&value)
		}
		values = append(values, value)
		if err != nil {
			panic(err.Error())
		}
	}
	if err := rows.Err(); err != nil {
		panic(err.Error())
	}
	return values, nil
}
func (s *Set) GetAll() ([]string, error) {
	return s.All()
}
func (s *Set) Del(value string) error {
	if !s.host.rawUTF8 {
		Encode(&value)
	}
	_, err := s.host.db.Exec("DELETE FROM "+s.table+" WHERE "+setCol+" = ?", value)
	return err
}
func (s *Set) Remove() error {
	_, err := s.host.db.Exec("DROP TABLE " + s.table)
	return err
}
func (s *Set) Clear() error {
	_, err := s.host.db.Exec("TRUNCATE TABLE " + s.table)
	return err
}
func NewHashMap(host *Host, name string) (*HashMap, error) {
	h := &HashMap{host, name}
	query := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s (%s %s, %s %s, %s %s)", name, ownerCol, defaultStringType, keyCol, defaultStringType, valCol, defaultStringType)
	if _, err := h.host.db.Exec(query); err != nil {
		return nil, err
	}
	if Verbose {
		log.Println("Created table " + name + " in database " + host.dbname)
	}
	return h, nil
}
func (h *HashMap) Set(owner, key, value string) error {
	if !h.host.rawUTF8 {
		Encode(&value)
	}
	ok, err := h.Has(owner, key)
	if err != nil {
		return err
	}
	if Verbose {
		log.Printf("%s/%s exists? %v\n", owner, key, ok)
	}
	if ok {
		_, err = h.host.db.Exec("UPDATE "+h.table+" SET "+valCol+" = ? WHERE "+ownerCol+" = ? AND "+keyCol+" = ?", value, owner, key)
		if Verbose {
			log.Println("Updated the table: " + h.table)
		}
	} else {
		_, err = h.host.db.Exec("INSERT INTO "+h.table+" ("+ownerCol+", "+keyCol+", "+valCol+") VALUES (?, ?, ?)", owner, key, value)
		if Verbose {
			log.Println("Added to the table: " + h.table)
		}
	}
	return err
}
func (h *HashMap) Get(owner, key string) (string, error) {
	rows, err := h.host.db.Query("SELECT "+valCol+" FROM "+h.table+" WHERE "+ownerCol+" = ? AND "+keyCol+" = ?", owner, key)
	if err != nil {
		return "", err
	}
	defer rows.Close()
	var value string
	counter := 0
	for rows.Next() {
		err = rows.Scan(&value)
		if err != nil {
			panic(err.Error())
		}
		counter++
	}
	if err := rows.Err(); err != nil {
		panic(err.Error())
	}
	if counter == 0 {
		return "", errors.New("No such owner/key: " + owner + "/" + key)
	}
	if !h.host.rawUTF8 {
		Decode(&value)
	}
	return value, nil
}
func (h *HashMap) Has(owner, key string) (bool, error) {
	rows, err := h.host.db.Query("SELECT "+valCol+" FROM "+h.table+" WHERE "+ownerCol+" = ? AND "+keyCol+" = ?", owner, key)
	if err != nil {
		return false, err
	}
	defer rows.Close()
	var value string
	counter := 0
	for rows.Next() {
		err = rows.Scan(&value)
		if err != nil {
			panic(err.Error())
		}
		counter++
	}
	if err := rows.Err(); err != nil {
		panic(err.Error())
	}
	if counter > 1 {
		panic("Duplicate keys in hash map! " + value)
	}
	return counter > 0, nil
}
func (h *HashMap) Exists(owner string) (bool, error) {
	rows, err := h.host.db.Query("SELECT "+valCol+" FROM "+h.table+" WHERE "+ownerCol+" = ?", owner)
	if err != nil {
		return false, err
	}
	defer rows.Close()
	var value string
	counter := 0
	for rows.Next() {
		err = rows.Scan(&value)
		if err != nil {
			panic(err.Error())
		}
		counter++
	}
	if err := rows.Err(); err != nil {
		panic(err.Error())
	}
	return counter > 0, nil
}
func (h *HashMap) All() ([]string, error) {
	rows, err := h.host.db.Query("SELECT " + ownerCol + " FROM " + h.table)
	if err != nil {
		return []string{}, err
	}
	defer rows.Close()
	var (
		values []string
		value  string
	)
	for rows.Next() {
		err = rows.Scan(&value)
		values = append(values, value)
		if err != nil {
			panic(err.Error())
		}
	}
	if err := rows.Err(); err != nil {
		panic(err.Error())
	}
	return values, nil
}
func (h *HashMap) GetAll() ([]string, error) {
	return h.All()
}
func (h *HashMap) Keys(owner string) ([]string, error) {
	rows, err := h.host.db.Query("SELECT "+keyCol+" FROM "+h.table+" WHERE "+ownerCol+"= ?", owner)
	if err != nil {
		return []string{}, err
	}
	defer rows.Close()
	var (
		values []string
		value  string
	)
	for rows.Next() {
		err = rows.Scan(&value)
		values = append(values, value)
		if err != nil {
			panic(err.Error())
		}
	}
	if err := rows.Err(); err != nil {
		panic(err.Error())
	}
	return values, nil
}
func (h *HashMap) DelKey(owner, key string) error {
	_, err := h.host.db.Exec("DELETE FROM "+h.table+" WHERE "+ownerCol+" = ? AND "+keyCol+" = ?", owner, key)
	return err
}
func (h *HashMap) Del(owner string) error {
	results, err := h.host.db.Exec("DELETE FROM "+h.table+" WHERE "+ownerCol+" = ?", owner)
	if err != nil {
		return err
	}
	n, err := results.RowsAffected()
	if err != nil {
		return err
	}
	if Verbose {
		log.Println(n, "rows were deleted with Del("+owner+")!")
	}
	return nil
}
func (h *HashMap) Remove() error {
	_, err := h.host.db.Exec("DROP TABLE " + h.table)
	return err
}
func (h *HashMap) Clear() error {
	_, err := h.host.db.Exec("TRUNCATE TABLE " + h.table)
	return err
}
func NewKeyValue(host *Host, name string) (*KeyValue, error) {
	kv := &KeyValue{host, name}
	query := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s (%s %s, %s %s)", name, keyCol, defaultStringType, valCol, defaultStringType)
	if _, err := kv.host.db.Exec(query); err != nil {
		return nil, err
	}
	if Verbose {
		log.Println("Created table " + name + " in database " + host.dbname)
	}
	return kv, nil
}