• Stars
    star
    195
  • Rank 193,074 (Top 4 %)
  • Language
    Go
  • License
    MIT License
  • Created about 9 years ago
  • Updated almost 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An ORM code-generation tool for Go, provides ActiveRecord-like functionality for your types.

argen

argen is an ORM code-generation tool for Go, provides ActiveRecord-like functionality for your types.

Installation

$ go get -u github.com/monochromegane/argen/...

Quick start

  1. Define a table mapping struct in main.go.
  2. Mark it up with a +AR annotation in an adjacent comment like so:
//+AR
type User struct{
	Id int `db:"pk"`
	Name string
	Age int
}

And at the command line, simply type:

$ argen main.go

You should see new files, named *_gen.go.

And you can use ActiveRecord-like functions.

db, _ := sql.Open("sqlite3", "foo.db")
Use(db)

u := User{Name: "test", Age: 20}
u.Save()
//// INSERT INTO users (name, age) VALUES (?, ?); [test 20]

User{}.Where("name", "test").And("age", ">", 20).Query()
//// SELECT users.id, users.name, users.age FROM users WHERE name = ? AND age > ?; [test 20]

ActiveRecord-like functions

Setup

db, _ := sql.Open("sqlite3", "foo.db")

// Set db
Use(db)

Create record

u := User{Name: "test", Age: 20}
u.Save()

or

// XxxParams has same fields to original type.
User{}.Create(UserParams{Name: "test", Age: 20})

Query

// Get the first record
User{}.First()
//// SELECT users.id, users.name, users.age FROM users ORDER BY id ASC LIMIT ?; [1]

// Get the last record
User{}.Last()
//// SELECT users.id, users.name, users.age FROM users ORDER BY id DESC LIMIT ?; [1]

// Get the record by Id
User{}.Find(1)
//// SELECT users.id, users.name, users.age FROM users WHERE id = ? LIMIT ?; [1 1]

// Get all record
User{}.All().Query()
//// SELECT users.id, users.name, users.age FROM users;

Query with conditions

// Get the first matched record
User{}.FindBy("name", "test")
//// SELECT users.id, users.name, users.age FROM users WHERE name = ? LIMIT ?; [test 1]

// Get the first matched record
User{}.Where("name", "test").QueryRow()
//// SELECT users.id, users.name, users.age FROM users WHERE name = ?; [test]

// Get the all matched records
User{}.Where("name", "test").Query()
//// SELECT users.id, users.name, users.age FROM users WHERE name = ?; [test]

// And
User{}.Where("name", "test").And("age", ">", 20).Query()
//// SELECT users.id, users.name, users.age FROM users WHERE name = ? AND age > ?; [test 20]
// Count
User{}.Count()
//// SELECT COUNT(*) FROM users;

// Exists
User{}.Exists()
//// SELECT 1 FROM users LIMIT ?; [1]

// Select
User{}.Select("id", "name").Query()
//// SELECT users.id, users.name FROM users;

// Order
User{}.Order("name", "ASC").Query()
//// SELECT users.id, users.name, users.age FROM users ORDER BY name ASC;

// Limit and offset
User{}.Limit(1).Offset(2).Query()
//// SELECT users.id, users.name, users.age FROM users LIMIT ? OFFSET ?; [1 2]

// GroupBy and having
User{}.Group("name").Having("count(name)", 2).Query()
//// SELECT users.id, users.name, users.age FROM users GROUP BY name HAVING count(name) = ?; [2]

Update

user, _ := User{}.Find(1)

// Update an existing struct
user.Name = "a"
user.Save()
//// UPDATE users SET id = ?, name = ?, age = ? WHERE id = ?; [1 a 20 1]

// Update attributes with validation
user.Update(UserParams{Name: "b"})
//// UPDATE users SET id = ?, name = ?, age = ? WHERE id = ?; [1 b 20 1]

// Update attributes without validation
user.UpdateColumns(UserParams{Name: "c"})
//// UPDATE users SET id = ?, name = ?, age = ? WHERE id = ?; [1 b 20 1]

Delete

user, _ := User{}.Find(1)

// Delete an existing struct
user.Destroy()
//// DELETE FROM users WHERE id = ?; [1]

Associations

Has One

Add association function to your type:

func (m User) hasOnePost() *ar.Association {
        return nil
}

And type argen or go generate on your command line.

user, _ := User{}.Create(UserParams{Name: "user1"})
user.BuildPost(PostParams{Name: "post1"}).Save()

// Get the related record
user.Post()
//// SELECT posts.id, posts.user_id, posts.name FROM posts WHERE user_id = ?; [1]

// Join
user.JoinsPost().Query()
//// SELECT users.id, users.name, users.age FROM users INNER JOIN posts ON posts.user_id = users.id;

Has Many

Add association function to your type:

func (m User) hasManyPosts() *ar.Association {
        return nil
}

And type argen or go generate on your command line.

user, _ := User{}.Create(UserParams{Name: "user1"})
user.BuildPost(PostParams{Name: "post1"}).Save()

// Get the related records
user.Posts()
//// SELECT posts.id, posts.user_id, posts.name FROM posts WHERE user_id = ?; [1]

// Join
user.JoinsPosts()
//// SELECT users.id, users.name, users.age FROM users INNER JOIN posts ON posts.user_id = users.id;

Belongs To

Add association function to your type:

func (p Post) belongsToUser() *ar.Association {
        return nil
}

And type argen or go generate on your command line.

u, _ := User{}.Create(UserParams{Name: "user1"})
post, _ := u.BuildPost(PostParams{Name: "post1"})
post.Save()

// Get the related record
post.User()
//// SELECT users.id, users.name, users.age FROM users WHERE id = ?; [1]

// Join
post.JoinsUser().Query()
//// SELECT posts.id, posts.user_id, posts.name FROM posts INNER JOIN users ON users.id = posts.user_id;

Validation

Add validation function to your type:

func (u User) validatesName() ar.Rule {
	// Define rule for "name" column
	return ar.MakeRule().Format().With("[a-z]")
}

You specify target column by naming validatesXxx.

Rules

// presence
Presence()

// format
Formart().With("regex")

// numericality
Numericality().OnlyInteger().GreaterThan(10)

Trigger

// OnCreate
OnCreate()

// OnUpdate
OnUpdate()

Method chain

Validation rules has a chainable API. you could use it like this.

ar.MakeRule().
	Presence().
	Format().With("[a-z]").
	OnCreate()

Custom validation

Add custom validation function to your type:

func (p Post) validateCustom() ar.Rule {
        return ar.CustomRule(func(errors *ar.Errors) {
                if p.Name != "name" {
                        errors.Add("name", "must be name")
                }
        }).OnUpdate()
}

And type argen or go generate on your command line.

Error

u := User{Name: "invalid name"}
_, errs := u.IsValid()
if errs != nil {
	fmt.Errorf("%v\n", errs.Messages["name"])
}

Log

LogMode(true)

go generate

If you want to generate it by using go generate, you mark it up an annotation at top of file.

//go:generate argen

and type:

$ go generate

Code status

Build Status

TODO

  • Transaction
  • Callbacks (before/after save)
  • Conditions for callbacks and validations.
  • AS clause
  • Log options

Author

monochromegane

License

argen is licensed under the MIT

More Repositories

1

the_platinum_searcher

A code search tool similar to ack and the_silver_searcher(ag). It supports multi platforms and multi encodings.
Go
2,789
star
2

go_design_pattern

Design patterns in Golang.
Go
1,469
star
3

kaburaya

Kaburaya optimize the number of goroutines by feedback control.
Go
105
star
4

smux

smux is a socket multiplexer written in Golang. It provides fast communication by efficiently a single connection.
Go
100
star
5

hoi

An easy file/message transfer tool using http file server.
Go
99
star
6

mdt

A markdown table generation tool from CSV/TSV.
Go
92
star
7

dragon-imports

A tool for speedup goimports command 🐉
Go
63
star
8

LGTM

This is a Chrome Extension for LGTM.in/g. You can spice up your LGTM comments by this extension.
JavaScript
63
star
9

go-gitignore

A fast gitignore matching library for Go.
Go
61
star
10

gannoy

Approximate nearest neighbor search server and dynamic index written in Golang.
Go
40
star
11

torokko

A build proxy server using Docker container for Golang apps.
Go
31
star
12

go-avx

AVX(Advanced Vector Extensions) binding for golang.
Go
30
star
13

conflag

A combination command-line flag and configuration file library for Go.
Go
29
star
14

vagrant-global-status

A fast vagrant global-status command.
Go
13
star
15

go-bincode

A tool for embedding Go code in a Go binary using go-bindata.
Go
13
star
16

smartsifter

SmartSifter (On-line outlier detection) by Golang.
Go
12
star
17

starchart

StarChart is a tool to manage Google Cloud Machine Learning training programs and model versions.
Python
12
star
18

slack-incoming-webhooks

A Slack Incoming Webhooks client in Go.
Go
11
star
19

vagrant-peco

A peco tool for vagrant-global-status.
Shell
10
star
20

dotfiles

my dotfiles
Vim Script
10
star
21

be_strong

Strong parameter converter.
Ruby
9
star
22

stage

Simple and flexible simulation framework for Go.
Go
9
star
23

pendulum

Pendulum is a tool to manage Treasure Data scheduled jobs.
Ruby
9
star
24

mruby-tensorflow

TensorFlow class for mruby.
C++
7
star
25

BundleSaver

Android用ユーティリティ。 BundleまたはPreferenceに対するActivity状態の保存/復元を自動化してくれます。
Java
6
star
26

kaleidoscope

[WIP] Distributed peer-to-peer personal key-value store.
Go
6
star
27

go-code-embedding

A tool to embed Go source code into binary using go:embed.
Go
6
star
28

gradient_descent

The sample implementaion of gradient descent in Golang.
Go
6
star
29

QueryBuilder

A very simple query builder for PHP. It helps building query and binding values.
PHP
5
star
30

hugo-theme-thinking-megane

My blog theme for Hugo. Designed by keita_kawamoto. http://blog.monochromegane.com
HTML
5
star
31

synapse

Distributed, RESTful, Plugable Matching Engine.
Go
4
star
32

mruby-secure-random

SecureRandom class for mruby.
Ruby
4
star
33

dsn

A data source name adapter for sql.Open in golang.
Go
4
star
34

active_hash-like

Custom matcher for ActiveHash. It provides `like` operator.
Ruby
4
star
35

guardian

Monitor file changes and execute custom commands for each event.
Go
4
star
36

mruby-time-strftime

Time#strftime for mruby.
Ruby
4
star
37

flagen

A command line option parser generator using command line option.
Go
4
star
38

mackerel-plugin-delayed-job-count

delayed_job custom metrics plugin for mackerel.io agent.
Go
4
star
39

sanny

Scalable Approximate Nearest Neighbors in Golang optimized for embedding vectors.
Go
4
star
40

exponential-histograms

Exponential histograms is a data structure for sliding windows. It is from `Maintaining Stream Statistics over Sliding Windows, M.Datar, A.Gionis, P.Indyk, R.Motwani; ACM-SIAM, 2002`.
Go
4
star
41

mysql_dump_slow

A library to summarize MySQL slow_log records in Ruby.
Ruby
3
star
42

monochromegane.github.com

Thinking-megane - Ruby, Vim, Java, Android に関する情報を公開していくGithub Pagesです
HTML
3
star
43

retrospective-anchoco

ふりかえりのファシリテーターを行うときに使える"あんちょこ"です。
Ruby
3
star
44

banditsflow

🎰 A building workflow and tracking its information framework for bandits.
Python
3
star
45

active_hash-kaminari

Use kaminari paginator with ActiveHash.
Ruby
3
star
46

terminal

This is Go package that provides function like a "isatty()".
Go
2
star
47

kirakira

This is Cinch plugin that convert message to rainbow.
Ruby
2
star
48

queuing-theory-simulator

Queuing theory simulator in Go.
Go
2
star
49

go-ngt

NGT binding for golang.
Go
2
star
50

conference-proposals

My talk proposals.
2
star
51

ssd_mlengine

Port of SSD: Single Shot MultiBox Detector to Google Cloud Machine Learning Engine.
Python
2
star
52

go-whois

WHOIS client in Go
Go
2
star
53

treasure_hunter

CLI to manage query of Treasure Data command line tool.
Ruby
2
star
54

thinking-megane

My blog contents for Hugo. http://blog.monochromegane.com
2
star
55

adwin

Adwin is an adaptive windowing algorithm. It is from `Learning from time-changing data with adaptive windowing, Bifet, Albert, and Ricard Gavalda; Proceedings of the 2007 SIAM international conference on data mining. Society for Industrial and Applied Mathematics, 2007`.
Go
2
star
56

mole

Get all list of Go modules.
Go
1
star
57

postman

Go
1
star
58

ship-it

A simple deploy tool in Go. It's suitable for golang project.
Go
1
star
59

mruby-sidekiq-client

Sidekiq Client class for mruby.
Ruby
1
star
60

homebrew-pt

Ruby
1
star
61

mruby-annoy

AnnoyIndex class for mruby.
C++
1
star
62

thor_hammer

ThorHammer provides web api for your Thor CLI.
Ruby
1
star
63

go-home

A utility for getting home directory in Golang.
Go
1
star
64

sifter

[WIP] A lightweight index for full text search tools using bloom filter.
Go
1
star
65

unite-yaml

unite-yaml is a unite.vim's source which provides candidates for yaml.
Vim Script
1
star
66

homebrew-hoi

Ruby
1
star
67

go-embedding-accessor

An accessor generator for files embedded with go:embed.
Go
1
star