자동화 프로젝트에서 별도의 DB를 구축하고 커넥션을 맺자니 인프라 발급에 관리적인 문제와, 동시에 수많은 쿼리를 전송하여 발생하는 트렌잭션을 감당할 수 있을지 의문이 들었으나... 로컬에서 sqlite를 사용해 데이터를 저장하고 필요시 api를 뚫어 조회할 수 있는 시스템만 구축하면 모든 문제가 해결되어 golang으로 sqlite를 사용하는 방법을 기록 :)
package main
import (
"bufio"
"database/sql"
"fmt"
"os"
"github.com/dixonwille/wmenu"
_ "github.com/mattn/go-sqlite3"
"github.com/projectdiscovery/gologger"
)
type testData struct {
Id int
Name string
Age string
Address string
}
var (
myDB *sql.DB
)
func createTestTable() {
query := `
CREATE TABLE IF NOT EXISTS test_table (
id INTEGER NOT NULL PRIMARY KEY,
name TEXT,
age TEXT,
address TEXT,
UNIQUE (name)
);
`
if _, err := myDB.Exec(query); err != nil {
checkErr(err)
}
}
func insertTestData(_name string, _age string, _address string) {
query := `
INSERT INTO test_table VALUES(NULL,?,?,?)
`
if _, err := myDB.Exec(query, _name, _age, _address); err != nil {
checkErr(err)
}
gologger.Info().Msgf("데이터 삽입 완료!")
}
// QueryRow 메소드는 하나의 row. 즉 테이블 가장 최상단의 값을 가져온다.
func selectTestData1() {
var result testData
query := `
SELECT * FROM test_table
`
row := myDB.QueryRow(query)
row.Scan(&result.Id, &result.Name, &result.Age, &result.Address)
gologger.Info().Msgf("이름 : " + result.Name)
gologger.Info().Msgf("나이 : " + result.Age)
gologger.Info().Msgf("주소 : " + result.Address)
}
// Query 메소드는 전달된 쿼리의 결과에 대한 모든 row를 가져온다.
func selectTestData2() {
rows, err := myDB.Query("SELECT * FROM test_table")
checkErr(err)
for rows.Next() {
var result testData
rows.Scan(&result.Id, &result.Name, &result.Age, &result.Address)
gologger.Info().Msgf("이름 : " + result.Name)
gologger.Info().Msgf("나이 : " + result.Age)
gologger.Info().Msgf("주소 : " + result.Address)
fmt.Println("===================================================================")
}
}
func handleFunc(_opts []wmenu.Opt) {
switch _opts[0].Value {
case 0:
createTestTable()
gologger.Info().Msgf("test_table 생성 완료!")
case 1:
reader := bufio.NewReader(os.Stdin)
fmt.Print("이름 입력 : ")
name, _ := reader.ReadString('\n')
fmt.Print("나이 입력 : ")
age, _ := reader.ReadString('\n')
fmt.Print("주소 입력 : ")
address, _ := reader.ReadString('\n')
insertTestData(name, age, address)
case 2:
selectTestData1()
case 3:
selectTestData2()
case 5:
gologger.Info().Msgf("빠이 👋")
os.Exit(0)
}
}
func checkErr(err error) {
if err != nil {
gologger.Error().Msgf(err.Error())
}
}
func main() {
db, err := sql.Open("sqlite3", "./database/mydb.db")
checkErr(err)
defer db.Close()
myDB = db
menu := wmenu.NewMenu("\n메뉴를 선택하세요.")
menu.Action(func(_opts []wmenu.Opt) error { handleFunc(_opts); return nil })
menu.Option("테스트 테이블 생성", 0, false, nil)
menu.Option("테스트 데이터 삽입", 1, false, nil)
menu.Option("테스트 데이터 조회(QueryRow)", 2, false, nil)
menu.Option("테스트 데이터 조회(Query)", 3, false, nil)
menu.Option("종료!", 5, false, nil)
err = menu.Run()
checkErr(err)
}