Transfer first library files
This commit is contained in:
@@ -1,3 +1,17 @@
|
|||||||
module ersteller-lib
|
module ersteller-lib
|
||||||
|
|
||||||
go 1.24
|
go 1.24
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/jackc/pgx/v5 v5.7.5
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.29
|
||||||
|
golang.org/x/crypto v0.40.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||||
|
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||||
|
golang.org/x/sync v0.16.0 // indirect
|
||||||
|
golang.org/x/text v0.27.0 // indirect
|
||||||
|
)
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package ersteller_lib
|
||||||
|
|
||||||
|
// https://medium.com/@rnp0728/secure-password-hashing-in-go-a-comprehensive-guide-5500e19e7c1f
|
||||||
|
import "golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
|
// HashPassword generates a bcrypt hash for the given password.
|
||||||
|
func HashPassword(password string) (string, error) {
|
||||||
|
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
|
||||||
|
return string(bytes), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifyPassword verifies if the given password matches the stored hash.
|
||||||
|
func VerifyPassword(password, hash string) bool {
|
||||||
|
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package ersteller_lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func LogDebug(message string, a ...any) {
|
||||||
|
println(fmt.Sprintf(message, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Debug(a ...any) {
|
||||||
|
stringValue := joinStrings(a)
|
||||||
|
println(stringValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func joinStrings(a []any) string {
|
||||||
|
elementsToLog := []string{}
|
||||||
|
|
||||||
|
for i := 0; i < len(a); i++ {
|
||||||
|
elementsToLog = append(elementsToLog, strings.TrimSpace(fmt.Sprint(a[i])))
|
||||||
|
}
|
||||||
|
return strings.Join(elementsToLog, " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func LogError(message string, a ...any) {
|
||||||
|
println(fmt.Sprintf("Error: %v", fmt.Sprintf(message, a...)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Error(a ...any) {
|
||||||
|
println(fmt.Sprint("Error: ", joinStrings(a)))
|
||||||
|
}
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
package ersteller_lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CreatePostgresConnpool(dbUrl string) (*pgxpool.Pool, error) {
|
||||||
|
connPool, err := pgxpool.NewWithConfig(context.Background(), config(dbUrl))
|
||||||
|
if err != nil {
|
||||||
|
Error("Error while creating connection to the database!!", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
connection, err := connPool.Acquire(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
LogError("Error while acquiring connection from the database pool!! %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer connection.Release()
|
||||||
|
|
||||||
|
err = connection.Ping(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
LogError("Could not ping database")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return connPool, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func config(dbUrl string) *pgxpool.Config {
|
||||||
|
const defaultMaxConns = int32(4)
|
||||||
|
const defaultMinConns = int32(0)
|
||||||
|
const defaultMaxConnLifetime = time.Hour
|
||||||
|
const defaultMaxConnIdleTime = time.Minute * 30
|
||||||
|
const defaultHealthCheckPeriod = time.Minute
|
||||||
|
const defaultConnectTimeout = time.Second * 5
|
||||||
|
|
||||||
|
dbConfig, err := pgxpool.ParseConfig(dbUrl)
|
||||||
|
if err != nil {
|
||||||
|
Error("Failed to create a config, error: ", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
dbConfig.MaxConns = defaultMaxConns
|
||||||
|
dbConfig.MinConns = defaultMinConns
|
||||||
|
dbConfig.MaxConnLifetime = defaultMaxConnLifetime
|
||||||
|
dbConfig.MaxConnIdleTime = defaultMaxConnIdleTime
|
||||||
|
dbConfig.HealthCheckPeriod = defaultHealthCheckPeriod
|
||||||
|
dbConfig.ConnConfig.ConnectTimeout = defaultConnectTimeout
|
||||||
|
|
||||||
|
return dbConfig
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package ersteller_lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateSQLiteConnpool creates a new SQLite connection pool
|
||||||
|
func CreateSQLiteConnpool(dbPath string) (*sql.DB, error) {
|
||||||
|
db, err := sql.Open("sqlite3", dbPath)
|
||||||
|
if err != nil {
|
||||||
|
Error("Error while creating connection to the SQLite database!!", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test the connection
|
||||||
|
err = db.PingContext(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
LogError("Could not ping SQLite database: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set connection pool settings
|
||||||
|
db.SetMaxOpenConns(4)
|
||||||
|
db.SetMaxIdleConns(2)
|
||||||
|
|
||||||
|
return db, nil
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
package ersteller_lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
func FirstLetterToUpper(name string) string {
|
||||||
|
return strings.ToUpper(name[:1]) + name[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func FirstLetterToLower(name string) string {
|
||||||
|
return strings.ToLower(name[:1]) + name[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func InlineTemplate(templateString string, data any) string {
|
||||||
|
dollarRegex := regexp.MustCompile(`\$(\w+)\$`)
|
||||||
|
templateString = dollarRegex.ReplaceAllStringFunc(templateString, func(s string) string {
|
||||||
|
if strings.HasPrefix(s, "$.") || strings.HasPrefix(s, "$end") || strings.HasPrefix(s, "$else") {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return dollarRegex.ReplaceAllString(s, "$.$1$")
|
||||||
|
})
|
||||||
|
tmpl, err := template.New("inline").Delims("$", "$").Parse(templateString)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprint("Failed to parse template ", err)
|
||||||
|
}
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err = tmpl.Execute(&buf, data)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprint("Failed to execute template ", err)
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package ersteller_lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Trace(object any) string {
|
||||||
|
marshalled, err := json.Marshal(object)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprint(object)
|
||||||
|
}
|
||||||
|
return string(marshalled)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user