DEV Community

Mat
Mat

Posted on

I made SQL easy in Go

I hate working with SQL. I dont know why but just something about using it in programming languages is ugly to me. Because of this I tend to avoid it at all costs. I am a total SQL noob.

When I've used it in projects in the past its been through libraries like prisma-client-go. This is a really cool package. You define your schema, and run 1 command and you instantly have fully typed Go code to work with. I even used it to create a monitoring mobile app called Cronus.

I used it a lot but as my schema's grew in complexity, so did the generated go files. It currently sits at 61mb. This would often cause my VSCode to lag and become unusable. Theres also the problem that as your schema grows, Intelisense becomes so overwhelming that its basically useless.

I spent the weekend creating a go package that I think is pretty useful. It abstracts away the vast majority of the complexity of working with SQL in Go.

Feel free to check out eazydb

Creating a Client

Not much to change here from the default

c, err := eazydb.NewClient(eazydb.ClientOptions{
    User:     "postgres",
    Password: "postgres",
    Host:     "localhost",
    Port:     "5432",
    Name:     "postgres",
    Type:     eazydb.POSTGRES,
})
Enter fullscreen mode Exit fullscreen mode

Creating a table

This is where you start to see just how easy it is, theres also options to handle adding new fields from your structure automatically.

Any field with a json tag will be added to the Schema

type Users struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
    Age  int    `json:"age"`
}

// Create a table
_, err = c.NewTable("users").Fields(User{}).Key("id", dbtypes.SERIAL).Exec()
if err != nil {
    log.Fatalf("could not create table %v", err)
}

// Shorthand to use later
table := c.Table("users")
Enter fullscreen mode Exit fullscreen mode

Inserting data

Could not be easier, create your data and add it, either 1 at a time or 5000! It'll be handled

// Insert data
users := makeUsers(5000)
metadata, err := table.Add(users).Exec()
if err != nil {
    log.Fatalf("could not insert users table %v", err)
}
Enter fullscreen mode Exit fullscreen mode

Updating a field

Again, very easy. Just define what fields you want updated

// Update a field
Mat := &User{
    Age: 24,
}
metadata, err = table.Update(Mat).Where(
    *eazydb.String("name").Equals("Mat"),
).Exec()
Enter fullscreen mode Exit fullscreen mode

Want to update every field? No problem

// Update a field
metadata, err = table.Update(Mat).Exec()
Enter fullscreen mode Exit fullscreen mode

Deleting rows

Similar to updating

// Delete
metadata, err = table.Delete().Where(
    *eazydb.Int("age").Equals(40),
).Exec()
Enter fullscreen mode Exit fullscreen mode

Want to limit? Eazy just add a MaxRows()

metadata, err = table.Delete().Where(
    *eazydb.Int("age").Equals(40),
).MaxRows(50).Exec()
Enter fullscreen mode Exit fullscreen mode

Fetching data

Probably the best part, like every other operation. Just defined what you want to return. Any field with the json tag will be returned

var resp []User
_, err = table.Get(User{}).Where(
    *eazydb.Int("age").Equals(24),
).Exec(&resp)
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
manchicken profile image
Mike Stemle

I would have really liked to see a direct comparison between your new module and the other patterns that are common in this ecosystem.

Collapse
 
dyfet profile image
David Sugar

How does this compare with gorm?