package main

import (

  _ "errors"

  "fmt"

  "gorm.io/driver/clickhouse"

  "gorm.io/driver/mysql"

  "gorm.io/driver/postgres"

  //_"gorm.io/driver/sqlite"

  "gorm.io/driver/sqlserver"

  "gorm.io/gorm"

  "log"

  "time"

)

// db连接

var db *gorm.DB

//

func Setup_os() *gorm.DB{

  // db = newConnection()

  var Type = "mysql"

  var User  ="root"

  var Password  ="FuYun#12345654321"

  var Host  ="192.168.160.128"

  var Port  ="9966"

  var DataBaseName  ="mastpost"

  var dbURI string

  var dialector gorm.Dialector

  if Type == "mysql" {

     dbURI = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true",

        User,

        Password,

        Host,

        Port,

        DataBaseName)

     dialector = mysql.New(mysql.Config{

        DSN:                       dbURI, // data source name

        DefaultStringSize:         256,   // default size for string fields

        DisableDatetimePrecision:  true,  // disable datetime precision, which not supported before MySQL 5.6

        DontSupportRenameIndex:    true,  // drop & create when rename index, rename index not supported before MySQL 5.7, MariaDB

        DontSupportRenameColumn:   true,  // `change` when rename column, rename column not supported before MySQL 8, MariaDB

        SkipInitializeWithVersion: false, // auto configure based on currently MySQL version

     })

  } else if Type == "postgres" { // postgres

     dbURI = fmt.Sprintf("host=%s port=%s user=%s dbname=%s sslmode=disable password=%s",

        Host,

        Port,

        User,

        DataBaseName,

        Password)

     dialector = postgres.New(postgres.Config{

        DSN:                  "user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai",

        PreferSimpleProtocol: true, // disables implicit prepared statement usage

     })

  } else if Type == "sqlserver" { // sqlserver

     dbURI = fmt.Sprintf("sqlserver://%s:%s@%s:%s?database=%s",

        User,

        Password,

        Host,

        Port,

        DataBaseName)

     dialector = sqlserver.New(sqlserver.Config{

        DSN:                       dbURI, // data source name

        DefaultStringSize:         256,   // default size for string fields

     })

  } else if Type == "clickhouse"{ // clickhouse

     dbURI = fmt.Sprintf("tcp://%s:%s?database=%s&username=%s&password=%s&read_timeout=10&write_timeout=20",

        Host,

        Port,

        DataBaseName,

        User,

        Password)

     dialector = clickhouse.New(clickhouse.Config{

        DSN:                       dbURI, // data source name /

        })

  }

  //else { // sqlite3

  // //db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{})

  // dbURI = fmt.Sprintf("%s",DataBaseName)

  // dialector = sqlite.Open(dbURI)

  //}

  conn, err := gorm.Open(dialector, &gorm.Config{})

  if err != nil {

     log.Print(err.Error())

  }

  sqlDB, err := conn.DB()

  if err != nil {

     //fmt.Error("connect db server failed.")

     fmt.Errorf("connect db server failed.")

  }

  sqlDB.SetMaxIdleConns(10)                   //设置最大空闲连接

  sqlDB.SetMaxOpenConns(100)                  //设置最大连接数

  sqlDB.SetMaxIdleConns(7)

  db = conn

  return db

}

// GetDB 开放给外部获得db连接

//func GetDB_os() *gorm.DB {

//

// sqlDB, err := db.DB()

// fmt.Println(sqlDB)

// if err != nil {

//    fmt.Errorf("connect db server failed.")

//    Setup_os()

// }

// if err := sqlDB.Ping(); err != nil {

//    sqlDB.Close()

//    Setup_os()

// }

//

// return db

//}

func HandleError(err error,why string)  {

  if err != nil{

     fmt.Print(why,err)

  }

}

func main()  {

  sql :=Setup_os()

  db, err :=sql.DB()

  HandleError(err,"DB")

  fmt.Println("db",db.Ping())

  _, err = db.Exec("CREATE TABLE IF NOT EXISTS mastpost.hello(world varchar(50))")

  if err != nil{

     log.Fatalln(err)

  }

  _, err = db.Exec("INSERT INTO mastpost.hello(world) VALUES ('hello world')")

  if err != nil{

     log.Fatalln(err)

  }

  rows, err := db.Query("SELECT world FROM mastpost.hello")

  if err != nil{

     log.Fatalln(err)

  }

  fmt.Println(db.Stats())

  fmt.Println(rows)

  time.Sleep(time.Second*1000)

}