Go web 12. SQLite3

JINSOO PARK·2021년 10월 28일
0

Go 로 만드는 웹

목록 보기
11/16

SQLite3란?

SQLite는 MySQL나 PostgreSQL와 같은 데이터베이스 관리 시스템이지만, 서버가 아니라 응용 프로그램에 넣어 사용하는 비교적 가벼운 데이터베이스이다.

일반적인 RDBMS(관계형 데이터베이스)에 비해 대규모 작업에는 적합하지 않지만, 중소 규모라면 속도에 손색이 없다. 또 API는 단순히 라이브러리를 호출하는 것만 있으며, 데이터를 저장하는 데 하나의 파일만을 사용하는 것이 특징이다. -위키 백과-


즉 MySQL이나 MsSQL, Oracle DB 는 데이터 베이스를 설치하고 운영되는 서버가 있어야 한다.
하지만 SQLite는 간단하게 파일로만 동작한다.


tdm-gcc 설치하기

Go언어 에서 SQLite를 사용할 경우 go-sqlite3 라는 외부 패키지를 사용한다.

이때 Go언어에서 C Go 기능을 사용하는데, C언어의 라이브러리를 사용한다는 의미 이다.

하지만 문제는 표준 C언어를 컴파일 할 수 있어야 한는데 표준 C언어를 컴파일 하기 위해선 표준 컴파일러가 있어야 한다.

표준 컴파일러 중 Go언어 에서는 gcc를 사용한다.

하지만 MS window에서는 리눅스 기반인 gcc를 지원하지 않는다.

그러나 MS window에서도 gcc가 돌아 갈 수 있는 환경을 만들어 주는 것이 MinGW 라고 한다.

그러므로 MS window상에서 리눅스 표준 컴파일러 사용하기 위해선 MinGW를 이용하여 환경을 만든 후 gcc를 사용해야 한다.

짧게 말하면 tdm-gcc를 설치해라!

https://jmeubank.github.io/tdm-gcc/download/

위의 주소로 접속 후 다운로드 및 설치

minGW 실행

go-sqlite3설치

go get github.com/mattn/go-sqlite3



SQLite3 사용하기

web 10.todo리스트에 SQLite3를 적용한다.

ex) model.go

package model

import (
	"time"
)

type Todo struct {
	ID        int       `json:"id"`
	Name      string    `json:"name"`
	Completed bool      `json:"completed"`
	CreatedAt time.Time `json:"created_at"`
}

// 인터페이스 생성
type dbHandler interface {
	getTodos() []*Todo
	addTodo(name string) *Todo
	removeTodo(id int) bool
	completeTodo(id int, complete bool) bool
}

// 인터페이스의 인터페이스를 가지고 있음
var handler dbHandler

func init() {
	// handler = newMemoryHandler()
	handler = newSqliteHandler()
}

func GetTodos() []*Todo {
	return handler.getTodos()
}

func AddTodo(name string) *Todo {
	return handler.addTodo(name)
}

func RemoveTodo(id int) bool {
	return handler.removeTodo(id)
}

func CompleteTodo(id int, complete bool) bool {
	return handler.completeTodo(id, complete)
}

ex) memoryHandler.go

package model

import "time"

// 기존의 메모리 맵을 별도 스트럭터로 만듦
type memoryHandler struct {
	todoMap map[int]*Todo
}

// memoryHandler의 메서드
func (m *memoryHandler) getTodos() []*Todo {
	list := []*Todo{}
	for _, v := range m.todoMap {
		// map의 인덱스 만큼 반복
		// 키는 받지않고 value만 받음
		list = append(list, v)
		// list에 v값을 어팬드
	}
	return list
}

func (m *memoryHandler) addTodo(name string) *Todo {
	id := len(m.todoMap) + 1                   // map의 갯수만큼 id
	todo := &Todo{id, name, false, time.Now()} // 포인터형 구조체 Todo를 생성
	m.todoMap[id] = todo                       // todo의 데이터를 맵에 넣음
	return todo
}

func (m *memoryHandler) removeTodo(id int) bool {
	if _, ok := m.todoMap[id]; ok {
		delete(m.todoMap, id)
		return true
	}
	return false
}

func (m *memoryHandler) completeTodo(id int, complete bool) bool {
	if todo, ok := m.todoMap[id]; ok { // 맵에 있는지 확인
		todo.Completed = complete // 맵에 있는경우 변경
		return true
	}
	return false
}
func newMemoryHandler() dbHandler {
	m := &memoryHandler{}
	m.todoMap = make(map[int]*Todo)
	return m
}

ex) sqliteHandler.go

package model

import (
	"database/sql"
	"os"

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

type sqliteHandler struct {
	db *sql.DB
}

func (s *sqliteHandler) getTodos() []*Todo {
	return nil
}

func (s *sqliteHandler) addTodo(name string) *Todo {
	return nil
}

func (s *sqliteHandler) removeTodo(id int) bool {
	return false
}

func (s *sqliteHandler) completeTodo(id int, complete bool) bool {
	return false
}

// 데이터 베이스를 열면 사라지기전에 닫아줘야함
func (s *sqliteHandler) close() {
	s.db.Close()
}

func newSqliteHandler() dbHandler {
	os.Remove("./test.db")
	database, err := sql.Open("sqlite3", "./test.db")
	if err != nil {
		panic(err)
	}
	statement, _ := database.Prepare(
		`CREATE TABLE IF NOT EXISTS todos (
			id        INTEGER  PRIMARY KEY AUTOINCREMENT,
			name      TEXT,
			completed BOOLEAN,
			createdAt DATETIME
		)`) // 테이블을 만드는 쿼리문
	statement.Exec()
	return &sqliteHandler{db: database}
}
profile
개린이

0개의 댓글

관련 채용 정보