postgres.go 3.2 KB

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