From ef6abee17371e975e5023eb29275c0dbd47e2c5f Mon Sep 17 00:00:00 2001 From: Marceline Brook Date: Mon, 1 Aug 2022 15:52:33 +0100 Subject: [PATCH 1/7] Autogenerated Adjustments for Docker Absence --- go.mod | 26 +++++++++++++++++++++++++- go.sum | 16 ---------------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index 9c14db8..f274d52 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,32 @@ go 1.17 require ( cloud.google.com/go/datastore v1.6.0 - github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab github.com/joho/godotenv v1.4.0 google.golang.org/api v0.60.0 ) + +require ( + cloud.google.com/go v0.97.0 // indirect + github.com/census-instrumentation/opencensus-proto v0.2.1 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 // indirect + github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed // indirect + github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect + github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0 // indirect + github.com/envoyproxy/protoc-gen-validate v0.1.0 // indirect + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/go-cmp v0.5.6 // indirect + github.com/googleapis/gax-go/v2 v2.1.1 // indirect + go.opencensus.io v0.23.0 // indirect + golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 // indirect + golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1 // indirect + golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 // indirect + golang.org/x/text v0.3.6 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20211021150943-2b146023228c // indirect + google.golang.org/grpc v1.40.0 // indirect + google.golang.org/protobuf v1.27.1 // indirect +) diff --git a/go.sum b/go.sum index 856c7ae..87b9964 100644 --- a/go.sum +++ b/go.sum @@ -22,7 +22,6 @@ cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAV cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3 h1:wPBktZFzYBcCZVARvwVKqH1uEj+aLXofJEtrb4oOsio= cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.97.0 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8= @@ -68,7 +67,6 @@ github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed h1:OZmjad4L3H8ncOIR8rn github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -103,7 +101,6 @@ github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+Licev github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= @@ -157,7 +154,6 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU= @@ -172,12 +168,9 @@ github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwA github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -187,7 +180,6 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -207,7 +199,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -293,7 +284,6 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a h1:4Kd8OPUx1xgUwrHDaviWZO8MsgoZTZYC3g+8m16RBww= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1 h1:B333XXssMuKQeBwiNODx4TupZy7bf4sxFZnN2ZOcvUE= @@ -351,7 +341,6 @@ golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/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/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -451,7 +440,6 @@ google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59t google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0 h1:ECJUVngj71QI6XEm7b1sAf8BljU5inEhMbKPR8Lxhhk= google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= @@ -516,7 +504,6 @@ google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8 h1:XosVttQUxX8erNhEruTu053/VchgYuksoS9Bj/OITjU= google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= @@ -563,17 +550,14 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 4cad38e0408e812993d1763fa920c68ce0e0f3e4 Mon Sep 17 00:00:00 2001 From: Marceline Brook Date: Mon, 1 Aug 2022 15:59:31 +0100 Subject: [PATCH 2/7] 1. Refactor to remove duplicate code --- controllers/library.go | 62 ++++++++++++++++++++++++++---------------- main.go | 31 --------------------- server/router.go | 2 +- 3 files changed, 39 insertions(+), 56 deletions(-) diff --git a/controllers/library.go b/controllers/library.go index 1b05601..5cb2ea5 100644 --- a/controllers/library.go +++ b/controllers/library.go @@ -14,54 +14,64 @@ import ( "acme-books/models" ) -type LibraryController struct{} +type LibraryController struct { + ctx context.Context + client *datastore.Client +} -func (lc LibraryController) GetByKey(params martini.Params, w http.ResponseWriter) { - ctx := context.Background() - client, _ := datastore.NewClient(ctx, "acme-books") +func NewLibraryController() *LibraryController { + lc := new(LibraryController) + lc.ctx = context.Background() + lc.client, _ = datastore.NewClient(lc.ctx, "acme-books") - defer client.Close() + books := []models.Book{ + {Id: 1, Author: "George Orwell", Title: "1984", Borrowed: false}, + {Id: 2, Author: "George Orwell", Title: "Animal Farm", Borrowed: false}, + {Id: 3, Author: "Robert Jordan", Title: "Eye of the world", Borrowed: false}, + {Id: 4, Author: "Various", Title: "Collins Dictionary", Borrowed: false}, + } - id, err := strconv.Atoi(params["id"]) + var keys []*datastore.Key - if err != nil { + for _, book := range books { + keys = append(keys, datastore.IDKey("Book", book.Id, nil)) + } + + if _, err := lc.client.PutMulti(lc.ctx, keys, books); err != nil { fmt.Println(err) - w.WriteHeader(http.StatusBadRequest) - return } - var book models.Book - key := datastore.IDKey("Book", int64(id), nil) + return lc +} +func (lc LibraryController) Close() error { + return lc.client.Close() +} - err = client.Get(ctx, key, &book) +func (lc LibraryController) GetByKey(params martini.Params, w http.ResponseWriter) { + id, err := strconv.Atoi(params["id"]) if err != nil { fmt.Println(err) - w.WriteHeader(http.StatusInternalServerError) + w.WriteHeader(http.StatusBadRequest) return } - jsonStr, err := json.MarshalIndent(book, "", " ") - + key := datastore.IDKey("Book", int64(id), nil) + var book models.Book + err = lc.client.Get(lc.ctx, key, &book) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } - w.WriteHeader(http.StatusOK) - w.Write(jsonStr) + writeJson(book, w) } func (lc LibraryController) ListAll(r *http.Request, w http.ResponseWriter) { - ctx := context.Background() - client, _ := datastore.NewClient(ctx, "acme-books") - - defer client.Close() var output []models.Book - - it := client.Run(ctx, datastore.NewQuery("Book")) + it := lc.client.Run(lc.ctx, datastore.NewQuery("Book")) for { var b models.Book _, err := it.Next(&b) @@ -72,7 +82,11 @@ func (lc LibraryController) ListAll(r *http.Request, w http.ResponseWriter) { output = append(output, b) } - jsonStr, err := json.MarshalIndent(output, "", " ") + writeJson(output, w) +} + +func writeJson(item interface{}, w http.ResponseWriter) { + jsonStr, err := json.MarshalIndent(item, "", " ") if err != nil { fmt.Println(err) diff --git a/main.go b/main.go index 40f0b27..109e2e7 100644 --- a/main.go +++ b/main.go @@ -1,14 +1,9 @@ package main import ( - "context" - "fmt" "log" "os" - "cloud.google.com/go/datastore" - - "acme-books/models" "acme-books/server" "github.com/joho/godotenv" @@ -20,8 +15,6 @@ func main() { log.Fatal("Error loading .env file! Did you forget to run `gcloud beta emulators datastore env-init > .env`") } - bootstrapBooks() - host := getEnvWithDefault("HOST", "localhost") port := getEnvWithDefault("PORT", "3030") @@ -34,27 +27,3 @@ func getEnvWithDefault(key, fallback string) string { } return fallback } - -func bootstrapBooks() { - ctx := context.Background() - client, _ := datastore.NewClient(ctx, "acme-books") - - defer client.Close() - - books := []models.Book{ - {Id: 1, Author: "George Orwell", Title: "1984", Borrowed: false}, - {Id: 2, Author: "George Orwell", Title: "Animal Farm", Borrowed: false}, - {Id: 3, Author: "Robert Jordan", Title: "Eye of the world", Borrowed: false}, - {Id: 4, Author: "Various", Title: "Collins Dictionary", Borrowed: false}, - } - - var keys []*datastore.Key - - for _, book := range books { - keys = append(keys, datastore.IDKey("Book", book.Id, nil)) - } - - if _, err := client.PutMulti(ctx, keys, books); err != nil { - fmt.Println(err) - } -} diff --git a/server/router.go b/server/router.go index 70f082c..6f2a048 100644 --- a/server/router.go +++ b/server/router.go @@ -7,7 +7,7 @@ import ( ) func NewRouter() *martini.ClassicMartini { - libraryController := new(controllers.LibraryController) + libraryController := controllers.NewLibraryController() router := martini.Classic() From f872084d2ed248e9456e4cdd5eaf34cc29a30feb Mon Sep 17 00:00:00 2001 From: Marceline Brook Date: Mon, 1 Aug 2022 16:05:09 +0100 Subject: [PATCH 3/7] 2. Ordered book list by Id --- controllers/library.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/library.go b/controllers/library.go index 5cb2ea5..987ac1a 100644 --- a/controllers/library.go +++ b/controllers/library.go @@ -71,7 +71,7 @@ func (lc LibraryController) GetByKey(params martini.Params, w http.ResponseWrite func (lc LibraryController) ListAll(r *http.Request, w http.ResponseWriter) { var output []models.Book - it := lc.client.Run(lc.ctx, datastore.NewQuery("Book")) + it := lc.client.Run(lc.ctx, datastore.NewQuery("Book").Order("Id")) for { var b models.Book _, err := it.Next(&b) From 727149fb8f4c06f3816216e95548b9b502a63b9e Mon Sep 17 00:00:00 2001 From: Marceline Brook Date: Tue, 2 Aug 2022 10:38:47 +0100 Subject: [PATCH 4/7] 3. An incredibly over-engineered way to do Filtering --- controllers/library.go | 69 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/controllers/library.go b/controllers/library.go index 987ac1a..dc8bca2 100644 --- a/controllers/library.go +++ b/controllers/library.go @@ -5,13 +5,12 @@ import ( "encoding/json" "fmt" "net/http" + "regexp" "strconv" + "acme-books/models" "cloud.google.com/go/datastore" "github.com/go-martini/martini" - "google.golang.org/api/iterator" - - "acme-books/models" ) type LibraryController struct { @@ -69,13 +68,73 @@ func (lc LibraryController) GetByKey(params martini.Params, w http.ResponseWrite } func (lc LibraryController) ListAll(r *http.Request, w http.ResponseWriter) { + filter := r.URL.Query().Get("q") var output []models.Book - it := lc.client.Run(lc.ctx, datastore.NewQuery("Book").Order("Id")) + query := datastore.NewQuery("Book") + + if filter != "" { + splitIndices := regexp.MustCompile("(<=|<|>=|>|=)").FindStringIndex(filter) + if len(splitIndices) < 2 { + w.WriteHeader(http.StatusBadRequest) + return + } + sepIndex := splitIndices[1] + fieldName := filter[:splitIndices[0]] + filterStr := filter[:sepIndex] + + metaQuery := datastore.NewQuery("__property__") + type Prop struct { + Repr []string `datastore:"property_representation"` + } + var props []Prop + + keys, err := lc.client.GetAll(lc.ctx, metaQuery, &props) + //fmt.Println(props) + //fmt.Println(keys) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + return + } + + var columnKind string + ok := false + for i, k := range keys { + if k.Name == fieldName { + columnKind = props[i].Repr[0] + ok = true + break + } + } + if !ok { + w.WriteHeader(http.StatusBadRequest) + return + } + + var filterVal interface{} + switch columnKind { + case "BOOLEAN": + filterVal, err = strconv.ParseBool(filter[sepIndex:]) + case "INT64": + filterVal, err = strconv.Atoi(filter[sepIndex:]) + default: + filterVal = filter[sepIndex:] + } + //fmt.Println(fieldName) + //fmt.Println(filterStr) + //fmt.Println(filterVal) + + query = query.Filter(filterStr, filterVal) + + } + + query = query.Order("Id") + it := lc.client.Run(lc.ctx, query) + for { var b models.Book _, err := it.Next(&b) - if err == iterator.Done { + if err != nil { fmt.Println(err) break } From a7d2ab95d2ac31610e2f0ea22629e9d0b2be63ba Mon Sep 17 00:00:00 2001 From: Marceline Brook Date: Tue, 2 Aug 2022 11:52:56 +0100 Subject: [PATCH 5/7] 4. Added borrow and return endpoints --- controllers/library.go | 40 ++++++++++++++++++++++++++++++++++++++++ server/router.go | 2 ++ 2 files changed, 42 insertions(+) diff --git a/controllers/library.go b/controllers/library.go index dc8bca2..467dc94 100644 --- a/controllers/library.go +++ b/controllers/library.go @@ -144,6 +144,46 @@ func (lc LibraryController) ListAll(r *http.Request, w http.ResponseWriter) { writeJson(output, w) } +func (lc LibraryController) Borrow(params martini.Params, w http.ResponseWriter) { + lc.SetBorrowed(params, w, true) + return +} + +func (lc LibraryController) Return(params martini.Params, w http.ResponseWriter) { + lc.SetBorrowed(params, w, false) + return +} +func (lc LibraryController) SetBorrowed(params martini.Params, w http.ResponseWriter, borrowed bool) { + id, err := strconv.Atoi(params["id"]) + if err != nil { + fmt.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + key := datastore.IDKey("Book", int64(id), nil) + + var book models.Book + err = lc.client.Get(lc.ctx, key, &book) + if err != nil { + fmt.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + if book.Borrowed == borrowed { + w.WriteHeader(http.StatusBadRequest) + return + } + book.Borrowed = borrowed + _, err = lc.client.Mutate(lc.ctx, datastore.NewUpdate(key, &book)) + if err != nil { + fmt.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + w.WriteHeader(http.StatusNoContent) + return +} + func writeJson(item interface{}, w http.ResponseWriter) { jsonStr, err := json.MarshalIndent(item, "", " ") diff --git a/server/router.go b/server/router.go index 6f2a048..079eab4 100644 --- a/server/router.go +++ b/server/router.go @@ -13,6 +13,8 @@ func NewRouter() *martini.ClassicMartini { router.Get("/books", libraryController.ListAll) router.Get("/books/:id", libraryController.GetByKey) + router.Put("/books/:id/borrow", libraryController.Borrow) + router.Put("/books/:id/return", libraryController.Return) return router } From ecf5b00301b12475d7b09edaf1832974ecfc0775 Mon Sep 17 00:00:00 2001 From: Marceline Brook Date: Tue, 2 Aug 2022 14:29:21 +0100 Subject: [PATCH 6/7] 5. Added insert endpoint --- controllers/library.go | 53 ++++++++++++++++++++++++++++++++++++++++++ server/router.go | 1 + 2 files changed, 54 insertions(+) diff --git a/controllers/library.go b/controllers/library.go index 467dc94..eb4c5ba 100644 --- a/controllers/library.go +++ b/controllers/library.go @@ -1,9 +1,11 @@ package controllers import ( + "bytes" "context" "encoding/json" "fmt" + "io" "net/http" "regexp" "strconv" @@ -184,6 +186,57 @@ func (lc LibraryController) SetBorrowed(params martini.Params, w http.ResponseWr return } +func (lc LibraryController) New(r *http.Request, w http.ResponseWriter) { + var book models.Book + body := new(bytes.Buffer) + + _, err := io.Copy(body, r.Body) + if err != nil { + fmt.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + + err = json.Unmarshal(body.Bytes(), &book) + if err != nil { + fmt.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + + key := datastore.IncompleteKey("Book", nil) + fmt.Println(key) + key, err = lc.client.Put(lc.ctx, key, &book) + fmt.Println(key) + + if err != nil { + fmt.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + + type bookWithKey struct { + Key string + models.Book + } + amendedBook := *new(bookWithKey) + amendedBook.Key = (*key).String() + amendedBook.Book = book + + fmt.Println("AmendedBook:", amendedBook) + + jsonStr, err := json.MarshalIndent(amendedBook, "", " ") + if err != nil { + fmt.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + + fmt.Println(string(jsonStr)) + w.WriteHeader(http.StatusOK) + w.Write(jsonStr) +} + func writeJson(item interface{}, w http.ResponseWriter) { jsonStr, err := json.MarshalIndent(item, "", " ") diff --git a/server/router.go b/server/router.go index 079eab4..442bd92 100644 --- a/server/router.go +++ b/server/router.go @@ -15,6 +15,7 @@ func NewRouter() *martini.ClassicMartini { router.Get("/books/:id", libraryController.GetByKey) router.Put("/books/:id/borrow", libraryController.Borrow) router.Put("/books/:id/return", libraryController.Return) + router.Post("/book", libraryController.New) return router } From 53af033d644e4330c694ba1835b87e7aac00d771 Mon Sep 17 00:00:00 2001 From: Marceline Brook Date: Tue, 2 Aug 2022 14:57:59 +0100 Subject: [PATCH 7/7] Refactoring to add controllers.handleNoneNilErr() --- controllers/library.go | 73 +++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 47 deletions(-) diff --git a/controllers/library.go b/controllers/library.go index eb4c5ba..47f26ad 100644 --- a/controllers/library.go +++ b/controllers/library.go @@ -51,18 +51,14 @@ func (lc LibraryController) Close() error { func (lc LibraryController) GetByKey(params martini.Params, w http.ResponseWriter) { id, err := strconv.Atoi(params["id"]) - if err != nil { - fmt.Println(err) - w.WriteHeader(http.StatusBadRequest) + if handleNoneNilErr(err, w, http.StatusBadRequest) { return } key := datastore.IDKey("Book", int64(id), nil) var book models.Book err = lc.client.Get(lc.ctx, key, &book) - if err != nil { - fmt.Println(err) - w.WriteHeader(http.StatusInternalServerError) + if handleNoneNilErr(err, w, http.StatusInternalServerError) { return } @@ -87,15 +83,12 @@ func (lc LibraryController) ListAll(r *http.Request, w http.ResponseWriter) { metaQuery := datastore.NewQuery("__property__") type Prop struct { - Repr []string `datastore:"property_representation"` + Reps []string `datastore:"property_representation"` } var props []Prop keys, err := lc.client.GetAll(lc.ctx, metaQuery, &props) - //fmt.Println(props) - //fmt.Println(keys) - if err != nil { - w.WriteHeader(http.StatusBadRequest) + if handleNoneNilErr(err, w, http.StatusBadRequest) { return } @@ -103,7 +96,7 @@ func (lc LibraryController) ListAll(r *http.Request, w http.ResponseWriter) { ok := false for i, k := range keys { if k.Name == fieldName { - columnKind = props[i].Repr[0] + columnKind = props[i].Reps[0] ok = true break } @@ -122,9 +115,6 @@ func (lc LibraryController) ListAll(r *http.Request, w http.ResponseWriter) { default: filterVal = filter[sepIndex:] } - //fmt.Println(fieldName) - //fmt.Println(filterStr) - //fmt.Println(filterVal) query = query.Filter(filterStr, filterVal) @@ -157,18 +147,14 @@ func (lc LibraryController) Return(params martini.Params, w http.ResponseWriter) } func (lc LibraryController) SetBorrowed(params martini.Params, w http.ResponseWriter, borrowed bool) { id, err := strconv.Atoi(params["id"]) - if err != nil { - fmt.Println(err) - w.WriteHeader(http.StatusBadRequest) + if handleNoneNilErr(err, w, http.StatusBadRequest) { return } key := datastore.IDKey("Book", int64(id), nil) var book models.Book err = lc.client.Get(lc.ctx, key, &book) - if err != nil { - fmt.Println(err) - w.WriteHeader(http.StatusBadRequest) + if handleNoneNilErr(err, w, http.StatusBadRequest) { return } if book.Borrowed == borrowed { @@ -177,9 +163,7 @@ func (lc LibraryController) SetBorrowed(params martini.Params, w http.ResponseWr } book.Borrowed = borrowed _, err = lc.client.Mutate(lc.ctx, datastore.NewUpdate(key, &book)) - if err != nil { - fmt.Println(err) - w.WriteHeader(http.StatusBadRequest) + if handleNoneNilErr(err, w, http.StatusBadRequest) { return } w.WriteHeader(http.StatusNoContent) @@ -191,27 +175,18 @@ func (lc LibraryController) New(r *http.Request, w http.ResponseWriter) { body := new(bytes.Buffer) _, err := io.Copy(body, r.Body) - if err != nil { - fmt.Println(err) - w.WriteHeader(http.StatusBadRequest) + if handleNoneNilErr(err, w, http.StatusBadRequest) { return } err = json.Unmarshal(body.Bytes(), &book) - if err != nil { - fmt.Println(err) - w.WriteHeader(http.StatusBadRequest) + if handleNoneNilErr(err, w, http.StatusBadRequest) { return } key := datastore.IncompleteKey("Book", nil) - fmt.Println(key) key, err = lc.client.Put(lc.ctx, key, &book) - fmt.Println(key) - - if err != nil { - fmt.Println(err) - w.WriteHeader(http.StatusBadRequest) + if handleNoneNilErr(err, w, http.StatusBadRequest) { return } @@ -223,29 +198,33 @@ func (lc LibraryController) New(r *http.Request, w http.ResponseWriter) { amendedBook.Key = (*key).String() amendedBook.Book = book - fmt.Println("AmendedBook:", amendedBook) - jsonStr, err := json.MarshalIndent(amendedBook, "", " ") - if err != nil { - fmt.Println(err) - w.WriteHeader(http.StatusBadRequest) + if handleNoneNilErr(err, w, http.StatusBadRequest) { return } - fmt.Println(string(jsonStr)) w.WriteHeader(http.StatusOK) - w.Write(jsonStr) + _, err = w.Write(jsonStr) + handleNoneNilErr(err, w, http.StatusInternalServerError) } func writeJson(item interface{}, w http.ResponseWriter) { jsonStr, err := json.MarshalIndent(item, "", " ") - if err != nil { - fmt.Println(err) - w.WriteHeader(http.StatusInternalServerError) + if handleNoneNilErr(err, w, http.StatusInternalServerError) { return } w.WriteHeader(http.StatusOK) - w.Write(jsonStr) + _, err = w.Write(jsonStr) + handleNoneNilErr(err, w, http.StatusInternalServerError) +} + +func handleNoneNilErr(err error, w http.ResponseWriter, httpResponseStatusCode int) bool { + if err != nil { + fmt.Println(err) + w.WriteHeader(httpResponseStatusCode) + return true + } + return false }