kisielk/sqlstruct — pull request #3 by l3pp4rd (2014-01-15 19:19:16+00:00)
Title: Allows to alias a specific tables to structs

Its often useful to have joins in a query and this allows to scan separate table data into a separate struct.
See the example bellow:

Sql used with MySQL driver
``` sql
CREATE TABLE IF NOT EXISTS address (
id INTEGER NOT NULL AUTO_INCREMENT,
address VARCHAR(512) NOT NULL,
city VARCHAR(32) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB;

INSERT INTO address (address, city) VALUES
('Plento 34', 'Vilnius');

CREATE TABLE IF NOT EXISTS users (
id INTEGER NOT NULL AUTO_INCREMENT,
username VARCHAR(32) NOT NULL,
name VARCHAR(64) NOT NULL,
address VARCHAR(256) NOT NULL,
address_id INTEGER NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY address_id(address_id),
CONSTRAINT fk_user_address FOREIGN KEY (address_id) REFERENCES address(id)
) ENGINE=InnoDB;

INSERT INTO users (username, name, address, address_id) VALUES
('gedi', 'Gedas', 'gediminas.morkevicius@gmail.com', 1);
```

And go code to see it in action:
``` go
package main

import "github.com/kisielk/sqlstruct"
import "database/sql"
import _ "github.com/go-sql-driver/mysql"
import "fmt"
import "log"

type User struct {
Id int `sql:"id"`
Username string `sql:"username"`
Email string `sql:"address"`
Name string `sql:"name"`
HomeAddress *Address `sql:"-"`
}

type Address struct {
Id int `sql:"id"`
City string `sql:"city"`
Street string `sql:"address"`
}

func main() {
db, err := sql.Open("mysql", "root:nimda@/test")
if err != nil {
log.Fatal(err)
}
defer db.Close()

user := new(User)
address := new(Address)
sql := `
SELECT %s, %s FROM users AS u
INNER JOIN address AS a ON a.id = u.address_id
WHERE u.username = ?
`
sql = fmt.Sprintf(sql, sqlstruct.AliasedColumns(*user, "u"), sqlstruct.AliasedColumns(*address, "a"))
rows, err := db.Query(sql, "gedi")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
if rows.Next() {
err = sqlstruct.AliasedScan(user, rows, "u")
if err != nil {
log.Fatal(err)
}
err = sqlstruct.AliasedScan(address, rows, "a")
if err != nil {
log.Fatal(err)
}
user.HomeAddress = address
}
fmt.Printf("user: %+v and his home address: %+v", *user, *user.HomeAddress)
}
```