Transfer first library files

This commit is contained in:
Achim Rohn
2025-07-27 17:53:07 +02:00
parent e187673510
commit 728cf90236
7 changed files with 196 additions and 0 deletions
+14
View File
@@ -1,3 +1,17 @@
module ersteller-lib
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
)
+16
View File
@@ -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
}
+32
View File
@@ -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
View File
@@ -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
}
+29
View File
@@ -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
View File
@@ -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
View File
@@ -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)
}