diff --git a/.env b/.env deleted file mode 100644 index b5abba7..0000000 --- a/.env +++ /dev/null @@ -1,14 +0,0 @@ -HOST="0.0.0.0" -POSTGRES_PASSWORD="postgres" -POSTGRES_DB="lah_db" -POSTGRES_USER="postgres" -POSTGRES_PORT=5432 -BACKEND_PORT=9000 -FRONTEND_PORT=3000 -REDIS_HOST="127.0.0.1" -REDIS_PASSWORD=null -REDIS_ENDPOINT_URL=redis://redis:6379 -REDIS_PORT=6379 -SESSION_TYPE=redis -CHAT_CONFIG=backend.config.ConfigDev -CHAT_PORT=8080 \ No newline at end of file diff --git a/backend/messaging/Dockerfile b/backend/messaging/Dockerfile new file mode 100644 index 0000000..42d3a18 --- /dev/null +++ b/backend/messaging/Dockerfile @@ -0,0 +1,11 @@ +FROM golang:latest + +WORKDIR /usr/src/app + +COPY go.mod go.sum ./ +RUN go mod download && go mod verify + +COPY . . +RUN go build -v -o /usr/local/bin/app ./ + +CMD ["app"] \ No newline at end of file diff --git a/backend/messaging/README.md b/backend/messaging/README.md new file mode 100644 index 0000000..7b9ddcb --- /dev/null +++ b/backend/messaging/README.md @@ -0,0 +1,129 @@ +# Build Messaging: +> Requires CHAT_PORT environment variable +> +> In backend/messaging directory: +> ``` +> go run main.go +> ``` + + +# API Routes: + +## GET /message +> ### Request Example: +> > No Request Parameters +> ### Response Example: +> > ``` +> > Status Code: 200 +> > +> > [ +> > { +> > "id": 1, +> > "sender_id": 1, +> > "receiver_id": 2, +> > "time_sent": "2022-06-06T00:43:21Z", +> > "body": "welp" +> > }, +> > { +> > "id": 2, +> > "sender_id": 1, +> > "receiver_id": 2, +> > "time_sent": "2022-06-06T00:43:58Z", +> > "body": "welp" +> > }, +> > { +> > "id": 3, +> > "sender_id": 1, +> > "receiver_id": 2, +> > "time_sent": "2022-06-06T00:44:59Z", +> > "body": "welp" +> > } +> > ] +> > ``` + + +## POST /message +> ### Request Example: +> > ``` +> > { +> > "sender_id": 1, +> > "receiver_id": 2, +> > "time_sent": "2022-06-06T00:43:21Z", +> > "body": "welp" +> > } +> > ``` +> ### Response Example: + +> > ``` +> > Status Code: 200 +> > +> > ``` +> > { +> > "id": 1 +> > "sender_id": 1, +> > "receiver_id": 2, +> > "time_sent": "2022-06-06T00:43:21Z", +> > "body": "welp" +> > } +> > ``` + +## GET /message/:id +> ### Request Example: +> > id: integer +> ### Response Example: +> > ``` +> > Status Code: 200 +> > +> > ``` +> > { +> > "id": 1 +> > "sender_id": 1, +> > "receiver_id": 2, +> > "time_sent": "2022-06-06T00:43:21Z", +> > "body": "welp" +> > } +> > ``` + +## DELETE /message/:id +> ### Request Example: +> > id: integer +> ### Response Example: +> > ``` +> > Status Code: 200 +> > +> > ``` +> > null +> > ``` + +## GET /message/user/:sid/to/:rid +> ### Request Example: +> > sid: integer (sender id) +> > rid: integer (receiver id) +> ### Response Example: +> > ``` +> > Status Code: 200 +> > +> > [ +> > { +> > "id": 1, +> > "sender_id": 1, +> > "receiver_id": 2, +> > "time_sent": "2022-06-06T00:43:21Z", +> > "body": "welp" +> > }, +> > { +> > "id": 2, +> > "sender_id": 1, +> > "receiver_id": 2, +> > "time_sent": "2022-06-06T00:43:58Z", +> > "body": "welp" +> > }, +> > { +> > "id": 3, +> > "sender_id": 1, +> > "receiver_id": 2, +> > "time_sent": "2022-06-06T00:44:59Z", +> > "body": "welp" +> > } +> > ] +> > ``` diff --git a/backend/messaging/db/db.go b/backend/messaging/db/db.go new file mode 100644 index 0000000..033f5f6 --- /dev/null +++ b/backend/messaging/db/db.go @@ -0,0 +1,57 @@ +package db + +import ( + "database/sql" + "fmt" + "io/ioutil" + "os" + + _ "github.com/lib/pq" +) + +type DbStruct[T interface{}] interface { + QueryAs(T, string) +} + +type Database struct { + Client *sql.DB +} + +func New(db_name string, username string, password string) Database { + conn_str := fmt.Sprintf("postgres://%s:%s@%s?sslmode=disable", username, password, db_name) + db, err := sql.Open("postgres", conn_str) + if err != nil { + panic(err) + } + return Database{ + Client: db, + } +} + +func NewFromEnv() Database { + db_name := os.Getenv("POSTGRES_DB") + user := os.Getenv("POSTGRES_USER") + pw := os.Getenv("POSTGRES_PASSWORD") + return New(db_name, user, pw) +} + +func (db Database) QueryFromFile(file string) bool { + q, err := ioutil.ReadFile(file) + if err != nil { + return false + } + return db.Query(string(q)) +} + +func (db Database) Query(query string) bool { + _, err := db.Client.Exec(query) + return err == nil +} + +func (db Database) QueryRows(query string) *sql.Rows { + rows, err := db.Client.Query(query) + if err != nil { + return nil + } + return rows +} diff --git a/backend/messaging/db/queries/create_tables.sql b/backend/messaging/db/queries/create_tables.sql new file mode 100644 index 0000000..d7ca2e2 --- /dev/null +++ b/backend/messaging/db/queries/create_tables.sql @@ -0,0 +1,7 @@ +CREATE TABLE IF NOT EXISTS messages ( + id SERIAL PRIMARY KEY NOT NULL, + sender_id INT NOT NULL, + receiver_id INT NOT NULL, + time_sent TIMESTAMPTZ, + body TEXT +); \ No newline at end of file diff --git a/backend/messaging/go.mod b/backend/messaging/go.mod new file mode 100644 index 0000000..502342d --- /dev/null +++ b/backend/messaging/go.mod @@ -0,0 +1,27 @@ +module messaging + +go 1.18 + +require github.com/gin-gonic/gin v1.8.0 + +require ( + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.14.0 // indirect + github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/go-playground/validator/v10 v10.10.0 // indirect + github.com/goccy/go-json v0.9.7 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/lib/pq v1.10.6 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.0.1 // indirect + github.com/ugorji/go/codec v1.2.7 // indirect + golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect + golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect + golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect + golang.org/x/text v0.3.6 // indirect + google.golang.org/protobuf v1.28.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/backend/messaging/go.sum b/backend/messaging/go.sum new file mode 100644 index 0000000..6a41b9a --- /dev/null +++ b/backend/messaging/go.sum @@ -0,0 +1,89 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +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/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.8.0 h1:4WFH5yycBMA3za5Hnl425yd9ymdw1XPm4666oab+hv4= +github.com/gin-gonic/gin v1.8.0/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= +github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= +github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= +github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= +github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= +github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +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.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraCFObP8S1v6PRp0bLrtU= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/backend/messaging/main.go b/backend/messaging/main.go new file mode 100644 index 0000000..de3816b --- /dev/null +++ b/backend/messaging/main.go @@ -0,0 +1,70 @@ +package main + +import ( + "fmt" + "messaging/db" + "messaging/message" + "os" + "strconv" + + "github.com/gin-gonic/gin" +) + +func main() { + router := gin.Default() + db := db.NewFromEnv() + db.QueryFromFile("db/queries/create_tables.sql") + + msg := router.Group("/message") + + msg.GET("", func(c *gin.Context) { + msgs := message.GetMessages(&db) + fmt.Println(msgs) + c.JSON(200, msgs) + }) + + msg.POST("", func(c *gin.Context) { + var msg message.Message + c.BindJSON(&msg) + + id := msg.ToDb(&db) + msg.Id = &id + c.JSON(200, msg) + }) + + msg.GET(":id", func(c *gin.Context) { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + c.JSON(400, gin.H{"status": "bad request"}) + } + msg := message.FromDb(&db, id) + if msg != nil { + c.JSON(200, msg) + } + c.JSON(400, gin.H{"status": "bad request"}) + }) + + msg.DELETE(":id", func(c *gin.Context) { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + c.JSON(400, gin.H{"status": "bad request"}) + } + if message.DeleteMessage(&db, id) { + c.JSON(200, nil) + } else { + c.JSON(400, gin.H{"status": "bad request"}) + } + }) + + router.GET("/chat/:sid/:rid", func(c *gin.Context) { + sid, serr := strconv.Atoi(c.Param("sid")) + rid, rerr := strconv.Atoi(c.Param("rid")) + if serr != nil || rerr != nil { + c.JSON(400, gin.H{"status": "bad request"}) + } + msgs := message.GetUserMessages(&db, sid, rid) + c.JSON(200, msgs) + }) + + router.Run(fmt.Sprintf(":%s", os.Getenv("MSG_PORT"))) +} diff --git a/backend/messaging/message/message.go b/backend/messaging/message/message.go new file mode 100644 index 0000000..3eb366e --- /dev/null +++ b/backend/messaging/message/message.go @@ -0,0 +1,78 @@ +package message + +import ( + "fmt" + "messaging/db" + "time" +) + +type Message struct { + Id *int64 `db:"id" json:"id"` + Sender int `db:"sender_id" json:"sender_id"` + Receiver int `db:"receiver_id" json:"receiver_id"` + Time time.Time `db:"time_sent" json:"time_sent"` + Body string `db:"body" json:"body"` +} + +func New(sender int, receiver int, time time.Time, body string) Message { + return Message{ + nil, + sender, + receiver, + time, + body, + } +} + +func (m Message) ToDb(db *db.Database) int64 { + var id int64 + err := db.Client.QueryRow(fmt.Sprintf( + "INSERT INTO messages (sender_id, receiver_id, time_sent, body) VALUES (%d, %d, '%s', '%s') RETURNING id;", + m.Sender, + m.Receiver, + m.Time.Local().Format(time.RFC3339), + m.Body)).Scan(&id) + if err != nil { + panic(err) + } + return id +} + +func FromDb(db *db.Database, id int) *Message { + var msg Message + q := fmt.Sprintf("SELECT * FROM messages WHERE id = %d;", id) + fmt.Println(q) + err := db.Client.QueryRow(q).Scan(&msg.Id, &msg.Sender, &msg.Receiver, &msg.Time, &msg.Body) + if err != nil { + return nil + } + return &msg +} + +func GetMessages(db *db.Database) []Message { + var msgs []Message + rows := db.QueryRows("SELECT * FROM messages") + defer rows.Close() + for rows.Next() { + var msg Message + rows.Scan(&msg.Id, &msg.Sender, &msg.Receiver, &msg.Time, &msg.Body) + msgs = append(msgs, msg) + } + return msgs +} + +func GetUserMessages(db *db.Database, id1 int, id2 int) []Message { + var msgs []Message + rows := db.QueryRows(fmt.Sprintf("SELECT * FROM messages WHERE sender_id = %d OR receiver_id = %d ORDER BY time_sent", id1, id2)) + defer rows.Close() + for rows.Next() { + var msg Message + rows.Scan(&msg.Id, &msg.Sender, &msg.Receiver, &msg.Time, &msg.Body) + msgs = append(msgs, msg) + } + return msgs +} + +func DeleteMessage(db *db.Database, id int) bool { + return db.Query(fmt.Sprintf("DELETE FROM messages WHERE id = %d", id)) +} diff --git a/chat.example.env b/chat.example.env deleted file mode 100644 index 1ad2e04..0000000 --- a/chat.example.env +++ /dev/null @@ -1,7 +0,0 @@ -REDIS_HOST="127.0.0.1" -REDIS_ENDPOINT_URL=redis://redis:6379 -REDIS_PASSWORD=null -REDIS_PORT=6379 -SESSION_TYPE=redis -CHAT_CONFIG=backend.config.ConfigDev -CHAT_PORT=8080 \ No newline at end of file diff --git a/docker-compose.chat.yml b/docker-compose.chat.yml deleted file mode 100644 index fa061c7..0000000 --- a/docker-compose.chat.yml +++ /dev/null @@ -1,24 +0,0 @@ -version: '3.1' - -# Define services -services: - - # Chat Microservice - chat: - # Configuration for building the docker image for the service - build: - context: ./chat-service # Use an image built from the specified dockerfile in the current directory. - dockerfile: Dockerfile - ports: - - '${CHAT_PORT}:${CHAT_PORT}' # Forward the exposed port on the container to port on the host machine - restart: unless-stopped - depends_on: - - redis # This service depends on redis. Start that first. - environment: # Pass environment variables to the service - REDIS_HOST: redis - REDIS_PORT: "${REDIS_PORT}" - - # Redis Service - redis: - image: "redis:latest" # Use a public Redis image to build the redis service - restart: unless-stopped \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index ba033eb..f438fc1 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -8,7 +8,7 @@ services: ports: - '${POSTGRES_PORT}:${POSTGRES_PORT}' env_file: - - ./backend/api/.env.docker + - .env api: container_name: api build: ./backend/api @@ -21,6 +21,7 @@ services: - .env depends_on: - db + frontend: container_name: react build: ./frontend @@ -31,23 +32,16 @@ services: - "${FRONTEND_PORT}" depends_on: - api - - chat - chat: - container_name: chat - build: - context: ./chat-service - dockerfile: Dockerfile + messaging: + container_name: messaging + build: ./backend/messaging ports: - - '${CHAT_PORT}:${CHAT_PORT}' - restart: unless-stopped + - '${MSG_PORT}:${MSG_PORT}' + expose: + - "${MSG_PORT}" + restart: always + env_file: + - .env depends_on: - - redis - environment: - REDIS_HOST: redis - REDIS_PORT: "${REDIS_PORT}" - - redis: - container_name: redis - image: "redis:latest" - restart: unless-stopped \ No newline at end of file + - db diff --git a/example.env b/example.env index 1390cd5..ffe23c5 100644 --- a/example.env +++ b/example.env @@ -4,4 +4,5 @@ POSTGRES_DB="lah_db" POSTGRES_USER="postgres" POSTGRES_PORT=5432 BACKEND_PORT=9000 -FRONTEND_PORT=3000 \ No newline at end of file +FRONTEND_PORT=3000 +MSG_PORT=7000 \ No newline at end of file