model

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2022 License: MIT Imports: 7 Imported by: 0

README

Basic model generator

Use model sub-command to execute generator:

bungen model -h

First create your database and tables in it

create table "projects"
(
    "projectId" serial not null,
    "name"      text   not null,

    primary key ("projectId")
);

create table "users"
(
    "userId"    serial      not null,
    "email"     varchar(64) not null,
    "activated" bool        not null default false,
    "name"      varchar(128),
    "countryId" integer,

    primary key ("userId")
);

create schema "geo";
create table geo."countries"
(
    "countryId" serial     not null,
    "code"      varchar(3) not null,
    "coords"    integer[],

    primary key ("countryId")
);

alter table "users"
    add constraint "fk_user_country"
        foreign key ("countryId")
            references geo."countries" ("countryId") on update restrict on delete restrict;

Run generator

bungen model -c postgres://user:password@localhost:5432/yourdb -o ~/output/model.go -t public.* -f

You should get following models on model package:

//lint:file-ignore U1000 ignore unused code, it's generated
package model

var Columns = struct { 
	Project struct{ 
		ID, Name string
	}
	User struct{ 
		ID, Email, Activated, Name, CountryID string

		Country string
	}
	GeoCountry struct{ 
		ID, Code, Coords string
	}
}{ 
	Project: struct { 
		ID, Name string
	}{ 
		ID: "projectId",
		Name: "name",
	},
	User: struct { 
		ID, Email, Activated, Name, CountryID string

		Country string
	}{ 
		ID: "userId",
		Email: "email",
		Activated: "activated",
		Name: "name",
		CountryID: "countryId",
		
		Country: "Country",
	},
	GeoCountry: struct { 
		ID, Code, Coords string
	}{ 
		ID: "countryId",
		Code: "code",
		Coords: "coords",
	},
}

var Tables = struct { 
	Project struct {
		Name, Alias string
	}
	User struct {
		Name, Alias string
	}
	GeoCountry struct {
		Name, Alias string
	}
}{ 
	Project: struct {
		Name, Alias string
	}{ 
		Name: "projects",
		Alias: "t",
	},
	User: struct {
		Name, Alias string
	}{ 
		Name: "users",
		Alias: "t",
	},
	GeoCountry: struct {
		Name, Alias string
	}{ 
		Name: "geo.countries",
		Alias: "t",
	},
}

type Project struct {
	bun.BaseModel `bun:"projects,alias:t"`
	
	ID int `bun:"projectId,pk"` 
	Name string `bun:"name,nullzero"` 
}

type User struct {
	bun.BaseModel `bun:"users,alias:t"`
	
	ID int `bun:"userId,pk"` 
	Email string `bun:"email,nullzero"` 
	Activated bool `bun:"activated,nullzero"` 
	Name *string `bun:"name"` 
	CountryID *int `bun:"countryId"` 
	
	Country *GeoCountry `bun:"join:countryId=countryId,rel:belongs-to"` 
}

type GeoCountry struct {
	bun.BaseModel `bun:"geo.countries,alias:t"`
	
	ID int `bun:"countryId,pk"` 
	Code string `bun:"code,nullzero"` 
	Coords []int `bun:"coords,array"` 
}


Try it

package model

import (
	"fmt"
	"testing"

	"github.com/uptrace/bun"
)

const AllColumns = "t.*"

func TestModel(t *testing.T) {

	// connecting to db
	pgdb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN("postgres://user:password@localhost:5432/yourdb")))
	db := bun.NewDB(pgdb, pgdialect.New(), bun.WithDiscardUnknownColumns())

	if _, err := db.Exec(`truncate table users; truncate table geo.countries cascade;`); err != nil {
		panic(err)
	}

	// objects to insert
	toInsert := []GeoCountry{
		GeoCountry{
			Code:   "us",
			Coords: []int{1, 2},
		},
		GeoCountry{
			Code:   "uk",
			Coords: nil,
		},
	}

	// inserting
	ctx := context.Background()
	if _, err := db.NewInsert().Model(&toInsert).Column("code", "coords").Exec(ctx); err != nil {
		panic(err)
	}

	// selecting
	var toSelect []GeoCountry
	ctx = context.Background()
	if err := db.NewSelect().Model(&toSelect).Scan(ctx); err != nil {
		panic(err)
	}

	fmt.Printf("%#v\n", toSelect)

	// user with fk
	newUser := User{
		Email:     "[email protected]",
		Activated: true,
		CountryID: &toSelect[0].ID,
	}

	// inserting
	ctx = context.Background()
	if _, err := db.NewInsert().Model(&newUser).Column("email", "activated", "countryId").Exec(ctx); err != nil {
		panic(err)
	}

	// selecting inserted user
	user := User{}
	m := db.NewSelect().
		Column(AllColumns).
		Relation(Columns.User.Country).
		Where(`? = ?`, bun.Ident(Columns.User.Email), "[email protected]")
	
	ctx = context.Background()
	if err := m.Scan(ctx); err != nil {
		panic(err)
	}

	fmt.Printf("%#v\n", user)
	fmt.Printf("%#v\n", user.Country)
}

Documentation

Index

Constants

View Source
const Template = `` /* 2034-byte string literal not displayed */

Variables

This section is empty.

Functions

func CreateCommand

func CreateCommand() *cobra.Command

CreateCommand creates generator command

Types

type Basic

type Basic struct {
	// contains filtered or unexported fields
}

Basic represents basic generator

func New

func New() *Basic

New creates basic generator

func (*Basic) AddFlags

func (g *Basic) AddFlags(command *cobra.Command)

AddFlags adds flags to command

func (*Basic) Generate

func (g *Basic) Generate() error

Generate runs whole generation process

func (*Basic) Options

func (g *Basic) Options() Options

Options gets options

func (*Basic) Packer

func (g *Basic) Packer() base.Packer

Packer returns packer function for compile entities into package

func (*Basic) ReadFlags

func (g *Basic) ReadFlags(command *cobra.Command) error

ReadFlags read flags from command

func (*Basic) SetOptions

func (g *Basic) SetOptions(options Options)

SetOptions sets options

type Options

type Options struct {
	base.Options

	// Package sets package name for model
	// Works only with SchemaPackage = false
	Package string

	// Do not replace primary key name to ID
	KeepPK bool

	// Soft delete column
	SoftDelete string

	// use sql.Null... instead of pointers
	UseSQLNulls bool

	// Do not generate alias tag
	NoAlias bool

	// Do not generate discard_unknown_columns tag
	NoDiscard bool

	// Override type for json/jsonb
	JSONTypes map[string]string

	// Add json tag to models
	AddJSONTag bool
}

Options for generator

func (*Options) Def

func (o *Options) Def()

Def fills default values of an options

type TemplateColumn

type TemplateColumn struct {
	model.Column

	Tag     template.HTML
	Comment template.HTML
}

TemplateColumn stores column info

func NewTemplateColumn

func NewTemplateColumn(entity model.Entity, column model.Column, options Options) TemplateColumn

NewTemplateColumn creates a column for template

type TemplateEntity

type TemplateEntity struct {
	model.Entity

	Tag template.HTML

	NoAlias bool
	Alias   string

	Columns []TemplateColumn

	HasRelations bool
	Relations    []TemplateRelation
}

TemplateEntity stores struct info

func NewTemplateEntity

func NewTemplateEntity(entity model.Entity, options Options) TemplateEntity

NewTemplateEntity creates an entity for template

type TemplatePackage

type TemplatePackage struct {
	Package string

	HasImports bool
	Imports    []string

	Entities []TemplateEntity

	ORMNeeded   bool
	ORMDbStruct string
}

TemplatePackage stores package info

func NewTemplatePackage

func NewTemplatePackage(entities []model.Entity, options Options) TemplatePackage

NewTemplatePackage creates a package for template

type TemplateRelation

type TemplateRelation struct {
	model.Relation

	Tag     template.HTML
	Comment template.HTML
}

TemplateRelation stores relation info

func NewTemplateRelation

func NewTemplateRelation(relation model.Relation, options Options) TemplateRelation

NewTemplateRelation creates relation for template

func NewTemplateRelationWithJoin

func NewTemplateRelationWithJoin(relation model.Relation, relFK, relPK string, options Options) TemplateRelation

NewTemplateRelationWithJoin creates relation for template with `join` tag component relPK - primary key in foreign table

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL