Get started in Go
These instructions assume that you use Bazel and Gazelle , but you can adapt them for any build system you like.
Setup
First, add twicedb-go
as a project dependency:
$ bazel run //:gazelle -- update-repos bitbucket.org/twicedb/twicedb-go
Next, install the TwiceDB code generator–you may be prompted for your password since it is installed in /usr/local/bin
by default:
$ bazel run @org_bitbucket_twicedb_twicedb_go//gen:install
Tags
With setup completed, let’s imagine that we have an existing project with the following code, and we want to integrate it with TwiceDB:
// Package models provides the models that we'll read from and write to the
// database.
package models
// A Company has 0 or more Persons who work there.
type Company struct {
Name string
}
// NewCompany returns a pointer to a Company with the given name.
func NewCompany(name string) *Company {
return &Company{
Name: name,
}
}
// A Person is someone who works at a Company.
type Person struct {
Firstname string
Lastname string
Salary int32
Manager *Person
Company *Company
}
// NewPerson returns a pointer to a Person with the given fields.
func NewPerson(
firstname string,
lastname string,
salary int32,
manager *Person,
company *company) *Person {
return &Person{
Firstname: firstname,
Lastname: lastname,
Salary: salary,
Manager: manager,
Company: company,
}
}
Here is the modified file:
// Package models provides the models that we'll read from and write to the
// database.
package models
//go:generate twicedb-gen -kind object -name Company
//go:generate twicedb-gen -kind object -name Person -fields Manager:Person,Company:Company
import (
"bitbucket.org/twicedb/twicedb-go/client/api"
)
// A Company has 0 or more Persons who work there.
type Company struct {
api.IndexableF
Name *string `twicedb:"index"`
}
// A Person is someone who works at a Company.
type Person struct {
api.IndexableF
Firstname *string `twicedb:"index"`
Lastname *string `twicedb:"index"`
Salary *int32 `twicedb:"index,project"`
//Manager *Person
//Company *Company
}
You can see that the code is quite a bit shorter, and you can probably guess from the model definitions what behaviors are provided. Let’s review the changes one-by-one:
- We added a
go:generate
command for theCompany
model. This tells TwiceDB to generate the code required to interact with the database. - We added a
go:generate
command for thePerson
model. Since aPerson
references (or “belongs to”) both aManager
, which is anotherPerson
, and aCompany
, we pass appropriate arguments totwicedb-gen
to generate the extra files and methods. - We embedded
api.IndexableF
in theCompany
model and in thePerson
model. This adds some TwiceDB fields to the models. - We changed
Company.Name
to*string
and added thetwicedb:"index"
tag. This allows us to do fastCompany
lookups byName
. - We changed
Person.Firstname
andPerson.Lastname
to*string
and added thetwicedb:"index"
tag. This allows us to do fastPerson
lookups byFirstname
, byLastname
, or by both. - We changed
Person.Salary
to*int32
and added thetwicedb:"index,project"
tag. This allows us to do fastPerson
lookups bySalary
and to calculate aggregate statistics, such as the meanSalary
. - We commented out
Person.Manager
andPerson.Company
since these relations are managed entirely by TwiceDB. It’s helpful to keep the commented lines in place as a reminder to anyone who reads the code in the future. - We removed
NewCompany
andNewPerson
. Constructors are generated automatically bytwicedb-gen
.
After making those changes, don’t forget to run go generate ./...
!
Stuck?
If you get stuck, consult twicedb-get-started-in-go , which contains all of the code that you see here. For a complete reference, check out the full documentation .
Next steps
Now that you know how to set up your code for TwiceDB and Go, take a look at the examples to see how a complete application fits together.