postgres.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package database
  2. import (
  3. "context"
  4. "database/sql"
  5. "errors"
  6. "fmt"
  7. "github.com/gravitl/netmaker/db"
  8. "time"
  9. "github.com/gravitl/netmaker/servercfg"
  10. _ "github.com/lib/pq"
  11. )
  12. // PGDB - database object for PostGreSQL
  13. var PGDB *sql.DB
  14. // PG_FUNCTIONS - map of db functions for PostGreSQL
  15. var PG_FUNCTIONS = map[string]interface{}{
  16. INIT_DB: initPGDB,
  17. CREATE_TABLE: pgCreateTable,
  18. INSERT: pgInsert,
  19. INSERT_PEER: pgInsertPeer,
  20. DELETE: pgDeleteRecord,
  21. DELETE_ALL: pgDeleteAllRecords,
  22. FETCH_ALL: pgFetchRecords,
  23. CLOSE_DB: pgCloseDB,
  24. isConnected: pgIsConnected,
  25. }
  26. func getPGConnString() string {
  27. pgconf := servercfg.GetSQLConf()
  28. pgConn := fmt.Sprintf("host=%s port=%d user=%s "+
  29. "password=%s dbname=%s sslmode=%s connect_timeout=5",
  30. pgconf.Host, pgconf.Port, pgconf.Username, pgconf.Password, pgconf.DB, pgconf.SSLMode)
  31. return pgConn
  32. }
  33. func initPGDB() error {
  34. gormDB := db.FromContext(db.WithContext(context.TODO()))
  35. var dbOpenErr error
  36. PGDB, dbOpenErr = gormDB.DB()
  37. if dbOpenErr != nil {
  38. return dbOpenErr
  39. }
  40. PGDB.SetMaxOpenConns(5)
  41. PGDB.SetConnMaxLifetime(time.Hour)
  42. return PGDB.Ping()
  43. }
  44. func pgCreateTable(tableName string) error {
  45. statement, err := PGDB.Prepare("CREATE TABLE IF NOT EXISTS " + tableName + " (key TEXT NOT NULL UNIQUE PRIMARY KEY, value TEXT)")
  46. if err != nil {
  47. return err
  48. }
  49. defer statement.Close()
  50. _, err = statement.Exec()
  51. if err != nil {
  52. return err
  53. }
  54. return nil
  55. }
  56. func pgInsert(key string, value string, tableName string) error {
  57. if key != "" && value != "" {
  58. insertSQL := "INSERT INTO " + tableName + " (key, value) VALUES ($1, $2) ON CONFLICT (key) DO UPDATE SET value = $3;"
  59. statement, err := PGDB.Prepare(insertSQL)
  60. if err != nil {
  61. return err
  62. }
  63. defer statement.Close()
  64. _, err = statement.Exec(key, value, value)
  65. if err != nil {
  66. return err
  67. }
  68. return nil
  69. } else {
  70. return errors.New("invalid insert " + key + " : " + value)
  71. }
  72. }
  73. func pgInsertPeer(key string, value string) error {
  74. if key != "" && value != "" {
  75. err := pgInsert(key, value, PEERS_TABLE_NAME)
  76. if err != nil {
  77. return err
  78. }
  79. return nil
  80. } else {
  81. return errors.New("invalid peer insert " + key + " : " + value)
  82. }
  83. }
  84. func pgDeleteRecord(tableName string, key string) error {
  85. deleteSQL := "DELETE FROM " + tableName + " WHERE key = $1;"
  86. statement, err := PGDB.Prepare(deleteSQL)
  87. if err != nil {
  88. return err
  89. }
  90. defer statement.Close()
  91. if _, err = statement.Exec(key); err != nil {
  92. return err
  93. }
  94. return nil
  95. }
  96. func pgDeleteAllRecords(tableName string) error {
  97. deleteSQL := "DELETE FROM " + tableName
  98. statement, err := PGDB.Prepare(deleteSQL)
  99. if err != nil {
  100. return err
  101. }
  102. defer statement.Close()
  103. if _, err = statement.Exec(); err != nil {
  104. return err
  105. }
  106. return nil
  107. }
  108. func pgFetchRecords(tableName string) (map[string]string, error) {
  109. row, err := PGDB.Query("SELECT * FROM " + tableName + " ORDER BY key")
  110. if err != nil {
  111. return nil, err
  112. }
  113. records := make(map[string]string)
  114. defer row.Close()
  115. for row.Next() { // Iterate and fetch the records from result cursor
  116. var key string
  117. var value string
  118. row.Scan(&key, &value)
  119. records[key] = value
  120. }
  121. if len(records) == 0 {
  122. return nil, errors.New(NO_RECORDS)
  123. }
  124. return records, nil
  125. }
  126. func pgCloseDB() {
  127. //PGDB.Close()
  128. }
  129. func pgIsConnected() bool {
  130. stats := PGDB.Stats()
  131. return stats.OpenConnections > 0
  132. }