Go Web编程 Chapter6

Go web编程

Chapter_6 Storing_Data

csv_store
package main

import (
   "encoding/csv"
   "fmt"
   "os"
   "strconv"
)

type Post struct {
   Id      int
   Content string
   Author  string
}

func main() {
   // creating a CSV file
   csvFile, err := os.Create("posts.csv")
   if err != nil {
      panic(err)
   }
   defer csvFile.Close()

   allPosts := []Post{
      Post{Id: 1, Content: "Hello World!", Author: "Sau Sheong"},
      Post{Id: 2, Content: "Bonjour Monde!", Author: "Pierre"},
      Post{Id: 3, Content: "Hola Mundo!", Author: "Pedro"},
      Post{Id: 4, Content: "Greetings Earthlings!", Author: "Sau Sheong"},
   }

   writer := csv.NewWriter(csvFile)
   for _, post := range allPosts {
      line := []string{strconv.Itoa(post.Id), post.Content, post.Author}
      err := writer.Write(line)
      if err != nil {
         panic(err)
      }
   }
   writer.Flush()

   // reading a CSV file
   file, err := os.Open("posts.csv")
   if err != nil {
      panic(err)
   }
   defer file.Close()

   reader := csv.NewReader(file)
   reader.FieldsPerRecord = -1
   record, err := reader.ReadAll()
   if err != nil {
      panic(err)
   }

   var posts []Post
   for _, item := range record {
      id, _ := strconv.ParseInt(item[0], 0, 0)
      post := Post{Id: int(id), Content: item[1], Author: item[2]}
      posts = append(posts, post)
   }
   fmt.Println(posts[0].Id)
   fmt.Println(posts[0].Content)
   fmt.Println(posts[0].Author)
}
gob_store
package main

import (
   "bytes"
   "encoding/gob"
   "fmt"
   "io/ioutil"
)

type Post struct {
   Id      int
   Content string
   Author  string
}

// store data
func store(data interface{}, filename string) {
   buffer := new(bytes.Buffer)
   encoder := gob.NewEncoder(buffer)
   err := encoder.Encode(data)
   if err != nil {
      panic(err)
   }
   err = ioutil.WriteFile(filename, buffer.Bytes(), 0600)
   if err != nil {
      panic(err)
   }
}

// load the data
func load(data interface{}, filename string) {
   raw, err := ioutil.ReadFile(filename)
   if err != nil {
      panic(err)
   }
   buffer := bytes.NewBuffer(raw)
   dec := gob.NewDecoder(buffer)
   err = dec.Decode(data)
   if err != nil {
      panic(err)
   }
}

func main() {
   post := Post{Id: 1, Content: "Hello World!", Author: "Sau Sheong"}
   store(post, "post1")
   var postRead Post
   load(&postRead, "post1")
   fmt.Println(postRead)
}
gorm_store
package main

import (
   "fmt"
   "github.com/jinzhu/gorm"
   _ "github.com/lib/pq"
   "time"
)

type Post struct {
   Id        int
   Content   string
   Author    string `sql:"not null"`
   Comments  []Comment
   CreatedAt time.Time
}

type Comment struct {
   Id        int
   Content   string
   Author    string `sql:"not null"`
   PostId    int
   CreatedAt time.Time
}

var Db *gorm.DB

// connect to the Db
func init() {
   var err error
   Db, err = gorm.Open("postgres", "user=gwp dbname=gwp password=gwp sslmode=disable")
   if err != nil {
      panic(err)
   }
   Db.AutoMigrate(&Post{}, &Comment{})
}

func main() {
   post := Post{Content: "Hello World!", Author: "Sau Sheong"}
   fmt.Println(post) // {0 Hello World! Sau Sheong [] 0001-01-01 00:00:00 +0000 UTC}

   // Create a post
   Db.Create(&post)
   fmt.Println(post) // {1 Hello World! Sau Sheong [] 2015-04-13 11:38:50.91815604 +0800 SGT}

   // Add a comment
   comment := Comment{Content: "Good post!", Author: "Joe"}
   Db.Model(&post).Association("Comments").Append(comment)

   // Get comments from a post
   var readPost Post
   Db.Where("author = $1", "Sau Sheong").First(&readPost)
   var comments []Comment
   Db.Model(&readPost).Related(&comments)
   fmt.Println(comments[0]) // {1 Good post! Joe 1 2015-04-13 11:38:50.920377 +0800 SGT}
}
map_store
package main

import (
   "fmt"
)

type Post struct {
   Id      int
   Content string
   Author  string
}

var PostById map[int]*Post
var PostsByAuthor map[string][]*Post

func store(post Post) {
   PostById[post.Id] = &post
   PostsByAuthor[post.Author] = append(PostsByAuthor[post.Author], &post)
}

func main() {

   PostById = make(map[int]*Post)
   PostsByAuthor = make(map[string][]*Post)

   post1 := Post{Id: 1, Content: "Hello World!", Author: "Sau Sheong"}
   post2 := Post{Id: 2, Content: "Bonjour Monde!", Author: "Pierre"}
   post3 := Post{Id: 3, Content: "Hola Mundo!", Author: "Pedro"}
   post4 := Post{Id: 4, Content: "Greetings Earthlings!", Author: "Sau Sheong"}

   store(post1)
   store(post2)
   store(post3)
   store(post4)

   fmt.Println(PostById[1])
   fmt.Println(PostById[2])

   for _, post := range PostsByAuthor["Sau Sheong"] {
      fmt.Println(post)
   }
   for _, post := range PostsByAuthor["Pedro"] {
      fmt.Println(post)
   }
}
read_write_files
package main

import (
   "fmt"
   "io/ioutil"
   "os"
)

func main() {
   data := []byte("Hello World!\n")

   // write to file and read from file using WriteFile and ReadFile
   err := ioutil.WriteFile("data1", data, 0644)
   if err != nil {
      panic(err)
   }
   read1, _ := ioutil.ReadFile("data1")
   fmt.Print(string(read1))

   // write to file and read from file using the File struct
   file1, _ := os.Create("data2")
   defer file1.Close()

   bytes, _ := file1.Write(data)
   fmt.Printf("Wrote %d bytes to file\n", bytes)

   file2, _ := os.Open("data2")
   defer file2.Close()

   read2 := make([]byte, len(data))
   bytes, _ = file2.Read(read2)
   fmt.Printf("Read %d bytes from file\n", bytes)
   fmt.Println(string(read2))
}
sql_store1
package main

import (
   "database/sql"
   "fmt"
   _ "github.com/lib/pq"
)

type Post struct {
   Id      int
   Content string
   Author  string
}

var Db *sql.DB

// connect to the Db
func init() {
   var err error
   Db, err = sql.Open("postgres", "user=gwp dbname=gwp password=gwp sslmode=disable")
   if err != nil {
      panic(err)
   }
}

// get all posts
func Posts(limit int) (posts []Post, err error) {
   rows, err := Db.Query("select id, content, author from posts limit $1", limit)
   if err != nil {
      return
   }
   for rows.Next() {
      post := Post{}
      err = rows.Scan(&post.Id, &post.Content, &post.Author)
      if err != nil {
         return
      }
      posts = append(posts, post)
   }
   rows.Close()
   return
}

// Get a single post
func GetPost(id int) (post Post, err error) {
   post = Post{}
   err = Db.QueryRow("select id, content, author from posts where id = $1", id).Scan(&post.Id, &post.Content, &post.Author)
   return
}

// Create a new post
func (post *Post) Create() (err error) {
   statement := "insert into posts (content, author) values ($1, $2) returning id"
   stmt, err := Db.Prepare(statement)
   if err != nil {
      return
   }
   defer stmt.Close()
   err = stmt.QueryRow(post.Content, post.Author).Scan(&post.Id)
   return
}

// Update a post
func (post *Post) Update() (err error) {
   _, err = Db.Exec("update posts set content = $2, author = $3 where id = $1", post.Id, post.Content, post.Author)
   return
}

// Delete a post
func (post *Post) Delete() (err error) {
   _, err = Db.Exec("delete from posts where id = $1", post.Id)
   return
}

// Delete all posts
func DeleteAll() (err error) {
   _, err = Db.Exec("delete from posts")
   return
}

func main() {
   post := Post{Content: "Hello World!", Author: "Sau Sheong"}

   // Create a post
   fmt.Println(post) // {0 Hello World! Sau Sheong}
   post.Create()
   fmt.Println(post) // {1 Hello World! Sau Sheong}

   // Get one post
   readPost, _ := GetPost(post.Id)
   fmt.Println(readPost) // {1 Hello World! Sau Sheong}

   // Update the post
   readPost.Content = "Bonjour Monde!"
   readPost.Author = "Pierre"
   readPost.Update()

   // Get all posts
   posts, _ := Posts(10)
   fmt.Println(posts) // [{1 Bonjour Monde! Pierre}]

   // Delete the post
   readPost.Delete()

   // Get all posts
   posts, _ = Posts(10)
   fmt.Println(posts) // []

   // Delete all posts
   // DeleteAll()
}

setup.sql

drop table posts;

create table posts (
  id      serial primary key,
  content text,
  author  varchar(255)
);
sql_store2
package main

import (
   "database/sql"
   "errors"
   "fmt"
   _ "github.com/lib/pq"
)

type Post struct {
   Id       int
   Content  string
   Author   string
   Comments []Comment
}

type Comment struct {
   Id      int
   Content string
   Author  string
   Post    *Post
}

var Db *sql.DB

// connect to the Db
func init() {
   var err error
   Db, err = sql.Open("postgres", "user=gwp dbname=gwp password=gwp sslmode=disable")
   if err != nil {
      panic(err)
   }
}

func (comment *Comment) Create() (err error) {
   if comment.Post == nil {
      err = errors.New("Post not found")
      return
   }
   err = Db.QueryRow("insert into comments (content, author, post_id) values ($1, $2, $3) returning id", comment.Content, comment.Author, comment.Post.Id).Scan(&comment.Id)
   return
}

// Get a single post
func GetPost(id int) (post Post, err error) {
   post = Post{}
   post.Comments = []Comment{}
   err = Db.QueryRow("select id, content, author from posts where id = $1", id).Scan(&post.Id, &post.Content, &post.Author)

   rows, err := Db.Query("select id, content, author from comments where post_id = $1", id)
   if err != nil {
      return
   }
   for rows.Next() {
      comment := Comment{Post: &post}
      err = rows.Scan(&comment.Id, &comment.Content, &comment.Author)
      if err != nil {
         return
      }
      post.Comments = append(post.Comments, comment)
   }
   rows.Close()
   return
}

// Create a new post
func (post *Post) Create() (err error) {
   err = Db.QueryRow("insert into posts (content, author) values ($1, $2) returning id", post.Content, post.Author).Scan(&post.Id)
   return
}

func main() {
   post := Post{Content: "Hello World!", Author: "Sau Sheong"}
   post.Create()

   // Add a comment
   comment := Comment{Content: "Good post!", Author: "Joe", Post: &post}
   comment.Create()
   readPost, _ := GetPost(post.Id)

   fmt.Println(readPost)                  // {1 Hello World! Sau Sheong [{1 Good post! Joe 0xc20802a1c0}]}
   fmt.Println(readPost.Comments)         // [{1 Good post! Joe 0xc20802a1c0}]
   fmt.Println(readPost.Comments[0].Post) // &{1 Hello World! Sau Sheong [{1 Good post! Joe 0xc20802a1c0}]}
}

setup.sql

drop table posts cascade;
drop table comments;

create table posts (
  id      serial primary key,
  content text,
  author  varchar(255)
);

create table comments (
  id      serial primary key,
  content text,
  author  varchar(255),
  post_id integer references posts(id)
);
sqlx_store
package main

import (
   "fmt"
   "github.com/jmoiron/sqlx"
   _ "github.com/lib/pq"
)

type Post struct {
   Id         int
   Content    string
   AuthorName string `db: author`
}

var Db *sqlx.DB

// connect to the Db
func init() {
   var err error
   Db, err = sqlx.Open("postgres", "user=gwp dbname=gwp password=gwp sslmode=disable")
   if err != nil {
      panic(err)
   }
}

// Get a single post
func GetPost(id int) (post Post, err error) {
   post = Post{}
   err = Db.QueryRowx("select id, content, author from posts where id = $1", id).StructScan(&post)
   if err != nil {
      return
   }
   return
}

// Create a new post
func (post *Post) Create() (err error) {
   err = Db.QueryRow("insert into posts (content, author) values ($1, $2) returning id", post.Content, post.AuthorName).Scan(&post.Id)
   return
}

func main() {
   post := Post{Content: "Hello World!", AuthorName: "Sau Sheong"}
   post.Create()
   fmt.Println(post) // {1 Hello World! Sau Sheong}}
}

setup.sql

drop table posts;

create table posts (
  id      serial primary key,
  content text,
  author  varchar(255)
);
Licensed under CC BY-NC-SA 4.0
Built with Hugo
Theme Stack designed by Jimmy