colinc86 / pgmodel

Package pgmodel provides a generalized way of working with Postgres rows.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

package pgmodel

Go Reference

Package pgmodel provides a generalized way of working with Postgres rows. Implementing the PGModel interface allows you to utilize the get, save, and delete functions without having to write repetitive query strings.

Turn this:

func (b *Bar) save(tx *pg.Tx) (orm.Result, error) {
  return tx.Query(b,
    `INSERT INTO foo.bars (id, name, date, value) 
    VALUES (?, ?, ?, ?) 
    ON CONFLICT (id) 
    DO UPDATE
    SET name = ?, date = ?, value = ? 
    WHERE bar.id = ?`, b.ID, b.Name, b.Date, b.Value, b.Name, b.Date, b.Value, b.ID)
}

In to this:

func (b *Bar) save(tx *pg.Tx) (orm.Result, error) {
  return pgmodel.Save(b, tx)
}

Install

$ go get github.com/colinc86/pgmodel

Example

To utilize the Get, GetMany, Save and Delete functions, you must implement the PGModel interface.

package example

import (
  "fmt"

  "github.com/go-pg/pg/v10"
  "github.com/go-pg/pg/v10/orm"
  "github.com/google/uuid"
)

type Bar struct {
  tableName struct{}  `pg:"bars"`
  ID        uuid.UUID `pg:"id,pk"`
  Name      string    `pg:"name"`
  Value     int       `pg:"value"`
  Values    []float64 `pg:"values,array"`
}

// PGModel interface methods

// PrimaryKey returns the model's primary key.
func (b Bar) PrimaryKey() string {
  return "id"
}

// PrimaryKeyValue returns the value of the model's primary key.
func (b Bar) PrimaryKeyValue() interface{} {
  return b.ID
}

// SchemaName returns the name of the model's schema.
func (b Bar) SchemaName() string {
  return "foo"
}

// TableName returns the name of the model's table.
func (b Bar) TableName() string {
  return "bars"
}

// ColumnCount returns the total number of columns in the table.
func (b Bar) ColumnCount() int {
  return 3
}

// NonPKColumns returns an array of non-primary key column names.
func (b Bar) NonPKColumns() []string {
  return []string{"name", "value"}
}

// NonPKValues returns an array of non-primary key values.
func (b Bar) NonPKValues() []interface{} {
  return []interface{}{b.Name, b.Value}
}

// Converts the model's slice from column, c, to a string value.
//
// This method's return value should be a stirng appropriate for a query. I.e.
// if the value in column c is the slice of floats, [0.1, 0.2, 0.3], then the
// method should return the string
//
//     {0.1, 0.2, 0.3}
//
// whereas if the value in c is the byte slice [0xA3, 0xA4, 0xA5], then the
// method should return
//
//     a3a4a5
func (b Bar) ConvertSlice(c string) string {
  var convertedValues []string
  if c == "values" {
    for _, v := range b.values {
      convertedValues = append(convertedValues, fmt.Sprintf("%f", v))
    }
  }

  return "{" + strings.Join(convertedValues, ",") + "}"
}

After implementing the PGModel interface, it is possible to write functions/methods such as...

// Save saves the bar.
func (b *Bar) Save(tx *pg.Tx) (orm.Result, error) {
  return pgmodel.Save(b, tx)
}

// Delete deletes the bar.
func (b *Bar) Delete(tx *pg.Tx) (orm.Result, error) {
  return pgmodel.Delete(b, tx)
}

// GetBar gets a bar from the db.
func GetBar(tx *pg.Tx, queryKey string, queryValue interface{}) (*Bar, error) {
  b := new(Bar)
  _, err := pgmodel.Get(b, tx, queryKey, queryValue)
  if err != nil {
    return nil, err
  }
  return b, nil
}

// GetBar gets bars from the db.
func GetBars(tx *pg.Tx, queryKey string, queryValue interface{}) ([]*Bar, error) {
  var b []*Bar
  _, err := pgmodel.GetMany(b, tx, queryKey, queryValue)
  if err != nil {
    return nil, err
  }
  return b, nil
}

About

Package pgmodel provides a generalized way of working with Postgres rows.

License:MIT License


Languages

Language:Go 100.0%