0
0

GoでgRPCサーバーを立ててみる3(repository.goの実装)

Posted at

お疲れ様です。

今日は「repository.goの実装」について部分いたします。

articleサービスにおいてDBとやり取りをするrepository.goの実装を行なっていきます。

今回は簡易的なデータベースとしてsqlite3を使用するので、以下のパッケージをインストールしておきましょう。

go get github.com/mattn/go-sqlite3

インストールできたら、忘れずにimportしておきます。

article/repository/repository.go
package repository

import (
	_ "github.com/mattn/go-sqlite3"
)

articleサービスでは、以下のようなarticlesテーブルにデータを格納していきます。

id author title content
INTEGER STRING STRING STRING

このテーブルとデータをやり取りする5つの処理を実装していきます。

article/repository/repository.go
type Repository interface {
  InsertArticle(ctx context.Context, input *pb.ArticleInput) (int64, error)
  SelectArticleByID(ctx context.Context, id int64) (*pb.Article, error)
  UpdateArticle(ctx context.Context, id int64, input *pb.ArticleInput) error
  DeleteArticle(ctx context.Context, id int64) error
  SelectAllArticles() (*sql.Rows, error)
}

type sqliteRepo struct {
	db *sql.DB
}

func NewsqliteRepo() (Repository, error) {
	db, err := sql.Open("sqlite3", "./article/article.sql")
	if err != nil {
		return nil, err
	}

	// articlesテーブルを作成
	cmd := `CREATE TABLE IF NOT EXISTS articles(
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		author STRING,
		title STRING,
		content STRING)`

	_, err = db.Exec(cmd)
	if err != nil {
		return nil, err
	}
	return &sqliteRepo{db}, nil
}

func (r *sqliteRepo) InsertArticle(ctx context.Context, input *pb.ArticleInput) (int64, error) {
	// DBに記事をINERT
}

func (r *sqliteRepo) SelectArticleByID(ctx context.Context, id int64) (*pb.Article, error) {
	// DBからIDに基づいて記事をSELECT
}

func (r *sqliteRepo) UpdateArticle(ctx context.Context, id int64, input *pb.ArticleInput) error {
	// DB内の記事をUPDATE
}

func (r *sqliteRepo) DeleteArticle(ctx context.Context, id int64) error {
	// DB内の記事をDELETE
}

func (r *sqliteRepo) SelectAllArticles() (*sql.Rows, error) {
	// articlesテーブルの記事を全取得
}

InsertArticle

article/repository/repository.go
func (r *sqliteRepo) InsertArticle(ctx context.Context, input *pb.ArticleInput) (int64, error) {
	// Inputの内容(Author, Title, Content)をarticlesテーブルにINSERT
	cmd := "INSERT INTO articles(author, title, content) VALUES (?, ?, ?)"
	result, err := r.db.Exec(cmd, input.Author, input.Title, input.Content)
	if err != nil {
		return 0, err
	}
	
	// INSERTした記事のIDを取得
	id, err := result.LastInsertId()
	if err != nil {
		return 0, err
	}
	
	// INSERTした記事のIDを返す
	return id, nil
}

SelectArticleByID

article/repository/repository.go
func (r *sqliteRepo) SelectArticleByID(ctx context.Context, id int64) (*pb.Article, error) {
	// 該当IDの記事をSELECT
	cmd := "SELECT * FROM articles WHERE id = ?"
	row := r.db.QueryRow(cmd, id)
	var a pb.Article

	// SELECTした記事の内容を読み取る
	err := row.Scan(&a.Id, &a.Author, &a.Title, &a.Content)
	if err != nil {
		return nil, err
	}

	// SELECTした記事を返す
	return &pb.Article{
		Id:      a.Id,
		Author:  a.Author,
		Title:   a.Title,
		Content: a.Content,
	}, nil
}

UpdateArticle

article/repository/repository.go
func (r *sqliteRepo) UpdateArticle(ctx context.Context, id int64, input *pb.ArticleInput) (*pb.Article, error) {
	// 該当IDのAuthor, Title, ContentをUPDATE
	cmd := "UPDATE articles SET author = ?, title = ?, content = ? WHERE id = ?"
	_, err := r.db.Exec(cmd, input.Author, input.Title, input.Content, id)
	if err != nil {
		return err
	}

	// errorがなければ返り値なし
	return nil
}

DeleteArticle

article/repository/repository.go
func (r *sqliteRepo) DeleteArticle(ctx context.Context, id int64) error {
	// 該当IDの記事をDELETE
	cmd := "DELETE FROM articles WHERE id = ?"
	_, err := r.db.Exec(cmd, id)
	if err != nil {
		return err
	}

	// errorがなければ返り値なし
	return nil
}

SelectAllArticles

article/repository/repository.go
func (r *sqliteRepo) SelectAllArticles() (*sql.Rows, error) {
	// articlesテーブルの記事を全取得
	cmd := "SELECT * FROM articles"
	rows, err := r.db.Query(cmd)
	if err != nil {
		return nil, err
	}

	// 全取得した記事を*sql.Rowsの形で返す
	return rows, nil
}

これで、repositoryの実装ができました!

今日は以上です。

次は「service.goの実装」についてです。

ありがとうございました。

よろしくお願いいたします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0