diff --git a/cmd/go-urlsh/go-urlsh.go b/cmd/go-urlsh/go-urlsh.go index 0cfd31a..5ff9466 100644 --- a/cmd/go-urlsh/go-urlsh.go +++ b/cmd/go-urlsh/go-urlsh.go @@ -2,20 +2,19 @@ package app import ( "codeberg.org/lauralani/go-urlsh/internal/app" - "codeberg.org/lauralani/go-urlsh/models" - "database/sql" + "codeberg.org/lauralani/go-urlsh/internal/db" "fmt" - "os" + "log" ) func Run() error { - var dberr error - models.DB, dberr = sql.Open("pgx", os.Getenv("DATABASE_URL")) - if dberr != nil { - return fmt.Errorf("couldn't connect to database: %v", dberr.Error()) + + err := db.InitializeDB() + if err != nil { + log.Fatalln(err) } - err := app.SetupFiber() + err = app.SetupFiber() if err != nil { return fmt.Errorf("couldn't start webserver: %v", err.Error()) } diff --git a/examples/settings.env b/examples/settings.env index 55cf844..384b7df 100644 --- a/examples/settings.env +++ b/examples/settings.env @@ -11,5 +11,5 @@ PORT=2345 TRUSTEDPROXIES=127.0.0.1,::1 # Postgresql connection string -# format: postgresql://:@/todos -DATABASE_URL='' \ No newline at end of file +# format: postgresql://:@/todos?sslmode=verify-ca +DATABASE_URL= \ No newline at end of file diff --git a/go.mod b/go.mod index 5ae3684..f56cd14 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,10 @@ require github.com/gofiber/fiber/v2 v2.44.0 require ( github.com/andybalholm/brotli v1.0.5 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/puddle/v2 v2.2.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect github.com/klauspost/compress v1.16.3 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.18 // indirect @@ -16,8 +20,18 @@ require ( github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 // indirect github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect github.com/tinylib/msgp v1.1.8 // indirect + github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect + github.com/uptrace/bun v1.1.12 // indirect + github.com/uptrace/bun/dialect/pgdialect v1.1.12 // indirect + github.com/uptrace/bun/driver/pgdriver v1.1.12 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.45.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect + github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + golang.org/x/crypto v0.7.0 // indirect + golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.8.0 // indirect + mellium.im/sasl v0.3.1 // indirect ) diff --git a/go.sum b/go.sum index 5c16a8a..6078874 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,21 @@ github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/gofiber/fiber/v2 v2.44.0 h1:Z90bEvPcJM5GFJnu1py0E1ojoerkyew3iiNJ78MQCM8= github.com/gofiber/fiber/v2 v2.44.0/go.mod h1:VTMtb/au8g01iqvHyaCzftuM/xmZgKOZCtFzz6CdV9w= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU= +github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= +github.com/jackc/puddle/v2 v2.2.0 h1:RdcDk92EJBuBS55nQMMYFXTxwstHug4jkhT5pq8VxPk= +github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -16,6 +28,8 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 h1:rmMl4fXJhKMNWl+K+r/fq4FbbKI+Ia2m9hYBLm2h4G4= @@ -23,21 +37,40 @@ github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94/go.mod h1:90zrgN3 github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d/go.mod h1:Gy+0tqhJvgGlqnTF8CVGP0AaGRjwBtXs/a5PA0Y3+A4= github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1AvpV+7XmhI4r39LGNzwUL4YpMuL5vk= github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0= github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= +github.com/uptrace/bun v1.1.12 h1:sOjDVHxNTuM6dNGaba0wUuz7KvDE1BmNu9Gqs2gJSXQ= +github.com/uptrace/bun v1.1.12/go.mod h1:NPG6JGULBeQ9IU6yHp7YGELRa5Agmd7ATZdz4tGZ6z0= +github.com/uptrace/bun/dialect/pgdialect v1.1.12 h1:m/CM1UfOkoBTglGO5CUTKnIKKOApOYxkcP2qn0F9tJk= +github.com/uptrace/bun/dialect/pgdialect v1.1.12/go.mod h1:Ij6WIxQILxLlL2frUBxUBOZJtLElD2QQNDcu/PWDHTc= +github.com/uptrace/bun/driver/pgdriver v1.1.12 h1:3rRWB1GK0psTJrHwxzNfEij2MLibggiLdTqjTtfHc1w= +github.com/uptrace/bun/driver/pgdriver v1.1.12/go.mod h1:ssYUP+qwSEgeDDS1xm2XBip9el1y9Mi5mTAvLoiADLM= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.45.0 h1:zPkkzpIn8tdHZUrVa6PzYd0i5verqiPSkgTd3bSUcpA= github.com/valyala/fasthttp v1.45.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -50,6 +83,7 @@ golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -70,6 +104,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -78,3 +114,8 @@ golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo= +mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw= diff --git a/internal/api/apikeys.go b/internal/api/apikeys.go new file mode 100644 index 0000000..23adb79 --- /dev/null +++ b/internal/api/apikeys.go @@ -0,0 +1,15 @@ +package api + +import "github.com/gofiber/fiber/v2" + +func HandleApiKeysGetAll(c *fiber.Ctx) error { + return nil +} + +func HandleApiKeysPost(c *fiber.Ctx) error { + return nil +} + +func HandleApiKeysDelete(c *fiber.Ctx) error { + return nil +} diff --git a/internal/api/urls.go b/internal/api/urls.go new file mode 100644 index 0000000..bbd46c8 --- /dev/null +++ b/internal/api/urls.go @@ -0,0 +1,91 @@ +package api + +import ( + "codeberg.org/lauralani/go-urlsh/internal/misc" + "codeberg.org/lauralani/go-urlsh/models" + "context" + "encoding/json" + "fmt" + "github.com/gofiber/fiber/v2" + "log" + "time" +) + +func HandleLinkGetAll(c *fiber.Ctx) error { + var links []models.Link + + err := models.DB.NewSelect().Model(&links).Scan(context.Background()) + if err != nil { + return fmt.Errorf("error querying links: %v", err.Error()) + } + + for _, link := range links { + log.Printf("id: %v, url: %v", link.ID, link.URL) + } + c.JSON(links) + return nil +} + +func HandleLinkGet(c *fiber.Ctx) error { + return nil +} + +func HandleLinkPost(c *fiber.Ctx) error { + // TODO: Add Auth + var newlink models.Link + + err := json.Unmarshal(c.Body(), &newlink) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, "400 Bad Request: "+err.Error()) + } + + // TODO: check if ID is already taken when ID is given + + if newlink.ID == "" { + newlink.ID = misc.RandomString(6) + } + + now := time.Now() + newlink.Created = now + newlink.Modified = now + + _, err = models.DB.NewInsert().Model(&newlink).Exec(context.Background()) + if err != nil { + return fiber.NewError(fiber.StatusInternalServerError, "500 Internal Server Error: "+err.Error()) + } + + c.Append("Location", c.BaseURL()+"/api/v1/links/"+newlink.ID) + c.Status(200) + c.JSON(newlink) + + return nil +} + +func HandleLinkPut(c *fiber.Ctx) error { + return nil +} + +func HandleLinkDelete(c *fiber.Ctx) error { + id := c.Params("id") + + if id == "" { + return fiber.NewError(fiber.StatusBadRequest, "400 Bad Request") + } + + numrows, err := models.DB.NewSelect().Model((*models.Link)(nil)).Where("id = ?", id).Count(context.Background()) + if err != nil { + log.Println(err.Error()) + return fiber.NewError(fiber.StatusInternalServerError, "500 Internal Server Error") + } + + if numrows < 1 { + return fiber.NewError(fiber.StatusNotFound, "404 Not Found") + } + + _, err = models.DB.NewDelete().Model((*models.Link)(nil)).Where("id = ?", id).Exec(context.Background()) + if err != nil { + log.Println(err.Error()) + return fiber.NewError(fiber.StatusInternalServerError, "500 Internal Server Error") + } + return nil +} diff --git a/internal/app/fiber.go b/internal/app/fiber.go index 9263bbc..3c05f29 100644 --- a/internal/app/fiber.go +++ b/internal/app/fiber.go @@ -1,6 +1,7 @@ package app import ( + "codeberg.org/lauralani/go-urlsh/internal/api" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/compress" "github.com/gofiber/fiber/v2/middleware/cors" @@ -34,7 +35,6 @@ func SetupFiber() error { fiberapp := fiber.New(fiber.Config{ AppName: "go-urlsh", - GETOnly: true, ProxyHeader: proxyheader, Prefork: prod, ErrorHandler: HandleError, @@ -50,9 +50,15 @@ func SetupFiber() error { v1 := fiberapp.Group("/api/v1") v1.Use(cors.New(cors.Config{AllowOrigins: "*"})) - //v1.Get("/films", api.HandleFilmAll) - //v1.Get("/films/random", api.HandleFilmRandom) - //v1.Get("/films/:id", api.HandleFilmSingle) + v1.Get("/links", api.HandleLinkGetAll) + v1.Get("/links/:id", api.HandleLinkGet) + v1.Put("/links/:id", api.HandleLinkPut) + v1.Post("/links", api.HandleLinkPost) + v1.Delete("/links/:id", api.HandleLinkDelete) + + v1.Get("/apikeys", api.HandleApiKeysGetAll) + v1.Post("/apikeys", api.HandleApiKeysPost) + v1.Delete("/apikeys/:id", api.HandleApiKeysPost) listenerr := fiberapp.Listen(ip + ":" + port) if listenerr != nil { diff --git a/internal/db/initialize.go b/internal/db/initialize.go new file mode 100644 index 0000000..3a97b73 --- /dev/null +++ b/internal/db/initialize.go @@ -0,0 +1,23 @@ +package db + +import ( + "codeberg.org/lauralani/go-urlsh/models" + "context" + "database/sql" + "fmt" + "github.com/uptrace/bun" + "github.com/uptrace/bun/dialect/pgdialect" + "github.com/uptrace/bun/driver/pgdriver" + "os" +) + +func InitializeDB() error { + sqldb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(os.Getenv("DATABASE_URL")))) + models.DB = bun.NewDB(sqldb, pgdialect.New()) + + _, err := models.DB.NewCreateTable().IfNotExists().Model((*models.Link)(nil)).Exec(context.Background()) + if err != nil { + return fmt.Errorf("couldn't create database: [%w]", err) + } + return nil +} diff --git a/internal/misc/misc.go b/internal/misc/misc.go new file mode 100644 index 0000000..18d5e6c --- /dev/null +++ b/internal/misc/misc.go @@ -0,0 +1,15 @@ +package misc + +import ( + "math/rand" +) + +func RandomString(n int) string { + var letters = []rune("abcdefghijklmnopqrstuvwxyz0123456789") + + s := make([]rune, n) + for i := range s { + s[i] = letters[rand.Intn(len(letters))] + } + return string(s) +} diff --git a/models/db.go b/models/db.go index e0a44a2..e0ab6e9 100644 --- a/models/db.go +++ b/models/db.go @@ -1,5 +1,7 @@ package models -import "database/sql" +import ( + "github.com/uptrace/bun" +) -var DB *sql.DB +var DB *bun.DB diff --git a/models/links.go b/models/links.go new file mode 100644 index 0000000..f96f381 --- /dev/null +++ b/models/links.go @@ -0,0 +1,15 @@ +package models + +import ( + "github.com/uptrace/bun" + "time" +) + +type Link struct { + bun.BaseModel `bun:"table:links"` + ID string `bun:"id,pk" json:"id,omitempty"` + Created time.Time `bun:"created" json:"created,omitempty"` + Modified time.Time `bun:"modified" json:"modified,omitempty"` + URL string `bun:"url,notnull" json:"url"` + Description string `bun:"description" json:"description,omitempty"` +}