I am using gorm (Golang) to connect to my postgres database below the connection code
func NewDatabase(config *config.Config) *gorm.DB {
dsn := fmt.Sprintf(
"host=%s user=%s password=%s dbname=%s port=%s sslmode=disable",
config.DBHost, config.DBUser, config.DBPass, config.DBName, config.DBPort)
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
Logger: logger.Default.LogMode(logger.Info),
NamingStrategy: schema.NamingStrategy{
TablePrefix: "public.",
SingularTable: false,
NameReplacer: CustomReplacer{func(s string) string {
return strings.NewReplacer("\"", "").Replace(s)
}},
},
})
if err != nil {
logrus.Fatal("Error connecting to database ", err)
}
logrus.Info("Database connection successful")
sqlDB, err := db.DB()
if err != nil {
return nil
}
if err != nil {
logrus.Fatal("Error getting sql connection", err)
}
sqlDB.SetMaxIdleConns(config.DBMaxIdlePoolSize)
sqlDB.SetMaxOpenConns(config.DBMaxOpenPoolSize)
return db
}
I am getting unusual error ERRO[0003] ERROR: relation "public.databases" does not exist (SQLSTATE 42P01) because databases table exists in my database in the public schema.
However if I point the database to a remote DB which has same data as local it works perfectly fine.
Add search_path=public parameter to the connection string.
Related
I'm trying to use toml to store the connection settings of a database.
I want to load these settings that are in a config.toml file and thus do my operations
I tried the following:
go code:
func Init() *sql.DB {
config, err := toml.LoadFile("config.toml")
if err != nil {
log.Fatal("Erro ao carregar variaveis de ambiente")
}
host := config.Get("postgres.host").(string)
port := config.Get("postgres.port").(string)
user := config.Get("postgres.user").(string)
password := config.Get("postgres.password").(string)
dbname := config.Get("postgres.dbname").(string)
stringConnection := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s", host, port, user, password, dbname)
db, err := sql.Open("postgres", stringConnection)
if err != nil {
panic(err)
}
fmt.Println("Sucesso ao realizar conexão com o banco de dados")
err = db.Ping()
return db
}
config.toml:
[postgres]
host = "localhost"
port = 5432
user = "postgres"
password = "ivaneteJC"
dbname = "webhook"
this attempt is returning an error, which unfortunately I do not know how to proceed
error:
panic: interface conversion: interface {} is int64, not string
Any solution ?
As for your error, like #tkausl said, you define port as integer, and not a string, yet you do type assertion of the value to string in this line
port := config.Get("postgres.port").(string)
Change the string to int64 like the error said and you should be fine.
Are you using the https://github.com/pelletier/go-toml package? If so, this package seems to also support unmarshalling config files into Go struct directly. This is a more convenient approach instead of having to config.Get each config one by one.
type PostgreConfig struct {
Host string
Port int
User string
Password string
Dbname string
}
type MyConfig struct {
Postgres *PostgreConfig
}
// Read the toml file content
doc, err := os.ReadFile("config.toml")
if err != nil {
panic(err)
}
// Parse the content
var cfg MyConfig
err = toml.Unmarshal(doc, &cfg)
if err != nil {
panic(err)
}
fmt.Println(cfg.Postgres.Host)
fmt.Println(cfg.Postgres.Port)
The solution with minimal changes:
// solution 1
port := config.Get("postgres.port")
stringConnection := fmt.Sprintf("host=%s port=%v user=%s password=%s dbname=%s", host, port, user, password, dbname)
// solution 2
port := config.Get("postgres.port").(int64)
stringConnection := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s", host, port, user, password, dbname)
// solution 3
// config.toml
port = "5432"
I'm trying to connect to my mongo db atlas database, but I'm getting an error that I can't solve it within mongo+go forums.
The code:
package main
import (
"context"
"log"
"time"
"fmt"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
"go.mongodb.org/mongo-driver/bson"
)
func main(){
client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://my-user:<my-pass>#datalake0-lesz0.a.query.mongodb.net/my-db?ssl=true&authSource=admin"))
if err != nil {
log.Fatal(err)
}
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
err = client.Connect(ctx)
if err != nil {
log.Fatal(err)
}
defer client.Disconnect(ctx)
err = client.Ping(ctx, readpref.Primary())
if err != nil {
log.Fatal(err)
}
databases, err := client.ListDatabaseNames(ctx, bson.M{})
if err != nil {
log.Fatal(err)
}
fmt.Println(databases)
}
The error:
connection() error occured during connection handshake: auth error: sasl conversation error: unable to authenticate using mechanism "SCRAM-SHA-1": (AuthenticationFailed) authentication failed, correlationID = 167bc5ba18415510a4144b7a
exit status 1
If the URI in the connect string is verbatim, then this is your problem:
mongodb://my-user:<my-pass> is incorrect, <my-pass> should be substituted with your password
You've probably cut and pasted the provided URI on completion of DB setup but this connect string does not include items like your password, also you gave my-user which, unless you set up the username my-user that also needs changing.
I am trying to connect MongoDB by the native MongoDB driver with go language
(ref).
Here is my snapcode.
package main
import (
"context"
"fmt"
"log"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
const (
account = "rootAdmin"
password = "12345678"
iP = "127.0.0.1"
port = 27017
tlsCertificateKeyFile = "D:/cert/wa.pem"
)
type mongoStuff struct {
ctx context.Context
client *mongo.Client
cancel context.CancelFunc
}
func connectToMongoDB() *mongoStuff {
uri := fmt.Sprintf("mongodb://%v:%v#%v:%v/?authSource=admin&tlsCertificateKeyFile=%v&tls=true",
account,
password,
iP,
port,
tlsCertificateKeyFile)
credential := options.Credential{
AuthMechanism: "MONGODB-X509",
Username: account,
Password: password,
}
log.Println(uri)
clientOpts := options.Client().ApplyURI(uri).SetAuth(credential)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
client, err := mongo.Connect(ctx, clientOpts)
if err != nil {
log.Println("Dead connect")
log.Fatal(err)
}
return &mongoStuff{ctx, client, cancel}
}
func disconnectMongoDB(mongodb *mongoStuff) {
cancel := mongodb.cancel
client := mongodb.client
ctx := mongodb.ctx
defer cancel()
defer func() {
if err := client.Disconnect(ctx); err != nil {
log.Println("Dead disconnect")
panic(err)
}
}()
}
func insertExamples(mongodb *mongoStuff) {
ctx := mongodb.ctx
var db *mongo.Database = mongodb.client.Database("documentation_examples")
coll := db.Collection("inventory_insert")
err := coll.Drop(ctx)
if err != nil {
log.Println("Dead drop")
log.Fatal(err)
}
{
result, err := coll.InsertOne(
ctx,
bson.D{
{"item", "canvas"},
{"qty", 100},
{"tags", bson.A{"cotton"}},
{
"size", bson.D{
{"h", 28},
{"w", 35.5},
{"uom", "cm"},
}},
})
if err != nil {
log.Println("Dead insertone")
log.Fatal(err)
}
log.Printf("insertone success. id=%v", result.InsertedID)
}
}
func main() {
mongodb := connectToMongoDB()
defer disconnectMongoDB(mongodb)
insertExamples(mongodb)
}
Whenever I run the code, it just comes up with the below error.
connection() error occured during connection handshake: auth error: round trip error: (AuthenticationFailed) No user name provided
I can't figure out what's going on.
To authenticate with x.509, the username should be either the common name of the certificate or empty. You seem to be attempting some mix of password and x.509 authentication.
All required options can be provided in the URI. See How can I connect with X509 by putting all options in the connection string in node.js driver for mongodb?.
If you insist on specifying credentials not in a URI, reference driver documentation that describes how to do that for x509 credentials.
sql.Open() wouldn't error:
if db, err = sql.Open("postgres", url); err != nil {
return nil, fmt.Errorf("Postgres connect error : (%v)", err)
}
but db.Ping() would error:
if err = db.Ping(); err != nil {
return nil, fmt.Errorf("Postgres ping error : (%v)", err)
}
and it was simply because the lib/pq connection string wouldn't connect from within a docker container with the seperated connection parameters.
For example:
url := fmt.Sprintf("user=%v password=%v host=%v port=%v dbname=%v",
rs.conf.Redshift.User,
rs.conf.Redshift.Password,
rs.conf.Redshift.Host,
rs.conf.Redshift.Port,
rs.conf.Redshift.DB)
Using the connection string as a URL worked:
url := fmt.Sprintf("postgres://%v:%v#%v:%v/%v?sslmode=disable",
pql.conf.Postgres.User,
pql.conf.Postgres.Password,
pql.conf.Postgres.Host,
pql.conf.Postgres.Port,
pql.conf.Postgres.DB)
See lib/pq docs here:
https://godoc.org/github.com/lib/pq
I was stuck on this for more than a day and I owe the fix to Nikolay Sandalov's comment here in GitHub:
https://github.com/coreos/clair/issues/134#issuecomment-491300639
Thank you, Nikolay 🙇🏻♂️
I'm trying to connect to a server through a socket using an ssl certificate. I have the private key and the certificate needed to connect to the server, i have looked around for something to help me write this code in Go but i have not found anything helpful. Here is the code i write so far, but it does not seem to get me anywhere, it seems to be sending data(tls.dial) before getting to the actual data, which forces the server to reply with some encrypted data which i am unable to check.
func main() {
cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
if err != nil {
log.Fatalf("server: loadkeys: %s", err)
}
config := tls.Config{Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true}
conn, err := tls.Dial("tcp", "1.2.3.4:1234", &config)
if err != nil {
log.Fatalf("client: dial: %s", err)
}
defer conn.Close()
log.Println("client: connected to: ", conn.RemoteAddr())
state := conn.ConnectionState()
for _, v := range state.PeerCertificates {
fmt.Println(x509.MarshalPKIXPublicKey(v.PublicKey))
fmt.Println(v.Subject)
}
log.Println("client: handshake: ", state.HandshakeComplete)
log.Println("client: mutual: ", state.NegotiatedProtocolIsMutual)
message := "data"
n, err := io.WriteString(conn, message)
if err != nil {
log.Fatalf("client: write: %s", err)
}
log.Printf("client: wrote %q (%d bytes)", message, n)
reply := make([]byte, 256)
n, err = conn.Read(reply)
log.Printf("client: read %q (%d bytes)", string(reply[:n]), n)
log.Print("client: exiting")
}