본문 바로가기

PROGRAMING/GO

go gin-gonic 라우터 빼고 파일 나누고!!

꼭 C#같았다.  여러파일이 하나처럼 동작했다.
일단 

package main
func main() {

	r := gin.Default()
	gin.ForceConsoleColor()
	//r.Static("/", "./views")
	r.Static("/src", "./views/src")

	r.HTMLRender = ginview.Default()
	r.GET("/ping2", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})

	r.GET("/index", func(c *gin.Context) {
		c.Header("Content-Type", "text/html")
		//views폴더가 자동으로 지정되는 듯하다. view로 폴더이름 했을땐 에러났다.
		c.HTML(http.StatusOK, "index.html", gin.H{})
	})

이런식으로 되어있던 것을 3개의 파일로 나눴다.
나누고 생각해보니 맨 위의 "package main" 이것이 제일 중요했다.
example.go  -- 원래 메인 파일 이 파일 하나를 3개로 나눈거다.

package main

import (
	"github.com/foolin/goview/supports/ginview"
	"github.com/gin-gonic/gin"
	_ "github.com/lib/pq"
)

const (
	// Initialize connection constants.
	HOST        = "localhost"
	DB_DATABASE = "postgres"
	DB_USER     = "postgres"
	DB_PASSWORD = "pwd"
)

func checkError(err error) {
	if err != nil {
		panic(err)
	}
}

func main() {

	r := gin.Default()
	gin.ForceConsoleColor()
	//r.Static("/", "./views")
	r.Static("/src", "./views/src")

	r.HTMLRender = ginview.Default()
	r.GET("/ping2", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})

	r.GET("/index", get_index)
	r.GET("/simple", get_simple)
	r.GET("/chejan_balance", get_chejan_balance)
	r.GET("/opt10085", get_opt10085)
	r.GET("/chejan_order", get_chejan_order)
	r.GET("/realtime_contract", get_realtime_contract)
	r.POST("/chejan_balance_data", post_chejan_balance_data)
	r.POST("/chejan_order_data", post_chejan_order_data)
	r.POST("/realtime_contract_data", post_realtime_contract_data)
	r.Run(":8080")
	//r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

변경된것에서는 라우터 만을 두었다.

두번째것은 get으로 호출되는 ui가 있는 페이지들을 내용을 함수로 뺀
get-html.go

package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/gofrs/uuid"
)

func get_index(c *gin.Context) {
	c.Header("Content-Type", "text/html")
	//views폴더가 자동으로 지정되는 듯하다. view로 폴더이름 했을땐 에러났다.
	c.HTML(http.StatusOK, "index.html", gin.H{})
}

func get_simple(c *gin.Context) {
	c.Header("Content-Type", "text/html")
	//views폴더가 자동으로 지정되는 듯하다. view로 폴더이름 했을땐 에러났다.
	c.HTML(http.StatusOK, "simple.html", gin.H{})
}

func get_chejan_balance(c *gin.Context) {
	c.Header("Content-Type", "text/html")
	//views폴더가 자동으로 지정되는 듯하다. view로 폴더이름 했을땐 에러났다.

	uuid1, err := uuid.NewV4()
	if err != nil {
		panic(err)
	}
	fmt.Println(uuid1)
	c.HTML(http.StatusOK, "chejan_balance.html", gin.H{"uuid": uuid1})
}

func get_opt10085(c *gin.Context) {
	c.Header("Content-Type", "text/html")
	//views폴더가 자동으로 지정되는 듯하다. view로 폴더이름 했을땐 에러났다.

	uuid1, err := uuid.NewV4()
	if err != nil {
		panic(err)
	}
	fmt.Println(uuid1)
	c.HTML(http.StatusOK, "opt10085.html", gin.H{"uuid": uuid1})
}

func get_chejan_order(c *gin.Context) {
	c.Header("Content-Type", "text/html")
	//views폴더가 자동으로 지정되는 듯하다. view로 폴더이름 했을땐 에러났다.

	uuid1, err := uuid.NewV4()
	if err != nil {
		panic(err)
	}
	fmt.Println(uuid1)
	c.HTML(http.StatusOK, "chejan_order.html", gin.H{"uuid": uuid1})
}

func get_realtime_contract(c *gin.Context) {
	c.Header("Content-Type", "text/html")
	//views폴더가 자동으로 지정되는 듯하다. view로 폴더이름 했을땐 에러났다.

	uuid1, err := uuid.NewV4()
	if err != nil {
		panic(err)
	}
	fmt.Println(uuid1)
	c.HTML(http.StatusOK, "realtime_contract.html", gin.H{"uuid": uuid1})
}

첫번째것에서 url에 매핑한 함수들이 있다. html호출!!
3번째는 json으로 데이터를 리턴해주는 함수들이다.
같은 패키지로 지정해서 그런지 import에는 따로 써주지 않아도 되었다.
다음에 로컬 패키지에서 package명 달리해서 한번 해보아야겠다.

package main

import (
	"fmt"
	"log"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/jmoiron/sqlx"
)

func post_chejan_balance_data(c *gin.Context) {
	stock_cd := c.PostForm("stock_cd")
	fmt.Printf("stock_cd data: %s\n", stock_cd)
	var connectionString string = fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=disable", HOST, DB_USER, DB_PASSWORD, DB_DATABASE)
	db, err := sqlx.Connect("postgres", connectionString)
	checkError(err)
	err = db.Ping()
	checkError(err)
	var sb strings.Builder
	sb.WriteString(`
		select 
			 acct_num
			,stock_cd
			,curr_amt
			,possession_qty
			,purchase_amt
			,tot_purchase_amt
			,order_possible_qty
			,today_net_buy_qty
			,order_type
			,today_sell_profit_loss
			,deposit

			,offered_amt
			,bid_amt
			,yesterday_amt
			,profit_loss_rt
			,credit_amt
			,credit_interest
			,expiry_dt
			,today_profit_loss_amt
			,today_profit_loss_rt
			,credit_today_profit_loss_amt
			,credit_today_profit_loss_rt
			,loan_qty
			,loan_dt
			,credit_gubun
			,crt_dtm
		from tb_chejan_balance
		order by crt_dtm desc
	`)
	//Go through rows
	rows, err := db.Queryx(sb.String())
	//fmt.Printf("Marshalled data: %s\n", mm)
	mm := []map[string]interface{}{}
	for rows.Next() {
		m := map[string]interface{}{}
		err := rows.MapScan(m)
		mm = append(mm, m)
		if err != nil {
			log.Fatal(err)
		}
	}
	c.JSON(200, mm)
}

func post_chejan_order_data(c *gin.Context) {
	stock_cd := c.PostForm("stock_cd")
	fmt.Printf("stock_cd data: %s\n", stock_cd)
	var connectionString string = fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=disable", HOST, DB_USER, DB_PASSWORD, DB_DATABASE)
	db, err := sqlx.Connect("postgres", connectionString)
	checkError(err)
	err = db.Ping()
	checkError(err)
	var sb strings.Builder
	sb.WriteString(`
			select 
			curr_time
				,acct_num
				,order_num
				,stock_cd
				,order_business_classification
				,order_status
				,order_qty
				,order_amt
				,not_contract_qty
				,contract_tot_amt
				,ongn_order_num
				,order_gubun
				,trade_gubun

				,order_type
				,contract_num
				,contract_amt
				,contract_qty
				,curr_amt
				,offered_amt
				,bid_amt
				,contract_amt_unit
				,contract_amt_qty
				,today_commission
				,today_tax
				,screen_num
				,terminal_num
				,credit_gubun
				,loan_dt
				,crt_dtm
			from tb_chejan_order
			order by crt_dtm desc
		`)
	//Go through rows
	rows, err := db.Queryx(sb.String())
	//fmt.Printf("Marshalled data: %s\n", mm)
	mm := []map[string]interface{}{}
	for rows.Next() {
		m := map[string]interface{}{}
		err := rows.MapScan(m)
		mm = append(mm, m)
		if err != nil {
			log.Fatal(err)
		}
	}
	c.JSON(200, mm)
}

func post_realtime_contract_data(c *gin.Context) {
	stock_cd := c.PostForm("stock_cd")
	stock_dt := c.PostForm("stock_dt")
	fmt.Printf("stock_cd data: %s\n", stock_cd)

	var connectionString string = fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=disable", HOST, DB_USER, DB_PASSWORD, DB_DATABASE)

	db, err := sqlx.Connect("postgres", connectionString)
	checkError(err)
	err = db.Ping()
	checkError(err)
	var sb strings.Builder
	sb.WriteString(`
	with vw00 as (
		select 
			stock_dt
			,stock_cd
			,curr_time
			,count(*) OVER(
					partition by stock_cd
					, stock_dt
					, ((cast(substring(curr_time,1,2) as integer)-9 )*60 + cast(substring(curr_time,3,2)  as integer) )/b.divide
			) cnt
			,FIRST_VALUE(curr_amt) OVER(
					partition by stock_cd
					, stock_dt
					, ((cast(substring(curr_time,1,2) as integer)-9 )*60 + cast(substring(curr_time,3,2)  as integer) )/b.divide
					order by curr_time asc
			) start_amt
			,last_valUE(curr_amt) OVER(
					partition by stock_cd
					, stock_dt
					, ((cast(substring(curr_time,1,2) as integer)-9 )*60 + cast(substring(curr_time,3,2)  as integer) )/b.divide
					order by curr_time asc		  
			) curr_amt
			,RANK() OVER(
					partition by stock_cd
					, stock_dt
					, ((cast(substring(curr_time,1,2) as integer)-9 )*60 + cast(substring(curr_time,3,2)  as integer) )/b.divide
					order by curr_time		  
			) rnk
			,((cast(substring(curr_time,1,2) as integer)-9 )*60 + cast(substring(curr_time,3,2)  as integer) )/b.divide  mm
			,max(abs(curr_amt)) over (partition by stock_cd
									, stock_dt
									, ((cast(substring(curr_time,1,2) as integer)-9 )*60 + cast(substring(curr_time,3,2)  as integer) )/b.divide 
									) as high_amt 
			,min(abs(curr_amt)) over (partition by stock_cd
									, stock_dt
									, ((cast(substring(curr_time,1,2) as integer)-9 )*60 + cast(substring(curr_time,3,2)  as integer) )/b.divide 
									) as low_amt 
			,(case when trade_qty>0 then trade_qty else 0 end)  offered_trade_qty
			,(case when trade_qty<0 then trade_qty else 0 end)  bid_trade_qty
			,b.divide
		from tb_realtime_contract  a
		cross join (select 5 as  divide ) b
		where 1=1`)
	//if stock_cd != "" {
	sb.WriteString(` 
		and a.stock_cd='005930'`)
	//}

	if stock_dt != "" {
		sb.WriteString(` 
		and a.stock_dt='20200403'`)
	}

	sb.WriteString(`
		)
		select 
			stock_dt
			,stock_cd
			,curr_amt
			,mm
			,curr_time
			,start_amt
			,high_amt
			,low_amt
			,offered_trade_qty
			,bid_trade_qty 
			,divide
			,cnt
			,stock_dt ||'-'|| stock_cd ||'-'|| curr_time  id 
		from vw00 
		where rnk=1
		order by mm asc
		`)
	//Go through rows
	rows, err := db.Queryx(sb.String())
	//fmt.Printf("Marshalled data: %s\n", mm)
	mm := []map[string]interface{}{}
	for rows.Next() {
		m := map[string]interface{}{}
		err := rows.MapScan(m)
		mm = append(mm, m)
		if err != nil {
			log.Fatal(err)
		}
	}
	//fmt.Printf("Marshalled data: %s\n", mm)
	//엄청 많은 건을 가지고 와서 1분 27초만에 조회를 했는데
	//출력도 되었는데
	//c.JSON에서 해결이 안된다.
	//혹은 여기서 해결이 되었는데 chrome에서 해결을 못한다.
	//메모리가 1,8G가 까지 치솟았는데 네트워크에서는 응답을 못받았다.
	//sql 로그 남기는 건
	//https://github.com/luna-duclos/instrumentedsql 이것을 해보자 dddata는 유료다.
	//api 툴에서 호출해보았다.
	// response로는 값이 안보이는데 hex로 보면 값이 전달됨을 확인했다.
	// 네트워크는 전달되었다고 보는게 맞는것 같다.
	// 그럼 그리드에서 확인이 안된다는건데.
	// console.log로 데이터가 왔는지 찍어보자.
	// console.log로도 데이터가 찍힘을 확인했다.
	// 그리드에서 못받춰주는건지. grid.on 걸었던 이벤트에서 찍은 로그가 문제인지 확인해보자.
	// 결국엔 그리드가 문제였다. 대용량 데이터를 처리못하는데 네이버 그리드에서는
	// 대용량 데이터도 처리하는 것처럼 설명해두었다.

	c.JSON(200, mm)
}

'PROGRAMING > GO' 카테고리의 다른 글

go string builder  (0) 2020.04.05
go multiline 문자열 여러줄 문자열 sql 쓸때.  (0) 2020.04.05