diff --git a/000_temp/01_rand/main.go b/000_temp/01_rand/main.go old mode 100755 new mode 100644 diff --git a/000_temp/02_hello/main.go b/000_temp/02_hello/main.go old mode 100755 new mode 100644 diff --git a/000_temp/17_hands-on/main.go b/000_temp/17_hands-on/main.go old mode 100755 new mode 100644 diff --git a/000_temp/17_hands-on/tpl.gohtml b/000_temp/17_hands-on/tpl.gohtml old mode 100755 new mode 100644 diff --git a/000_temp/18_svcc-sat/01/00 b/000_temp/18_svcc-sat/01/00 old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/01_unit/.gitignore b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/01_unit/.gitignore old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/01_unit/gulpfile.js b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/01_unit/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/01_unit/package.json b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/01_unit/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/01_unit/src/pack/math.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/01_unit/src/pack/math.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/01_unit/src/pack/math_test.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/01_unit/src/pack/math_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/02_coverage/.gitignore b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/02_coverage/.gitignore old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/02_coverage/cover.out b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/02_coverage/cover.out old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/02_coverage/gulpfile.js b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/02_coverage/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/02_coverage/package.json b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/02_coverage/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/02_coverage/src/pack/math.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/02_coverage/src/pack/math.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/02_coverage/src/pack/math_test.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/02_coverage/src/pack/math_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/03_benchmark/.gitignore b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/03_benchmark/.gitignore old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/03_benchmark/cover.out b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/03_benchmark/cover.out old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/03_benchmark/gulpfile.js b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/03_benchmark/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/03_benchmark/package.json b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/03_benchmark/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/03_benchmark/src/pack/template_test.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/03_benchmark/src/pack/template_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/04_example/.gitignore b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/04_example/.gitignore old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/04_example/cover.out b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/04_example/cover.out old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/04_example/gulpfile.js b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/04_example/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/04_example/package.json b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/04_example/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/04_example/src/pack/example_test.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/04_example/src/pack/example_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/.gitignore b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/.gitignore old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/gulpfile.js b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/index.html b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/index.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/less/_landing-page.less b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/less/_landing-page.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/less/app.less b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/less/app.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/package.json b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/app.css b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/app.css old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/app.js b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/app.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/controllers/CreateController.js b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/controllers/CreateController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/controllers/ManageController.js b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/controllers/ManageController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/controllers/ReviewController.js b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/controllers/ReviewController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/models/PODetail.js b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/models/PODetail.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/models/PurchaseOrder.js b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/models/PurchaseOrder.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/services/CurrencyService.js b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/services/CurrencyService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/services/PurchaseOrderService.js b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/services/PurchaseOrderService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/services/ShippingService.js b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/services/ShippingService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/ui-bootstrap-tpls-0.13.3.min.js b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/js/ui-bootstrap-tpls-0.13.3.min.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/views/create.html b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/views/create.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/views/home.html b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/views/home.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/views/manage.html b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/views/manage.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/views/manageSearch.html b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/views/manageSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/views/review.html b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/views/review.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/views/reviewSearch.html b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/res/views/reviewSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/main.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/main.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/ctrl/controllers.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/ctrl/controllers.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/ctrl/currency.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/ctrl/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/ctrl/home.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/ctrl/home.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/ctrl/purchaseOrder.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/ctrl/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/ctrl/shipping.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/ctrl/shipping.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/gzipserver.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/gzipserver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/model/currency.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/model/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/model/purchaseOrder.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/model/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/model/receiver.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/model/receiver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/model/vendor.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/poms/model/vendor.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/services/orgStructureService/orgStructureService.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/services/orgStructureService/orgStructureService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/services/vendorService/vendorService.go b/000_temp/34_test/go-testing-applications/1-go-testing-applications-m1-exercise-files/business_demo/src/services/vendorService/vendorService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/01_cli/src/pack/math.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/01_cli/src/pack/math.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/01_cli/src/pack/math_test.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/01_cli/src/pack/math_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/02_skip_short_and_verbose/src/pack/math.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/02_skip_short_and_verbose/src/pack/math.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/02_skip_short_and_verbose/src/pack/math_test.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/02_skip_short_and_verbose/src/pack/math_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/03_parallel/src/pack/math.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/03_parallel/src/pack/math.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/03_parallel/src/pack/math_test.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/03_parallel/src/pack/math_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/04_custom_runner/src/pack/math.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/04_custom_runner/src/pack/math.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/04_custom_runner/src/pack/math_test.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/04_custom_runner/src/pack/math_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/05_table_driven/src/pack/math.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/05_table_driven/src/pack/math.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/05_table_driven/src/pack/math_test.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/05_table_driven/src/pack/math_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/index.html b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/index.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/less/_landing-page.less b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/less/_landing-page.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/less/app.less b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/less/app.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/package.json b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/app.css b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/app.css old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/app.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/app.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/controllers/CreateController.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/controllers/CreateController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/controllers/ManageController.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/controllers/ManageController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/controllers/ReviewController.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/controllers/ReviewController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/models/PODetail.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/models/PODetail.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/models/PurchaseOrder.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/models/PurchaseOrder.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/services/CurrencyService.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/services/CurrencyService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/services/PurchaseOrderService.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/services/PurchaseOrderService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/services/ShippingService.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/services/ShippingService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/ui-bootstrap-tpls-0.13.3.min.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/js/ui-bootstrap-tpls-0.13.3.min.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/views/create.html b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/views/create.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/views/home.html b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/views/home.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/views/manage.html b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/views/manage.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/views/manageSearch.html b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/views/manageSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/views/review.html b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/views/review.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/views/reviewSearch.html b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/res/views/reviewSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/main.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/main.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/ctrl/controllers.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/ctrl/controllers.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/ctrl/currency.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/ctrl/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/ctrl/home.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/ctrl/home.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/ctrl/purchaseOrder.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/ctrl/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/ctrl/shipping.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/ctrl/shipping.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/gzipserver.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/gzipserver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/model/currency.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/model/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/model/currency_test.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/model/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/model/purchaseOrder.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/model/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/model/receiver.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/model/receiver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/model/vendor.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/poms/model/vendor.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/services/orgStructureService/orgStructureService.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/services/orgStructureService/orgStructureService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/services/vendorService/vendorService.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/06_business_unit_test/src/services/vendorService/vendorService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/index.html b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/index.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/less/_landing-page.less b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/less/_landing-page.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/less/app.less b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/less/app.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/package.json b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/app.css b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/app.css old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/app.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/app.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/controllers/CreateController.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/controllers/CreateController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/controllers/ManageController.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/controllers/ManageController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/controllers/ReviewController.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/controllers/ReviewController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/models/PODetail.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/models/PODetail.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/models/PurchaseOrder.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/models/PurchaseOrder.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/services/CurrencyService.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/services/CurrencyService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/services/PurchaseOrderService.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/services/PurchaseOrderService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/services/ShippingService.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/services/ShippingService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/ui-bootstrap-tpls-0.13.3.min.js b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/js/ui-bootstrap-tpls-0.13.3.min.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/views/create.html b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/views/create.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/views/home.html b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/views/home.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/views/manage.html b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/views/manage.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/views/manageSearch.html b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/views/manageSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/views/review.html b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/views/review.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/views/reviewSearch.html b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/res/views/reviewSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/main.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/main.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/ctrl/controllers.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/ctrl/controllers.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/ctrl/currency.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/ctrl/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/ctrl/currency_test.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/ctrl/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/ctrl/home.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/ctrl/home.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/ctrl/purchaseOrder.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/ctrl/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/ctrl/shipping.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/ctrl/shipping.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/gzipserver.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/gzipserver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/model/currency.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/model/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/model/currency_test.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/model/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/model/purchaseOrder.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/model/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/model/receiver.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/model/receiver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/model/vendor.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/poms/model/vendor.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/services/orgStructureService/orgStructureService.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/services/orgStructureService/orgStructureService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/services/vendorService/vendorService.go b/000_temp/34_test/go-testing-applications/2-go-testing-applications-m2-exercise-files/07_business_mocks/src/services/vendorService/vendorService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/count.out b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/count.out old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/cover.out b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/cover.out old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/gulpfile.js b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/index.html b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/index.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/less/_landing-page.less b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/less/_landing-page.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/less/app.less b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/less/app.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/model.out b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/model.out old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/package.json b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/app.css b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/app.css old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/app.js b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/app.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/controllers/CreateController.js b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/controllers/CreateController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/controllers/ManageController.js b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/controllers/ManageController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/controllers/ReviewController.js b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/controllers/ReviewController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/models/PODetail.js b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/models/PODetail.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/models/PurchaseOrder.js b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/models/PurchaseOrder.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/services/CurrencyService.js b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/services/CurrencyService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/services/PurchaseOrderService.js b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/services/PurchaseOrderService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/services/ShippingService.js b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/services/ShippingService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/ui-bootstrap-tpls-0.13.3.min.js b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/js/ui-bootstrap-tpls-0.13.3.min.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/views/create.html b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/views/create.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/views/home.html b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/views/home.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/views/manage.html b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/views/manage.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/views/manageSearch.html b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/views/manageSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/views/review.html b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/views/review.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/views/reviewSearch.html b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/res/views/reviewSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/main.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/main.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/ctrl/controllers.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/ctrl/controllers.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/ctrl/currency.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/ctrl/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/ctrl/currency_test.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/ctrl/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/ctrl/home.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/ctrl/home.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/ctrl/purchaseOrder.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/ctrl/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/ctrl/shipping.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/ctrl/shipping.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/gzipserver.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/gzipserver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/model/currency.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/model/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/model/currency_test.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/model/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/model/purchaseOrder.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/model/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/model/receiver.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/model/receiver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/model/vendor.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/poms/model/vendor.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/services/orgStructureService/orgStructureService.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/services/orgStructureService/orgStructureService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/services/vendorService/vendorService.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/01_business/src/services/vendorService/vendorService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/02_heat_map/count.out b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/02_heat_map/count.out old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/02_heat_map/gulpfile.js b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/02_heat_map/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/02_heat_map/package.json b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/02_heat_map/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/02_heat_map/src/pack/numtest.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/02_heat_map/src/pack/numtest.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/02_heat_map/src/pack/numtest_test.go b/000_temp/34_test/go-testing-applications/3-go-testing-applications-m3-exercise-files/02_heat_map/src/pack/numtest_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/01_Value/gulpfile.js b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/01_Value/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/01_Value/package.json b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/01_Value/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/01_Value/src/runner.go b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/01_Value/src/runner.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/02_Check/gulpfile.js b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/02_Check/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/02_Check/package.json b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/02_Check/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/02_Check/src/pack/math.go b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/02_Check/src/pack/math.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/02_Check/src/pack/math_test.go b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/02_Check/src/pack/math_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/02_Check/src/runner.go b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/02_Check/src/runner.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/03_CheckEqual/gulpfile.js b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/03_CheckEqual/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/03_CheckEqual/package.json b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/03_CheckEqual/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/03_CheckEqual/src/pack/quicksort.go b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/03_CheckEqual/src/pack/quicksort.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/03_CheckEqual/src/pack/sort_test.go b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/03_CheckEqual/src/pack/sort_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/03_CheckEqual/src/runner.go b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/03_CheckEqual/src/runner.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/04_Generator/gulpfile.js b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/04_Generator/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/04_Generator/package.json b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/04_Generator/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/04_Generator/src/runner.go b/000_temp/34_test/go-testing-applications/4-go-testing-applications-m4-exercise-files/04_Generator/src/runner.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/1_benchmark_standalone/gulpfile.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/1_benchmark_standalone/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/1_benchmark_standalone/package.json b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/1_benchmark_standalone/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/1_benchmark_standalone/src/pack/weather.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/1_benchmark_standalone/src/pack/weather.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/1_benchmark_standalone/src/runner.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/1_benchmark_standalone/src/runner.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/2_benchmark/gulpfile.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/2_benchmark/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/2_benchmark/package.json b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/2_benchmark/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/2_benchmark/src/pack/weather.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/2_benchmark/src/pack/weather.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/2_benchmark/src/pack/weather_test.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/2_benchmark/src/pack/weather_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/3_timers/gulpfile.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/3_timers/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/3_timers/package.json b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/3_timers/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/3_timers/src/pack/template.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/3_timers/src/pack/template.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/3_timers/src/pack/template_test.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/3_timers/src/pack/template_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/4_parallelism/gulpfile.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/4_parallelism/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/4_parallelism/package.json b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/4_parallelism/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/4_parallelism/src/pack/weather.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/4_parallelism/src/pack/weather.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/4_parallelism/src/pack/weather_test.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/4_parallelism/src/pack/weather_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/5_reportallocs/gulpfile.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/5_reportallocs/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/5_reportallocs/package.json b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/5_reportallocs/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/5_reportallocs/src/pack/template.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/5_reportallocs/src/pack/template.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/5_reportallocs/src/pack/template_test.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/5_reportallocs/src/pack/template_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/gulpfile.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/index.html b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/index.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/less/_landing-page.less b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/less/_landing-page.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/less/app.less b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/less/app.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/package.json b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/app.css b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/app.css old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/app.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/app.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/controllers/CreateController.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/controllers/CreateController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/controllers/ManageController.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/controllers/ManageController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/controllers/ReviewController.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/controllers/ReviewController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/models/PODetail.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/models/PODetail.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/models/PurchaseOrder.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/models/PurchaseOrder.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/services/CurrencyService.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/services/CurrencyService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/services/PurchaseOrderService.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/services/PurchaseOrderService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/services/ShippingService.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/services/ShippingService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/ui-bootstrap-tpls-0.13.3.min.js b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/js/ui-bootstrap-tpls-0.13.3.min.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/views/create.html b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/views/create.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/views/home.html b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/views/home.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/views/manage.html b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/views/manage.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/views/manageSearch.html b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/views/manageSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/views/review.html b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/views/review.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/views/reviewSearch.html b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/res/views/reviewSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/main.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/main.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/benchmark_test.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/benchmark_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/ctrl/controllers.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/ctrl/controllers.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/ctrl/currency.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/ctrl/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/ctrl/currency_test.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/ctrl/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/ctrl/home.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/ctrl/home.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/ctrl/purchaseOrder.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/ctrl/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/ctrl/shipping.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/ctrl/shipping.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/gzipserver.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/gzipserver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/model/currency.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/model/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/model/currency_test.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/model/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/model/purchaseOrder.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/model/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/model/receiver.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/model/receiver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/model/vendor.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/poms/model/vendor.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/services/orgStructureService/orgStructureService.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/services/orgStructureService/orgStructureService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/services/vendorService/vendorService.go b/000_temp/34_test/go-testing-applications/5-go-testing-applications-m5-exercise-files/6_business/src/services/vendorService/vendorService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/6-go-testing-applications-m6-exercise-files/gulpfile.js b/000_temp/34_test/go-testing-applications/6-go-testing-applications-m6-exercise-files/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/6-go-testing-applications-m6-exercise-files/package.json b/000_temp/34_test/go-testing-applications/6-go-testing-applications-m6-exercise-files/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/6-go-testing-applications-m6-exercise-files/src/pack/foo b/000_temp/34_test/go-testing-applications/6-go-testing-applications-m6-exercise-files/src/pack/foo old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/6-go-testing-applications-m6-exercise-files/src/pack/math.go b/000_temp/34_test/go-testing-applications/6-go-testing-applications-m6-exercise-files/src/pack/math.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/6-go-testing-applications-m6-exercise-files/src/pack/math_test.go b/000_temp/34_test/go-testing-applications/6-go-testing-applications-m6-exercise-files/src/pack/math_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/6-go-testing-applications-m6-exercise-files/src/runner.go b/000_temp/34_test/go-testing-applications/6-go-testing-applications-m6-exercise-files/src/runner.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/.gitignore b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/.gitignore old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/gulpfile.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/index.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/index.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/less/_landing-page.less b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/less/_landing-page.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/less/app.less b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/less/app.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/package.json b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/profile b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/profile old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/app.css b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/app.css old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/app.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/app.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/controllers/CreateController.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/controllers/CreateController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/controllers/ManageController.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/controllers/ManageController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/controllers/ReviewController.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/controllers/ReviewController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/models/PODetail.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/models/PODetail.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/models/PurchaseOrder.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/models/PurchaseOrder.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/services/CurrencyService.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/services/CurrencyService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/services/PurchaseOrderService.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/services/PurchaseOrderService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/services/ShippingService.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/services/ShippingService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/ui-bootstrap-tpls-0.13.3.min.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/js/ui-bootstrap-tpls-0.13.3.min.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/views/create.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/views/create.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/views/home.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/views/home.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/views/manage.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/views/manage.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/views/manageSearch.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/views/manageSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/views/review.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/views/review.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/views/reviewSearch.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/res/views/reviewSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/main.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/main.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/pack/cpuprofile.pro b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/pack/cpuprofile.pro old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/ctrl/controllers.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/ctrl/controllers.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/ctrl/currency.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/ctrl/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/ctrl/currency_test.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/ctrl/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/ctrl/home.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/ctrl/home.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/ctrl/purchaseOrder.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/ctrl/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/ctrl/shipping.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/ctrl/shipping.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/gzipserver.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/gzipserver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/model/currency.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/model/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/model/currency_test.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/model/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/model/purchaseOrder.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/model/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/model/receiver.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/model/receiver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/model/vendor.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/model/vendor.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/unit_test.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/poms/unit_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/services/orgStructureService/orgStructureService.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/services/orgStructureService/orgStructureService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/services/vendorService/vendorService.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/1_initial/src/services/vendorService/vendorService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/.gitignore b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/.gitignore old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/gulpfile.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/index.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/index.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/less/_landing-page.less b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/less/_landing-page.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/less/app.less b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/less/app.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/package.json b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/profile b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/profile old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/app.css b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/app.css old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/app.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/app.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/controllers/CreateController.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/controllers/CreateController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/controllers/ManageController.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/controllers/ManageController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/controllers/ReviewController.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/controllers/ReviewController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/models/PODetail.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/models/PODetail.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/models/PurchaseOrder.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/models/PurchaseOrder.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/services/CurrencyService.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/services/CurrencyService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/services/PurchaseOrderService.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/services/PurchaseOrderService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/services/ShippingService.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/services/ShippingService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/ui-bootstrap-tpls-0.13.3.min.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/js/ui-bootstrap-tpls-0.13.3.min.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/views/create.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/views/create.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/views/home.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/views/home.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/views/manage.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/views/manage.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/views/manageSearch.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/views/manageSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/views/review.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/views/review.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/views/reviewSearch.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/res/views/reviewSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/main.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/main.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/pack/cpuprofile.pro b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/pack/cpuprofile.pro old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/ctrl/controllers.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/ctrl/controllers.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/ctrl/currency.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/ctrl/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/ctrl/currency_test.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/ctrl/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/ctrl/home.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/ctrl/home.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/ctrl/purchaseOrder.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/ctrl/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/ctrl/shipping.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/ctrl/shipping.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/gzipserver.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/gzipserver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/model/currency.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/model/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/model/currency_test.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/model/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/model/purchaseOrder.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/model/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/model/receiver.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/model/receiver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/model/vendor.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/model/vendor.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/unit_test.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/poms/unit_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/services/orgStructureService/orgStructureService.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/services/orgStructureService/orgStructureService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/services/vendorService/vendorService.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/2_Server/src/services/vendorService/vendorService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/.gitignore b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/.gitignore old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/gulpfile.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/index.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/index.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/less/_landing-page.less b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/less/_landing-page.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/less/app.less b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/less/app.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/package.json b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/app.css b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/app.css old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/app.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/app.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/controllers/CreateController.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/controllers/CreateController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/controllers/ManageController.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/controllers/ManageController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/controllers/ReviewController.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/controllers/ReviewController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/models/PODetail.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/models/PODetail.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/models/PurchaseOrder.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/models/PurchaseOrder.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/services/CurrencyService.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/services/CurrencyService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/services/PurchaseOrderService.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/services/PurchaseOrderService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/services/ShippingService.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/services/ShippingService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/ui-bootstrap-tpls-0.13.3.min.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/js/ui-bootstrap-tpls-0.13.3.min.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/views/create.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/views/create.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/views/home.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/views/home.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/views/manage.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/views/manage.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/views/manageSearch.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/views/manageSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/views/review.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/views/review.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/views/reviewSearch.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/res/views/reviewSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/main.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/main.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/pack/cpuprofile.pro b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/pack/cpuprofile.pro old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/ctrl/controllers.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/ctrl/controllers.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/ctrl/currency.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/ctrl/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/ctrl/currency_test.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/ctrl/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/ctrl/home.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/ctrl/home.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/ctrl/purchaseOrder.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/ctrl/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/ctrl/shipping.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/ctrl/shipping.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/gzipserver.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/gzipserver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/model/currency.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/model/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/model/currency_test.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/model/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/model/purchaseOrder.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/model/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/model/receiver.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/model/receiver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/model/vendor.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/model/vendor.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/unit_test.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/poms/unit_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/services/orgStructureService/orgStructureService.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/services/orgStructureService/orgStructureService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/services/vendorService/vendorService.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/3_ResponseRecorder_a/src/services/vendorService/vendorService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/.gitignore b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/.gitignore old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/gulpfile.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/index.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/index.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/less/_landing-page.less b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/less/_landing-page.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/less/app.less b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/less/app.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/package.json b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/app.css b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/app.css old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/app.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/app.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/controllers/CreateController.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/controllers/CreateController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/controllers/ManageController.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/controllers/ManageController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/controllers/ReviewController.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/controllers/ReviewController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/models/PODetail.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/models/PODetail.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/models/PurchaseOrder.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/models/PurchaseOrder.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/services/CurrencyService.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/services/CurrencyService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/services/PurchaseOrderService.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/services/PurchaseOrderService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/services/ShippingService.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/services/ShippingService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/ui-bootstrap-tpls-0.13.3.min.js b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/js/ui-bootstrap-tpls-0.13.3.min.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/views/create.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/views/create.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/views/home.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/views/home.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/views/manage.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/views/manage.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/views/manageSearch.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/views/manageSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/views/review.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/views/review.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/views/reviewSearch.html b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/res/views/reviewSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/main.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/main.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/pack/cpuprofile.pro b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/pack/cpuprofile.pro old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/ctrl/controllers.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/ctrl/controllers.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/ctrl/currency.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/ctrl/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/ctrl/currency_test.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/ctrl/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/ctrl/home.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/ctrl/home.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/ctrl/purchaseOrder.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/ctrl/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/ctrl/shipping.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/ctrl/shipping.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/gzipserver.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/gzipserver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/model/currency.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/model/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/model/currency_test.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/model/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/model/purchaseOrder.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/model/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/model/receiver.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/model/receiver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/model/vendor.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/model/vendor.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/unit_test.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/poms/unit_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/services/orgStructureService/orgStructureService.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/services/orgStructureService/orgStructureService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/services/vendorService/vendorService.go b/000_temp/34_test/go-testing-applications/7-go-testing-applications-m7-exercise-files/4_ResponseRecorder_b/src/services/vendorService/vendorService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/gulpfile.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/index.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/index.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/less/_landing-page.less b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/less/_landing-page.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/less/app.less b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/less/app.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/package.json b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/profile b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/profile old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/app.css b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/app.css old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/app.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/app.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/controllers/CreateController.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/controllers/CreateController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/controllers/ManageController.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/controllers/ManageController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/controllers/ReviewController.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/controllers/ReviewController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/models/PODetail.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/models/PODetail.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/models/PurchaseOrder.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/models/PurchaseOrder.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/services/CurrencyService.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/services/CurrencyService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/services/PurchaseOrderService.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/services/PurchaseOrderService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/services/ShippingService.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/services/ShippingService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/ui-bootstrap-tpls-0.13.3.min.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/js/ui-bootstrap-tpls-0.13.3.min.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/views/create.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/views/create.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/views/home.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/views/home.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/views/manage.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/views/manage.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/views/manageSearch.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/views/manageSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/views/review.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/views/review.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/views/reviewSearch.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/res/views/reviewSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/main.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/main.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/pack/cpuprofile.pro b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/pack/cpuprofile.pro old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/ctrl/controllers.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/ctrl/controllers.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/ctrl/currency.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/ctrl/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/ctrl/currency_test.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/ctrl/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/ctrl/home.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/ctrl/home.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/ctrl/purchaseOrder.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/ctrl/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/ctrl/shipping.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/ctrl/shipping.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/gzipserver.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/gzipserver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/model/currency.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/model/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/model/currency_test.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/model/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/model/purchaseOrder.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/model/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/model/receiver.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/model/receiver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/model/vendor.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/model/vendor.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/unit_test.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/poms/unit_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/profiles/prof.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/profiles/prof.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/services/orgStructureService/orgStructureService.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/services/orgStructureService/orgStructureService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/services/vendorService/vendorService.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/01_standalone_cpu/src/services/vendorService/vendorService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/gulpfile.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/index.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/index.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/less/_landing-page.less b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/less/_landing-page.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/less/app.less b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/less/app.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/package.json b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/profile b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/profile old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/app.css b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/app.css old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/app.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/app.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/controllers/CreateController.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/controllers/CreateController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/controllers/ManageController.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/controllers/ManageController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/controllers/ReviewController.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/controllers/ReviewController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/models/PODetail.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/models/PODetail.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/models/PurchaseOrder.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/models/PurchaseOrder.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/services/CurrencyService.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/services/CurrencyService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/services/PurchaseOrderService.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/services/PurchaseOrderService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/services/ShippingService.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/services/ShippingService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/ui-bootstrap-tpls-0.13.3.min.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/js/ui-bootstrap-tpls-0.13.3.min.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/views/create.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/views/create.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/views/home.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/views/home.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/views/manage.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/views/manage.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/views/manageSearch.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/views/manageSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/views/review.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/views/review.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/views/reviewSearch.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/res/views/reviewSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/main.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/main.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/pack/cpuprofile.pro b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/pack/cpuprofile.pro old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/ctrl/controllers.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/ctrl/controllers.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/ctrl/currency.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/ctrl/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/ctrl/currency_test.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/ctrl/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/ctrl/home.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/ctrl/home.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/ctrl/purchaseOrder.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/ctrl/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/ctrl/shipping.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/ctrl/shipping.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/gzipserver.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/gzipserver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/model/currency.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/model/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/model/currency_test.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/model/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/model/purchaseOrder.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/model/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/model/receiver.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/model/receiver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/model/vendor.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/model/vendor.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/unit_test.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/poms/unit_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/profiles/prof.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/profiles/prof.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/services/orgStructureService/orgStructureService.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/services/orgStructureService/orgStructureService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/services/vendorService/vendorService.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/02_standalone_heap/src/services/vendorService/vendorService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/gulpfile.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/index.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/index.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/less/_landing-page.less b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/less/_landing-page.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/less/app.less b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/less/app.less old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/package.json b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/profile b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/profile old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/app.css b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/app.css old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/app.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/app.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/controllers/CreateController.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/controllers/CreateController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/controllers/ManageController.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/controllers/ManageController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/controllers/ReviewController.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/controllers/ReviewController.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/models/PODetail.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/models/PODetail.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/models/PurchaseOrder.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/models/PurchaseOrder.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/services/CurrencyService.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/services/CurrencyService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/services/PurchaseOrderService.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/services/PurchaseOrderService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/services/ShippingService.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/services/ShippingService.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/ui-bootstrap-tpls-0.13.3.min.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/js/ui-bootstrap-tpls-0.13.3.min.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/views/create.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/views/create.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/views/home.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/views/home.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/views/manage.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/views/manage.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/views/manageSearch.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/views/manageSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/views/review.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/views/review.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/views/reviewSearch.html b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/res/views/reviewSearch.html old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/main.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/main.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/pack/cpuprofile.pro b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/pack/cpuprofile.pro old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/ctrl/controllers.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/ctrl/controllers.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/ctrl/currency.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/ctrl/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/ctrl/currency_test.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/ctrl/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/ctrl/home.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/ctrl/home.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/ctrl/purchaseOrder.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/ctrl/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/ctrl/shipping.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/ctrl/shipping.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/gzipserver.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/gzipserver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/model/currency.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/model/currency.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/model/currency_test.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/model/currency_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/model/purchaseOrder.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/model/purchaseOrder.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/model/receiver.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/model/receiver.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/model/vendor.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/model/vendor.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/unit_test.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/poms/unit_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/profiles/prof.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/profiles/prof.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/services/orgStructureService/orgStructureService.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/services/orgStructureService/orgStructureService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/services/vendorService/vendorService.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/03_standalone_goroutines/src/services/vendorService/vendorService.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/04_tests/gulpfile.js b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/04_tests/gulpfile.js old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/04_tests/package.json b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/04_tests/package.json old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/04_tests/profile b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/04_tests/profile old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/04_tests/src/pack/cpuprofile.pro b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/04_tests/src/pack/cpuprofile.pro old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/04_tests/src/pack/math.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/04_tests/src/pack/math.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/04_tests/src/pack/math_test.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/04_tests/src/pack/math_test.go old mode 100755 new mode 100644 diff --git a/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/04_tests/src/pack/riemann_test.go b/000_temp/34_test/go-testing-applications/8-go-testing-applications-m8-exercise-files/04_tests/src/pack/riemann_test.go old mode 100755 new mode 100644 diff --git a/000_temp/42_class/01/main.go b/000_temp/42_class/01/main.go old mode 100755 new mode 100644 diff --git a/000_temp/42_class/04/example.txt b/000_temp/42_class/04/example.txt old mode 100755 new mode 100644 diff --git a/000_temp/44_class/03_uuid/main.go b/000_temp/44_class/03_uuid/main.go index 73380fcc..b009522c 100644 --- a/000_temp/44_class/03_uuid/main.go +++ b/000_temp/44_class/03_uuid/main.go @@ -15,7 +15,7 @@ func main() { func foo(w http.ResponseWriter, req *http.Request) { c, err := req.Cookie("session") if err != nil { - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c = &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/000_temp/44_class/04_session/main.go b/000_temp/44_class/04_session/main.go index 121b4fc2..089b10de 100644 --- a/000_temp/44_class/04_session/main.go +++ b/000_temp/44_class/04_session/main.go @@ -29,7 +29,7 @@ func foo(w http.ResponseWriter, req *http.Request) { // get cookie c, err := req.Cookie("session") if err != nil { - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c = &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/000_temp/44_class/07_hands-on_login/starting-code/main.go b/000_temp/44_class/07_hands-on_login/starting-code/main.go index c1d54275..3840d71f 100644 --- a/000_temp/44_class/07_hands-on_login/starting-code/main.go +++ b/000_temp/44_class/07_hands-on_login/starting-code/main.go @@ -35,7 +35,7 @@ func index(w http.ResponseWriter, req *http.Request) { // get cookie c, err := req.Cookie("session") if err != nil { - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c = &http.Cookie{ Name: "session", Value: sID.String(), @@ -97,7 +97,7 @@ func login(w http.ResponseWriter, req *http.Request) { return } // create a session - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c := &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/000_temp/44_class/10_hello-world/hworld b/000_temp/44_class/10_hello-world/hworld old mode 100755 new mode 100644 diff --git a/000_temp/44_class/11_hello-world/main.go b/000_temp/44_class/11_hello-world/main.go new file mode 100644 index 00000000..7c091dc9 --- /dev/null +++ b/000_temp/44_class/11_hello-world/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "Hello world") +} diff --git a/000_temp/44_class/12_interface/main.go b/000_temp/44_class/12_interface/main.go new file mode 100644 index 00000000..65c556c1 --- /dev/null +++ b/000_temp/44_class/12_interface/main.go @@ -0,0 +1,43 @@ +package main + +import "fmt" + +// package cache +type Cache interface { + Set(k string, val interface{}) + Get(k string) interface{} +} + +// package memcache +type memCache struct { + m map[string]interface{} +} + +func (m *memCache) Set(k string, val interface{}) { + m.m[k] = val +} + +func (m *memCache) Get(k string) interface{} { + return m.m[k] +} + +// package cmd +// imports cache +func cacheUser(cache Cache, id, def string) { + val := cache.Get(id) + if val == nil { + val = def + cache.Set(id, val) + } + fmt.Println(val) +} + +// package main +// imports memcache +func main() { + c := &memCache{ + m: map[string]interface{}{}, + } + cacheUser(c, "Bob", "Hello") + cacheUser(c, "Bob", "Goodbye") +} diff --git a/000_temp/44_class/13_interface/cache/main.go b/000_temp/44_class/13_interface/cache/main.go new file mode 100644 index 00000000..ed67f989 --- /dev/null +++ b/000_temp/44_class/13_interface/cache/main.go @@ -0,0 +1,6 @@ +package cache + +type Cache interface { + Set(k string, val interface{}) + Get(k string) interface{} +} diff --git a/000_temp/44_class/13_interface/cmd/main.go b/000_temp/44_class/13_interface/cmd/main.go new file mode 100644 index 00000000..66e34e26 --- /dev/null +++ b/000_temp/44_class/13_interface/cmd/main.go @@ -0,0 +1,15 @@ +package cmd + +import ( + "fmt" + "github.com/GoesToEleven/golang-web-dev/000_temp/44_class/13_interface/cache" +) + +func CacheUser(cache cache.Cache, id, def string) { + val := cache.Get(id) + if val == nil { + val = def + cache.Set(id, val) + } + fmt.Println(val) +} diff --git a/000_temp/44_class/13_interface/main.go b/000_temp/44_class/13_interface/main.go new file mode 100644 index 00000000..6875697f --- /dev/null +++ b/000_temp/44_class/13_interface/main.go @@ -0,0 +1,14 @@ +package main + +import ( + "github.com/GoesToEleven/golang-web-dev/000_temp/44_class/13_interface/cmd" + "github.com/GoesToEleven/golang-web-dev/000_temp/44_class/13_interface/memcache" +) + +func main() { + c := &memcache.MemCache{ + M: map[string]interface{}{}, + } + cmd.CacheUser(c, "Bob", "Hello") + cmd.CacheUser(c, "Bob", "Goodbye") +} diff --git a/000_temp/44_class/13_interface/memcache/main.go b/000_temp/44_class/13_interface/memcache/main.go new file mode 100644 index 00000000..bdcc3ec1 --- /dev/null +++ b/000_temp/44_class/13_interface/memcache/main.go @@ -0,0 +1,13 @@ +package memcache + +type MemCache struct { + M map[string]interface{} +} + +func (m *MemCache) Set(k string, val interface{}) { + m.M[k] = val +} + +func (m *MemCache) Get(k string) interface{} { + return m.M[k] +} diff --git a/000_temp/44_class/14_data-structure/main.go b/000_temp/44_class/14_data-structure/main.go new file mode 100644 index 00000000..f26aa833 --- /dev/null +++ b/000_temp/44_class/14_data-structure/main.go @@ -0,0 +1,50 @@ +package main + +import ( + "fmt" +) + +type person struct { + first string + last string +} + +type secretAgent struct { + person + ltk bool +} + +func (p person) greeting() { + fmt.Println(p.first, "says hellooooooo James") +} + +func (sa secretAgent) greeting() { + fmt.Println(sa.first, "says shaken, not stirred") +} + +type human interface { + greeting() +} + +func sayMore(h human) { + h.greeting() +} + +func main() { + p1 := person{ + "Eve", + "Moneypenny", + } + p1.greeting() + sayMore(p1) + + sa1 := secretAgent{ + person{ + "james", + "bond", + }, + true, + } + sa1.greeting() + sayMore(sa1) +} diff --git a/000_temp/44_class/15/main.go b/000_temp/44_class/15/main.go new file mode 100644 index 00000000..7106dd3f --- /dev/null +++ b/000_temp/44_class/15/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + "io" + "net/http" +) + +func init() { + fmt.Println("hello from init") +} + +func main() { + fmt.Println("hello from main") + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "Hello world") +} diff --git a/000_temp/45_pagination/main.go b/000_temp/45_pagination/main.go new file mode 100644 index 00000000..966b6986 --- /dev/null +++ b/000_temp/45_pagination/main.go @@ -0,0 +1,93 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" + "strconv" +) + +type Env struct { + Data []int + From int + To int + Amount int + ForwardStart int + BackwardStart int +} + +var tpl *template.Template +var xi []int + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + xi = make([]int, 0, 100) + for i := 0; i <= 100; i++ { + xi = append(xi, i) + } + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + + // we will show records FROM a certain record, TO a certain record + next := r.FormValue("next") + from, err := strconv.Atoi(next) + if err != nil { + from = 0 + } + + recordsPerPageToShow := 10 + to := from + recordsPerPageToShow + + // get the data to pass in + // slice a slice; aka, slicing a slice + // up to "to" but not including "to" is the way slicing works + // your slices could be slices of anything: int, string, struct + var xx []int + if to == len(xi) { + // get records to end + xx = xi[from:] + } else { + xx = xi[from:to] + } + + // get the ForwardStart + // if we are going "from" "to" + // then the next group of records would start at "to" + // but only if there are such records + var fs int + if to+recordsPerPageToShow <= len(xi) { + fs = to + } else { + fs = len(xi) - recordsPerPageToShow + } + + // get the BackwardStart + // if we are going "from" "to" + // then the previous group of records would start at "from" minus ten (records shown) + // but only if there are such records + var bs int + if from-recordsPerPageToShow >= 0 { + bs = from - recordsPerPageToShow + } else { + bs = 0 + } + + data := Env{ + Data: xx, + From: from, + To: to - 1, + Amount: recordsPerPageToShow, + ForwardStart: fs, + BackwardStart: bs, + } + err = tpl.ExecuteTemplate(w, "index.gohtml", data) + if err != nil { + fmt.Println(err) + } +} diff --git a/000_temp/45_pagination/templates/index.gohtml b/000_temp/45_pagination/templates/index.gohtml new file mode 100644 index 00000000..f94e705b --- /dev/null +++ b/000_temp/45_pagination/templates/index.gohtml @@ -0,0 +1,15 @@ + + + + + PAGINATION + + + +

RECORDS {{.From}} - {{.To}}

+{{range .Data}} + {{.}} +{{end}} +

Previous {{.Amount}} - Next {{.Amount}}

+ + \ No newline at end of file diff --git a/000_temp/46_sp17/01/main.go b/000_temp/46_sp17/01/main.go new file mode 100644 index 00000000..11327e8c --- /dev/null +++ b/000_temp/46_sp17/01/main.go @@ -0,0 +1,62 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.HandleFunc("/contact", contact) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, ` + + + + SITE + + +

HOME

+

HOME

+

ABOUT

+

CONTACT

+ +`) +} + +func about(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, ` + + + + SITE + + +

ABOUT

+

HOME

+

ABOUT

+

CONTACT

+ +`) +} + +func contact(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, ` + + + + SITE + + + +

CONTACT

+

HOME

+

ABOUT

+

CONTACT

+ +`) +} diff --git a/000_temp/46_sp17/02/main.go b/000_temp/46_sp17/02/main.go new file mode 100644 index 00000000..e1479422 --- /dev/null +++ b/000_temp/46_sp17/02/main.go @@ -0,0 +1,13 @@ +package main + +import "fmt" + +func main() { + x := 42 + fmt.Println(x) + foo() +} + +func foo() { + fmt.Println("hello") +} diff --git a/000_temp/46_sp17/03_handle_handler_handlefunc/01_handle/main.go b/000_temp/46_sp17/03_handle_handler_handlefunc/01_handle/main.go new file mode 100644 index 00000000..25d43891 --- /dev/null +++ b/000_temp/46_sp17/03_handle_handler_handlefunc/01_handle/main.go @@ -0,0 +1,18 @@ +package main + +import ( + "io" + "net/http" +) + +type hotdog int + +func (hotdog) ServeHTTP(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "Hello from hotdogger") +} + +func main() { + var foo hotdog + http.Handle("/", foo) + http.ListenAndServe(":8080", nil) +} diff --git a/000_temp/46_sp17/03_handle_handler_handlefunc/02_handlefunc/main.go b/000_temp/46_sp17/03_handle_handler_handlefunc/02_handlefunc/main.go new file mode 100644 index 00000000..f21302b4 --- /dev/null +++ b/000_temp/46_sp17/03_handle_handler_handlefunc/02_handlefunc/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", foo) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "Hello from hotdiggity dogger") +} diff --git a/000_temp/46_sp17/03_handle_handler_handlefunc/03_handlerfunc/main.go b/000_temp/46_sp17/03_handle_handler_handlefunc/03_handlerfunc/main.go new file mode 100644 index 00000000..a8448ce7 --- /dev/null +++ b/000_temp/46_sp17/03_handle_handler_handlefunc/03_handlerfunc/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.Handle("/", http.HandlerFunc(foo)) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "Holy diggity dogger") +} diff --git a/000_temp/46_sp17/04/main.go b/000_temp/46_sp17/04/main.go new file mode 100644 index 00000000..ecc7100c --- /dev/null +++ b/000_temp/46_sp17/04/main.go @@ -0,0 +1,8 @@ +package main + +import "fmt" + +func main() { + m := map[string]int{"Bond": 32, "Moneypenny": 24} + fmt.Println(m) +} diff --git a/000_temp/46_sp17/05/main.go b/000_temp/46_sp17/05/main.go new file mode 100644 index 00000000..d28c1f94 --- /dev/null +++ b/000_temp/46_sp17/05/main.go @@ -0,0 +1,13 @@ +package main + +import "fmt" + +func main() { + x := 42 + fmt.Println(x) + foo(x) +} + +func foo(x int) { + fmt.Println("hello", x) +} diff --git a/000_temp/46_sp17/06/main.go b/000_temp/46_sp17/06/main.go new file mode 100644 index 00000000..fc739a16 --- /dev/null +++ b/000_temp/46_sp17/06/main.go @@ -0,0 +1,15 @@ +package main + +import "fmt" + +var z int = 42 + +func main() { + y := 43 + fmt.Println(z, y) + foo() +} + +func foo() { + fmt.Println(z, z, z, z, z) +} diff --git a/000_temp/46_sp17/07_bond/main.go b/000_temp/46_sp17/07_bond/main.go new file mode 100644 index 00000000..7fa71c24 --- /dev/null +++ b/000_temp/46_sp17/07_bond/main.go @@ -0,0 +1,37 @@ +package main + +import "fmt" + +type person struct { + fName string + lName string + age int +} + +type secretAgent struct { + person + ltk bool +} + +func (p person) speak() string { + return fmt.Sprintln("uptown, func you up, uptown func you up") +} + +func (sa secretAgent) speak() string { + return fmt.Sprintln("shaken, not stirred") +} + +type human interface { + speak() string +} + +func foo(h human) { + fmt.Println("hello from foo") +} + +func main() { + p1 := person{"Nina", "Simone", 25} + sa1 := secretAgent{person{"Ian", "Fleming", 42}, false} + foo(p1) + foo(sa1) +} diff --git a/000_temp/46_sp17/08_notfound-notfoundhandler/main.go b/000_temp/46_sp17/08_notfound-notfoundhandler/main.go new file mode 100644 index 00000000..22b89116 --- /dev/null +++ b/000_temp/46_sp17/08_notfound-notfoundhandler/main.go @@ -0,0 +1,13 @@ +package main + +import "net/http" + +func main() { + http.HandleFunc("/", index) + http.Handle("/nf", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + http.NotFound(w, r) +} diff --git a/000_temp/46_sp17/09_fundamentals/01/main.go b/000_temp/46_sp17/09_fundamentals/01/main.go new file mode 100644 index 00000000..b8c285f4 --- /dev/null +++ b/000_temp/46_sp17/09_fundamentals/01/main.go @@ -0,0 +1,18 @@ +package main + +import "fmt" + +type person struct { + first string +} + +func (p person) speak() { + fmt.Println(p.first) +} + +func main() { + p1 := person{"McLeod"} + p2 := person{"Bond"} + p1.speak() + p2.speak() +} diff --git a/000_temp/46_sp17/09_fundamentals/02/main.go b/000_temp/46_sp17/09_fundamentals/02/main.go new file mode 100644 index 00000000..93acc138 --- /dev/null +++ b/000_temp/46_sp17/09_fundamentals/02/main.go @@ -0,0 +1,19 @@ +package main + +import "fmt" + +func main() { + xi := []int{4, 3, 5, 7, 3, 4, 5} + fmt.Println(xi) + + for i, v := range xi { + fmt.Println(i, v) + } + + m := map[string]int{"mcleod": 42, "bond": 32} + fmt.Println(m) + + for k, v := range m { + fmt.Println(k, v) + } +} diff --git a/000_temp/46_sp17/09_fundamentals/03/main.go b/000_temp/46_sp17/09_fundamentals/03/main.go new file mode 100644 index 00000000..a0670d16 --- /dev/null +++ b/000_temp/46_sp17/09_fundamentals/03/main.go @@ -0,0 +1,36 @@ +package main + +import "fmt" + +type human interface { + speak() +} + +type person struct { + first string +} + +func (p person) speak() { + fmt.Println(p.first) +} + +type car struct { + color string +} + +func (c car) speak() { + fmt.Println("I am color:", c.color) +} + +func foo(h human) { + fmt.Println(h) +} + +func main() { + p1 := person{"McLeod"} + p2 := person{"Bond"} + c1 := car{"red"} + foo(p1) + foo(p2) + foo(c1) +} diff --git a/000_temp/46_sp17/10_cli-input/main.go b/000_temp/46_sp17/10_cli-input/main.go new file mode 100644 index 00000000..bf5cf1df --- /dev/null +++ b/000_temp/46_sp17/10_cli-input/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + "os" +) + +func main() { + fmt.Println("Are you human?") + fmt.Println("YES or NO") + var answer string + _, err := fmt.Scanf("%s", &answer) + if err != nil { + panic(err) + } + if answer != "YES" { + fmt.Println("You're not human! What?!?!") + os.Exit(0) + } + fmt.Println("I am glad you are human") +} diff --git a/000_temp/46_sp17/11/main.go b/000_temp/46_sp17/11/main.go new file mode 100644 index 00000000..587e74d0 --- /dev/null +++ b/000_temp/46_sp17/11/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "fmt" + "net/http" +) + +func main() { + http.HandleFunc("/", foo) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, "Hello from foo") +} diff --git a/000_temp/46_sp17/12/main.go b/000_temp/46_sp17/12/main.go new file mode 100644 index 00000000..5ff7b320 --- /dev/null +++ b/000_temp/46_sp17/12/main.go @@ -0,0 +1,79 @@ +package main + +import ( + "fmt" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.HandleFunc("/contact", contact) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, ` + + + + index + + + +Hello from index +

+index +about +contact + +`) +} + +func about(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, ` + + + + about + + + +Hello from about +

+index +about +contact + +`) +} + +func contact(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, ` + + + + contact + + + +Hello from contact +

+index +about +contact + +`) +} diff --git a/000_temp/46_sp17/13/main.go b/000_temp/46_sp17/13/main.go new file mode 100644 index 00000000..5ea0c485 --- /dev/null +++ b/000_temp/46_sp17/13/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.HandleFunc("/contact", contact) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} + +func contact(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "contact.gohtml", nil) +} diff --git a/000_temp/46_sp17/13/templates/about.gohtml b/000_temp/46_sp17/13/templates/about.gohtml new file mode 100644 index 00000000..16b2020b --- /dev/null +++ b/000_temp/46_sp17/13/templates/about.gohtml @@ -0,0 +1,21 @@ + + + + + About + + + + +You are at about +

+index +about +contact + + + \ No newline at end of file diff --git a/000_temp/46_sp17/13/templates/contact.gohtml b/000_temp/46_sp17/13/templates/contact.gohtml new file mode 100644 index 00000000..f9044d6a --- /dev/null +++ b/000_temp/46_sp17/13/templates/contact.gohtml @@ -0,0 +1,21 @@ + + + + + Contact + + + + +You are at Contact +

+index +about +contact + + + \ No newline at end of file diff --git a/000_temp/46_sp17/13/templates/index.gohtml b/000_temp/46_sp17/13/templates/index.gohtml new file mode 100644 index 00000000..7a5de2ce --- /dev/null +++ b/000_temp/46_sp17/13/templates/index.gohtml @@ -0,0 +1,21 @@ + + + + + Index + + + + +You are at index +

+index +about +contact + + + \ No newline at end of file diff --git a/000_temp/46_sp17/14/main.go b/000_temp/46_sp17/14/main.go new file mode 100644 index 00000000..afff1f5d --- /dev/null +++ b/000_temp/46_sp17/14/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("template/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} diff --git a/000_temp/46_sp17/14/template/index.gohtml b/000_temp/46_sp17/14/template/index.gohtml new file mode 100644 index 00000000..14b4d345 --- /dev/null +++ b/000_temp/46_sp17/14/template/index.gohtml @@ -0,0 +1,17 @@ + + + + + Index + + + + +You are at index. + + + \ No newline at end of file diff --git a/000_temp/46_sp17/15/main.go b/000_temp/46_sp17/15/main.go new file mode 100644 index 00000000..2b12224e --- /dev/null +++ b/000_temp/46_sp17/15/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("template/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", 42) +} diff --git a/000_temp/46_sp17/15/template/index.gohtml b/000_temp/46_sp17/15/template/index.gohtml new file mode 100644 index 00000000..3ec9dff9 --- /dev/null +++ b/000_temp/46_sp17/15/template/index.gohtml @@ -0,0 +1,20 @@ + + + + + Index + + + + +You are at index. +
+ +

Here is the answer to the ultimate question: {{.}}

+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/16/main.go b/000_temp/46_sp17/16/main.go new file mode 100644 index 00000000..7d5f90b9 --- /dev/null +++ b/000_temp/46_sp17/16/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("template/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", "Todd") +} diff --git a/000_temp/46_sp17/16/template/index.gohtml b/000_temp/46_sp17/16/template/index.gohtml new file mode 100644 index 00000000..4b2183ff --- /dev/null +++ b/000_temp/46_sp17/16/template/index.gohtml @@ -0,0 +1,21 @@ + + + + + Index + + + + +You are at index. +
+ +

Who is your daddy?

+

{{.}}

+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/17/main.go b/000_temp/46_sp17/17/main.go new file mode 100644 index 00000000..ebb0316b --- /dev/null +++ b/000_temp/46_sp17/17/main.go @@ -0,0 +1,30 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +type person struct { + First string + Age int +} + +func init() { + tpl = template.Must(template.ParseGlob("template/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + p1 := person{ + "Todd", + 45, + } + tpl.ExecuteTemplate(w, "index.gohtml", p1) +} diff --git a/000_temp/46_sp17/17/template/index.gohtml b/000_temp/46_sp17/17/template/index.gohtml new file mode 100644 index 00000000..bb55b866 --- /dev/null +++ b/000_temp/46_sp17/17/template/index.gohtml @@ -0,0 +1,23 @@ + + + + + Index + + + + +You are at index. +
+ +

Who is your daddy?

+

{{.First}}

+ +

How old is he?

+

{{.Age}}

+ + \ No newline at end of file diff --git a/000_temp/46_sp17/18/main.go b/000_temp/46_sp17/18/main.go new file mode 100644 index 00000000..5ea0c485 --- /dev/null +++ b/000_temp/46_sp17/18/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.HandleFunc("/contact", contact) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} + +func contact(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "contact.gohtml", nil) +} diff --git a/000_temp/46_sp17/18/templates/about.gohtml b/000_temp/46_sp17/18/templates/about.gohtml new file mode 100644 index 00000000..16b2020b --- /dev/null +++ b/000_temp/46_sp17/18/templates/about.gohtml @@ -0,0 +1,21 @@ + + + + + About + + + + +You are at about +

+index +about +contact + + + \ No newline at end of file diff --git a/000_temp/46_sp17/18/templates/contact.gohtml b/000_temp/46_sp17/18/templates/contact.gohtml new file mode 100644 index 00000000..f9044d6a --- /dev/null +++ b/000_temp/46_sp17/18/templates/contact.gohtml @@ -0,0 +1,21 @@ + + + + + Contact + + + + +You are at Contact +

+index +about +contact + + + \ No newline at end of file diff --git a/000_temp/46_sp17/18/templates/index.gohtml b/000_temp/46_sp17/18/templates/index.gohtml new file mode 100644 index 00000000..7a5de2ce --- /dev/null +++ b/000_temp/46_sp17/18/templates/index.gohtml @@ -0,0 +1,21 @@ + + + + + Index + + + + +You are at index +

+index +about +contact + + + \ No newline at end of file diff --git a/000_temp/46_sp17/19/main.go b/000_temp/46_sp17/19/main.go new file mode 100644 index 00000000..c525d24c --- /dev/null +++ b/000_temp/46_sp17/19/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/foo", foo) + http.HandleFunc("/bar/", bar) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "hello from index") +} + +func foo(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "hello from foo") +} + +func bar(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "hello from bar") +} diff --git a/000_temp/46_sp17/20-string-int/main.go b/000_temp/46_sp17/20-string-int/main.go new file mode 100644 index 00000000..5376afb5 --- /dev/null +++ b/000_temp/46_sp17/20-string-int/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", "Heeeeeelllooo world, yeeeee-ha!") +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", 42) +} diff --git a/000_temp/46_sp17/20-string-int/templates/about.gohtml b/000_temp/46_sp17/20-string-int/templates/about.gohtml new file mode 100644 index 00000000..23817c97 --- /dev/null +++ b/000_temp/46_sp17/20-string-int/templates/about.gohtml @@ -0,0 +1,14 @@ + + + + + About + + + +

You are at about

+ +

{{.}}

+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/20-string-int/templates/index.gohtml b/000_temp/46_sp17/20-string-int/templates/index.gohtml new file mode 100644 index 00000000..2a8854d4 --- /dev/null +++ b/000_temp/46_sp17/20-string-int/templates/index.gohtml @@ -0,0 +1,14 @@ + + + + + Index + + + +

You are at index

+ +

{{.}}

+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/21-struct-slice-map/main.go b/000_temp/46_sp17/21-struct-slice-map/main.go new file mode 100644 index 00000000..d9535c9f --- /dev/null +++ b/000_temp/46_sp17/21-struct-slice-map/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "html/template" + "net/http" +) + +type person struct { + First string + Last string +} + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.HandleFunc("/contact", contact) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + p1 := person{ + "James", + "Bond", + } + + tpl.ExecuteTemplate(w, "index.gohtml", p1) +} + +func about(w http.ResponseWriter, r *http.Request) { + xi := []int{3, 5, 7, 9, 17, 749} + tpl.ExecuteTemplate(w, "about.gohtml", xi) +} + +func contact(w http.ResponseWriter, r *http.Request) { + m := map[string]int{ + "James": 32, + "Moneypenny": 24, + } + tpl.ExecuteTemplate(w, "contact.gohtml", m) +} diff --git a/000_temp/46_sp17/21-struct-slice-map/templates/about.gohtml b/000_temp/46_sp17/21-struct-slice-map/templates/about.gohtml new file mode 100644 index 00000000..6c4fc55b --- /dev/null +++ b/000_temp/46_sp17/21-struct-slice-map/templates/about.gohtml @@ -0,0 +1,17 @@ + + + + + About + + + +

You are at about

+ +

CURRENT DATA: {{.}}

+{{range .}} +

IN LOOP DATA: {{.}}

+{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/21-struct-slice-map/templates/contact.gohtml b/000_temp/46_sp17/21-struct-slice-map/templates/contact.gohtml new file mode 100644 index 00000000..a2da4bc5 --- /dev/null +++ b/000_temp/46_sp17/21-struct-slice-map/templates/contact.gohtml @@ -0,0 +1,17 @@ + + + + + Contact + + + +

You are at contact

+ +

CURRENT DATA: {{.}}

+{{range $name, $age := .}} +

IN LOOP DATA: {{$name}} {{$age}}

+{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/21-struct-slice-map/templates/index.gohtml b/000_temp/46_sp17/21-struct-slice-map/templates/index.gohtml new file mode 100644 index 00000000..d3b6734d --- /dev/null +++ b/000_temp/46_sp17/21-struct-slice-map/templates/index.gohtml @@ -0,0 +1,16 @@ + + + + + Index + + + +

You are at index

+ +

{{.}}

+

{{.First}}

+

{{.Last}}

+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/22/main.go b/000_temp/46_sp17/22/main.go new file mode 100644 index 00000000..863dea11 --- /dev/null +++ b/000_temp/46_sp17/22/main.go @@ -0,0 +1,28 @@ +package main + +import "fmt" + +func main() { + var answer1, answer2, answer3 string + + fmt.Print("Name: ") + _, err := fmt.Scan(&answer1) + if err != nil { + panic(err) + } + + fmt.Print("Fav Food: ") + _, err = fmt.Scan(&answer2) + if err != nil { + panic(err) + } + + fmt.Print("Fav Sport: ") + _, err = fmt.Scan(&answer3) + if err != nil { + panic(err) + } + + fmt.Println(answer1, answer2, answer3) + +} diff --git a/000_temp/46_sp17/23/main.go b/000_temp/46_sp17/23/main.go new file mode 100644 index 00000000..95eb597b --- /dev/null +++ b/000_temp/46_sp17/23/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "fmt" + "os" +) + +func main() { + // enter arguments when running program + // eg, go run main.go todd pizza surfing + + for i, v := range os.Args { + fmt.Println(i, v) + } +} diff --git a/000_temp/46_sp17/24_ParseGlob/main.go b/000_temp/46_sp17/24_ParseGlob/main.go new file mode 100644 index 00000000..c2a98bf6 --- /dev/null +++ b/000_temp/46_sp17/24_ParseGlob/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "log" + "os" + "text/template" +) + +func main() { + tpl, err := template.ParseGlob("templates/*/*.gohtml") + if err != nil { + log.Fatalln(err) + } + + err = tpl.Execute(os.Stdout, nil) + if err != nil { + log.Fatalln(err) + } + + err = tpl.ExecuteTemplate(os.Stdout, "vespa.gohtml", nil) + if err != nil { + log.Fatalln(err) + } + + err = tpl.ExecuteTemplate(os.Stdout, "two.gohtml", nil) + if err != nil { + log.Fatalln(err) + } + + err = tpl.ExecuteTemplate(os.Stdout, "one.gohtml", nil) + if err != nil { + log.Fatalln(err) + } +} diff --git a/000_temp/46_sp17/24_ParseGlob/templates/cats/vespa.gohtml b/000_temp/46_sp17/24_ParseGlob/templates/cats/vespa.gohtml new file mode 100644 index 00000000..85e72327 --- /dev/null +++ b/000_temp/46_sp17/24_ParseGlob/templates/cats/vespa.gohtml @@ -0,0 +1,3 @@ +****** +VESPA +****** \ No newline at end of file diff --git a/000_temp/46_sp17/24_ParseGlob/templates/dogs/two.gohtml b/000_temp/46_sp17/24_ParseGlob/templates/dogs/two.gohtml new file mode 100644 index 00000000..0c1c0a05 --- /dev/null +++ b/000_temp/46_sp17/24_ParseGlob/templates/dogs/two.gohtml @@ -0,0 +1,3 @@ +****** +TWO +****** \ No newline at end of file diff --git a/000_temp/46_sp17/24_ParseGlob/templates/mice/one.gohtml b/000_temp/46_sp17/24_ParseGlob/templates/mice/one.gohtml new file mode 100644 index 00000000..58420cdd --- /dev/null +++ b/000_temp/46_sp17/24_ParseGlob/templates/mice/one.gohtml @@ -0,0 +1,3 @@ +****** +ONE +****** \ No newline at end of file diff --git a/000_temp/46_sp17/25/main.go b/000_temp/46_sp17/25/main.go new file mode 100644 index 00000000..d9d91707 --- /dev/null +++ b/000_temp/46_sp17/25/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "net/http" + "text/template" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} diff --git a/000_temp/46_sp17/25/templates/about.gohtml b/000_temp/46_sp17/25/templates/about.gohtml new file mode 100644 index 00000000..cdc1ed08 --- /dev/null +++ b/000_temp/46_sp17/25/templates/about.gohtml @@ -0,0 +1,12 @@ + + + + + About + + + +

www.greatercommons.com

+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/25/templates/index.gohtml b/000_temp/46_sp17/25/templates/index.gohtml new file mode 100644 index 00000000..4d80a06b --- /dev/null +++ b/000_temp/46_sp17/25/templates/index.gohtml @@ -0,0 +1,12 @@ + + + + + Index + + + +Welcome to our website! + + + \ No newline at end of file diff --git a/000_temp/46_sp17/26/main.go b/000_temp/46_sp17/26/main.go new file mode 100644 index 00000000..4f6bcfc5 --- /dev/null +++ b/000_temp/46_sp17/26/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "net/http" + "text/template" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", false) +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} diff --git a/000_temp/46_sp17/26/templates/about.gohtml b/000_temp/46_sp17/26/templates/about.gohtml new file mode 100644 index 00000000..cdc1ed08 --- /dev/null +++ b/000_temp/46_sp17/26/templates/about.gohtml @@ -0,0 +1,12 @@ + + + + + About + + + +

www.greatercommons.com

+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/26/templates/index.gohtml b/000_temp/46_sp17/26/templates/index.gohtml new file mode 100644 index 00000000..f4d4af6e --- /dev/null +++ b/000_temp/46_sp17/26/templates/index.gohtml @@ -0,0 +1,14 @@ + + + + + Index + + + +{{if .}} +

Welcome to our website!

+{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/27/main.go b/000_temp/46_sp17/27/main.go new file mode 100644 index 00000000..a5a04a21 --- /dev/null +++ b/000_temp/46_sp17/27/main.go @@ -0,0 +1,30 @@ +package main + +import ( + "net/http" + "text/template" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + m := map[string]bool{} + m["Vince"] = true + m["eddie"] = true + m["G"] = true + tpl.ExecuteTemplate(w, "index.gohtml", m) +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} diff --git a/000_temp/46_sp17/27/templates/about.gohtml b/000_temp/46_sp17/27/templates/about.gohtml new file mode 100644 index 00000000..cdc1ed08 --- /dev/null +++ b/000_temp/46_sp17/27/templates/about.gohtml @@ -0,0 +1,12 @@ + + + + + About + + + +

www.greatercommons.com

+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/27/templates/index.gohtml b/000_temp/46_sp17/27/templates/index.gohtml new file mode 100644 index 00000000..c9d7cd96 --- /dev/null +++ b/000_temp/46_sp17/27/templates/index.gohtml @@ -0,0 +1,17 @@ + + + + + Index + + + +{{if .}} +

Welcome to our website!

+ {{range $k, $v := .}} +

{{$k}} - {{$v}}

+ {{end}} +{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/28/main.go b/000_temp/46_sp17/28/main.go new file mode 100644 index 00000000..9823dd23 --- /dev/null +++ b/000_temp/46_sp17/28/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "net/http" + "text/template" +) + +type person struct { + Name string + Prefs []string +} + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + p1 := person{"bond", []string{"martinis", "shaken not stirred", "fast cars", "intelligence"}} + p2 := person{"moneypenny", []string{"bond"}} + p3 := person{"Q", []string{"gadgets", "bond"}} + xp := []person{p1, p2, p3} + + tpl.ExecuteTemplate(w, "index.gohtml", xp) +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} diff --git a/000_temp/46_sp17/28/templates/about.gohtml b/000_temp/46_sp17/28/templates/about.gohtml new file mode 100644 index 00000000..cdc1ed08 --- /dev/null +++ b/000_temp/46_sp17/28/templates/about.gohtml @@ -0,0 +1,12 @@ + + + + + About + + + +

www.greatercommons.com

+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/28/templates/index.gohtml b/000_temp/46_sp17/28/templates/index.gohtml new file mode 100644 index 00000000..c6d5fa96 --- /dev/null +++ b/000_temp/46_sp17/28/templates/index.gohtml @@ -0,0 +1,22 @@ + + + + + Index + + + +

Welcome to our website!

+{{if .}} + {{range .}} +

{{.Name}}

+
    + {{range .Prefs}} +
  1. {{.}}
  2. + {{end}} +
+ {{end}} +{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/29_ServeFile/main.go b/000_temp/46_sp17/29_ServeFile/main.go new file mode 100644 index 00000000..0fcf14e6 --- /dev/null +++ b/000_temp/46_sp17/29_ServeFile/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", dog) + http.HandleFunc("/toby.jpg", dogPic) + http.ListenAndServe(":8080", nil) +} + +func dog(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + io.WriteString(w, ` `) +} + +func dogPic(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "public/img/toby.jpg") +} diff --git a/000_temp/46_sp17/29_ServeFile/public/img/toby.jpg b/000_temp/46_sp17/29_ServeFile/public/img/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/46_sp17/29_ServeFile/public/img/toby.jpg differ diff --git a/000_temp/46_sp17/30_fileserver/assets/resources/toby.jpg b/000_temp/46_sp17/30_fileserver/assets/resources/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/46_sp17/30_fileserver/assets/resources/toby.jpg differ diff --git a/000_temp/46_sp17/30_fileserver/main.go b/000_temp/46_sp17/30_fileserver/main.go new file mode 100644 index 00000000..b2bdb36c --- /dev/null +++ b/000_temp/46_sp17/30_fileserver/main.go @@ -0,0 +1,17 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", dog) + http.Handle("/resources/", http.FileServer(http.Dir("./assets"))) + http.ListenAndServe(":8080", nil) +} + +func dog(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + io.WriteString(w, ``) +} diff --git a/000_temp/46_sp17/31_fileserver-strip-prefix/assets/toby.jpg b/000_temp/46_sp17/31_fileserver-strip-prefix/assets/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/46_sp17/31_fileserver-strip-prefix/assets/toby.jpg differ diff --git a/000_temp/46_sp17/31_fileserver-strip-prefix/main.go b/000_temp/46_sp17/31_fileserver-strip-prefix/main.go new file mode 100644 index 00000000..2e190205 --- /dev/null +++ b/000_temp/46_sp17/31_fileserver-strip-prefix/main.go @@ -0,0 +1,17 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", dog) + http.Handle("/resources/", http.StripPrefix("/resources", http.FileServer(http.Dir("./assets")))) + http.ListenAndServe(":8080", nil) +} + +func dog(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + io.WriteString(w, ``) +} diff --git a/000_temp/46_sp17/32_fileserver-strip-prefix/assets/toby.jpg b/000_temp/46_sp17/32_fileserver-strip-prefix/assets/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/46_sp17/32_fileserver-strip-prefix/assets/toby.jpg differ diff --git a/000_temp/46_sp17/32_fileserver-strip-prefix/main.go b/000_temp/46_sp17/32_fileserver-strip-prefix/main.go new file mode 100644 index 00000000..09d9001b --- /dev/null +++ b/000_temp/46_sp17/32_fileserver-strip-prefix/main.go @@ -0,0 +1,17 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", dog) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./assets")))) + http.ListenAndServe(":8080", nil) +} + +func dog(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + io.WriteString(w, ``) +} diff --git a/000_temp/46_sp17/33_fileserver/assets/assets/toby.jpg b/000_temp/46_sp17/33_fileserver/assets/assets/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/46_sp17/33_fileserver/assets/assets/toby.jpg differ diff --git a/000_temp/46_sp17/33_fileserver/main.go b/000_temp/46_sp17/33_fileserver/main.go new file mode 100644 index 00000000..f169d01f --- /dev/null +++ b/000_temp/46_sp17/33_fileserver/main.go @@ -0,0 +1,17 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", dog) + http.Handle("/assets/", http.FileServer(http.Dir("./assets"))) + http.ListenAndServe(":8080", nil) +} + +func dog(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + io.WriteString(w, ``) +} diff --git a/000_temp/46_sp17/34_ServeFile/main.go b/000_temp/46_sp17/34_ServeFile/main.go new file mode 100644 index 00000000..eda4fedc --- /dev/null +++ b/000_temp/46_sp17/34_ServeFile/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/toby.jpg", toby) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + io.WriteString(w, ``) +} + +func toby(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "toby.jpg") +} diff --git a/000_temp/46_sp17/34_ServeFile/toby.jpg b/000_temp/46_sp17/34_ServeFile/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/46_sp17/34_ServeFile/toby.jpg differ diff --git a/000_temp/46_sp17/35_ServeFile/main.go b/000_temp/46_sp17/35_ServeFile/main.go new file mode 100644 index 00000000..5c10c696 --- /dev/null +++ b/000_temp/46_sp17/35_ServeFile/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/toby.jpg", tobers) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + io.WriteString(w, ``) +} + +func tobers(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "toby.jpg") +} diff --git a/000_temp/46_sp17/35_ServeFile/toby.jpg b/000_temp/46_sp17/35_ServeFile/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/46_sp17/35_ServeFile/toby.jpg differ diff --git a/000_temp/46_sp17/36_ServeFile/main.go b/000_temp/46_sp17/36_ServeFile/main.go new file mode 100644 index 00000000..aa5347f5 --- /dev/null +++ b/000_temp/46_sp17/36_ServeFile/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/public/css/main.css", css) + http.HandleFunc("/public/img/bali.jpg", bali) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + io.WriteString(w, ` + + + + Title + + + + +

HELLO WORLD!

+ + +`) +} + +func css(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "public/css/main.css") +} + +func bali(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "public/img/bali.jpg") +} diff --git a/000_temp/46_sp17/36_ServeFile/public/css/main.css b/000_temp/46_sp17/36_ServeFile/public/css/main.css new file mode 100644 index 00000000..04d1e5c5 --- /dev/null +++ b/000_temp/46_sp17/36_ServeFile/public/css/main.css @@ -0,0 +1,21 @@ +html, body { + padding: 0; + border: 0; + margin: 0; +} + +body { + height: 100vh; + display: flex; + flex-flow: row nowrap; + justify-content: center; + align-items: center; + background-image: url("http://github.com/img/bali.jpg"); + background-repeat: no-repeat; + background-size: cover; +} + +h1 { + font-size: 10rem; + color: gold; +} \ No newline at end of file diff --git a/000_temp/46_sp17/36_ServeFile/public/img/bali.jpg b/000_temp/46_sp17/36_ServeFile/public/img/bali.jpg new file mode 100644 index 00000000..9bc69e73 Binary files /dev/null and b/000_temp/46_sp17/36_ServeFile/public/img/bali.jpg differ diff --git a/000_temp/46_sp17/37_FileServer/assets/css/main.css b/000_temp/46_sp17/37_FileServer/assets/css/main.css new file mode 100644 index 00000000..04d1e5c5 --- /dev/null +++ b/000_temp/46_sp17/37_FileServer/assets/css/main.css @@ -0,0 +1,21 @@ +html, body { + padding: 0; + border: 0; + margin: 0; +} + +body { + height: 100vh; + display: flex; + flex-flow: row nowrap; + justify-content: center; + align-items: center; + background-image: url("http://github.com/img/bali.jpg"); + background-repeat: no-repeat; + background-size: cover; +} + +h1 { + font-size: 10rem; + color: gold; +} \ No newline at end of file diff --git a/000_temp/46_sp17/37_FileServer/assets/img/bali.jpg b/000_temp/46_sp17/37_FileServer/assets/img/bali.jpg new file mode 100644 index 00000000..9bc69e73 Binary files /dev/null and b/000_temp/46_sp17/37_FileServer/assets/img/bali.jpg differ diff --git a/000_temp/46_sp17/37_FileServer/main.go b/000_temp/46_sp17/37_FileServer/main.go new file mode 100644 index 00000000..56e70d61 --- /dev/null +++ b/000_temp/46_sp17/37_FileServer/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.Handle("/public/", http.StripPrefix("/public", http.FileServer(http.Dir("assets")))) + + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + io.WriteString(w, ` + + + + Title + + + + +

HELLO WORLD!

+ + +`) +} + +func css(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "public/css/main.css") +} + +func bali(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "public/img/bali.jpg") +} diff --git a/000_temp/46_sp17/38_template/assets/css/main.css b/000_temp/46_sp17/38_template/assets/css/main.css new file mode 100644 index 00000000..04d1e5c5 --- /dev/null +++ b/000_temp/46_sp17/38_template/assets/css/main.css @@ -0,0 +1,21 @@ +html, body { + padding: 0; + border: 0; + margin: 0; +} + +body { + height: 100vh; + display: flex; + flex-flow: row nowrap; + justify-content: center; + align-items: center; + background-image: url("http://github.com/img/bali.jpg"); + background-repeat: no-repeat; + background-size: cover; +} + +h1 { + font-size: 10rem; + color: gold; +} \ No newline at end of file diff --git a/000_temp/46_sp17/38_template/assets/img/bali.jpg b/000_temp/46_sp17/38_template/assets/img/bali.jpg new file mode 100644 index 00000000..9bc69e73 Binary files /dev/null and b/000_temp/46_sp17/38_template/assets/img/bali.jpg differ diff --git a/000_temp/46_sp17/38_template/main.go b/000_temp/46_sp17/38_template/main.go new file mode 100644 index 00000000..abdfb445 --- /dev/null +++ b/000_temp/46_sp17/38_template/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.Handle("/public/", http.StripPrefix("/public", http.FileServer(http.Dir("assets")))) + + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} diff --git a/000_temp/46_sp17/38_template/templates/index.gohtml b/000_temp/46_sp17/38_template/templates/index.gohtml new file mode 100644 index 00000000..091037d5 --- /dev/null +++ b/000_temp/46_sp17/38_template/templates/index.gohtml @@ -0,0 +1,13 @@ + + + + + Title + + + + +

HELLO WORLD!

+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/39_template-vars/assets/css/main.css b/000_temp/46_sp17/39_template-vars/assets/css/main.css new file mode 100644 index 00000000..04d1e5c5 --- /dev/null +++ b/000_temp/46_sp17/39_template-vars/assets/css/main.css @@ -0,0 +1,21 @@ +html, body { + padding: 0; + border: 0; + margin: 0; +} + +body { + height: 100vh; + display: flex; + flex-flow: row nowrap; + justify-content: center; + align-items: center; + background-image: url("http://github.com/img/bali.jpg"); + background-repeat: no-repeat; + background-size: cover; +} + +h1 { + font-size: 10rem; + color: gold; +} \ No newline at end of file diff --git a/000_temp/46_sp17/39_template-vars/assets/img/bali.jpg b/000_temp/46_sp17/39_template-vars/assets/img/bali.jpg new file mode 100644 index 00000000..9bc69e73 Binary files /dev/null and b/000_temp/46_sp17/39_template-vars/assets/img/bali.jpg differ diff --git a/000_temp/46_sp17/39_template-vars/main.go b/000_temp/46_sp17/39_template-vars/main.go new file mode 100644 index 00000000..105277f2 --- /dev/null +++ b/000_temp/46_sp17/39_template-vars/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/vars", vars) + http.Handle("/public/", http.StripPrefix("/public", http.FileServer(http.Dir("assets")))) + + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func vars(w http.ResponseWriter, r *http.Request) { + xs := []string{"James", "Moneypenny", "Q", "M"} + tpl.ExecuteTemplate(w, "vars.gohtml", xs) +} diff --git a/000_temp/46_sp17/39_template-vars/templates/index.gohtml b/000_temp/46_sp17/39_template-vars/templates/index.gohtml new file mode 100644 index 00000000..091037d5 --- /dev/null +++ b/000_temp/46_sp17/39_template-vars/templates/index.gohtml @@ -0,0 +1,13 @@ + + + + + Title + + + + +

HELLO WORLD!

+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/39_template-vars/templates/vars.gohtml b/000_temp/46_sp17/39_template-vars/templates/vars.gohtml new file mode 100644 index 00000000..f9df8efa --- /dev/null +++ b/000_temp/46_sp17/39_template-vars/templates/vars.gohtml @@ -0,0 +1,19 @@ + + + + + Title + + + + +{{range .}} +

{{.}}

+{{end}} + +{{range $index, $value := .}} +

{{$index}} {{$value}}

+{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/40_NotFoundHandler/main.go b/000_temp/46_sp17/40_NotFoundHandler/main.go new file mode 100644 index 00000000..64e8e815 --- /dev/null +++ b/000_temp/46_sp17/40_NotFoundHandler/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + "net/http" +) + +func main() { + http.HandleFunc("/", foo) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, req *http.Request) { + if req.URL.Path != "/" { + http.NotFound(w, req) + return + } + fmt.Println(req.URL.Path) + fmt.Fprintln(w, "go look at your terminal") +} diff --git a/040_json/21_solution/zz_web/templates/index.html b/000_temp/46_sp17/41_html-form/index.html old mode 100755 new mode 100644 similarity index 80% rename from 040_json/21_solution/zz_web/templates/index.html rename to 000_temp/46_sp17/41_html-form/index.html index 566549bd..e8180712 --- a/040_json/21_solution/zz_web/templates/index.html +++ b/000_temp/46_sp17/41_html-form/index.html @@ -6,5 +6,7 @@ +
+ \ No newline at end of file diff --git a/000_temp/46_sp17/42_cookie/01/main.go b/000_temp/46_sp17/42_cookie/01/main.go new file mode 100644 index 00000000..ce846b2d --- /dev/null +++ b/000_temp/46_sp17/42_cookie/01/main.go @@ -0,0 +1,59 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/dog/bowzer", bowzer) + http.HandleFunc("/dog/bowzer/pictures", bowzerpics) + http.HandleFunc("/cat", cat) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + var c *http.Cookie + c, err := r.Cookie("user-cookie") + if err != nil { + fmt.Println(err) + fmt.Printf("%T\n", c) + } + tpl.ExecuteTemplate(w, "index.gohtml", c) +} + +func bowzer(w http.ResponseWriter, r *http.Request) { + c := &http.Cookie{ + Name: "user-cookie", + Value: "this would be the value", + Path: "/dog/bowzer", + } + http.SetCookie(w, c) + tpl.ExecuteTemplate(w, "bowzer.gohtml", c) +} + +func bowzerpics(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("user-cookie") + if err != nil { + fmt.Println(err) + fmt.Printf("%T\n", c) + } + tpl.ExecuteTemplate(w, "bowzerpics.gohtml", c) +} + +func cat(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("user-cookie") + if err != nil { + fmt.Println(err) + fmt.Printf("%T\n", c) + } + tpl.ExecuteTemplate(w, "cat.gohtml", c) +} diff --git a/000_temp/46_sp17/42_cookie/01/templates/bowzer.gohtml b/000_temp/46_sp17/42_cookie/01/templates/bowzer.gohtml new file mode 100644 index 00000000..55eca3fc --- /dev/null +++ b/000_temp/46_sp17/42_cookie/01/templates/bowzer.gohtml @@ -0,0 +1,26 @@ + + + + + + + Bowzer + + + +

Bowzer

+ + +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + + \ No newline at end of file diff --git a/000_temp/46_sp17/42_cookie/01/templates/bowzerpics.gohtml b/000_temp/46_sp17/42_cookie/01/templates/bowzerpics.gohtml new file mode 100644 index 00000000..d97a5bfa --- /dev/null +++ b/000_temp/46_sp17/42_cookie/01/templates/bowzerpics.gohtml @@ -0,0 +1,24 @@ + + + + + + + Bowzer Pics + + + +

Bowzer Pics

+ +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/42_cookie/01/templates/cat.gohtml b/000_temp/46_sp17/42_cookie/01/templates/cat.gohtml new file mode 100644 index 00000000..0629e8ad --- /dev/null +++ b/000_temp/46_sp17/42_cookie/01/templates/cat.gohtml @@ -0,0 +1,24 @@ + + + + + + + Cat + + + +

Cat

+ +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/42_cookie/01/templates/index.gohtml b/000_temp/46_sp17/42_cookie/01/templates/index.gohtml new file mode 100644 index 00000000..3da06dc0 --- /dev/null +++ b/000_temp/46_sp17/42_cookie/01/templates/index.gohtml @@ -0,0 +1,24 @@ + + + + + + + Document + + + +

Index

+ +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/42_cookie/02/main.go b/000_temp/46_sp17/42_cookie/02/main.go new file mode 100644 index 00000000..bb9726b8 --- /dev/null +++ b/000_temp/46_sp17/42_cookie/02/main.go @@ -0,0 +1,59 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/dog/bowzer", bowzer) + http.HandleFunc("/dog/bowzer/pictures", bowzerpics) + http.HandleFunc("/cat", cat) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + var c *http.Cookie + c, err := r.Cookie("user-cookie") + if err != nil { + fmt.Println(err) + fmt.Printf("%T\n", c) + } + tpl.ExecuteTemplate(w, "index.gohtml", c) +} + +func bowzer(w http.ResponseWriter, r *http.Request) { + c := &http.Cookie{ + Name: "user-cookie", + Value: "this would be the value", + Path: "/", + } + http.SetCookie(w, c) + tpl.ExecuteTemplate(w, "bowzer.gohtml", c) +} + +func bowzerpics(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("user-cookie") + if err != nil { + fmt.Println(err) + fmt.Printf("%T\n", c) + } + tpl.ExecuteTemplate(w, "bowzerpics.gohtml", c) +} + +func cat(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("user-cookie") + if err != nil { + fmt.Println(err) + fmt.Printf("%T\n", c) + } + tpl.ExecuteTemplate(w, "cat.gohtml", c) +} diff --git a/000_temp/46_sp17/42_cookie/02/templates/bowzer.gohtml b/000_temp/46_sp17/42_cookie/02/templates/bowzer.gohtml new file mode 100644 index 00000000..55eca3fc --- /dev/null +++ b/000_temp/46_sp17/42_cookie/02/templates/bowzer.gohtml @@ -0,0 +1,26 @@ + + + + + + + Bowzer + + + +

Bowzer

+ + +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + + \ No newline at end of file diff --git a/000_temp/46_sp17/42_cookie/02/templates/bowzerpics.gohtml b/000_temp/46_sp17/42_cookie/02/templates/bowzerpics.gohtml new file mode 100644 index 00000000..d97a5bfa --- /dev/null +++ b/000_temp/46_sp17/42_cookie/02/templates/bowzerpics.gohtml @@ -0,0 +1,24 @@ + + + + + + + Bowzer Pics + + + +

Bowzer Pics

+ +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/42_cookie/02/templates/cat.gohtml b/000_temp/46_sp17/42_cookie/02/templates/cat.gohtml new file mode 100644 index 00000000..0629e8ad --- /dev/null +++ b/000_temp/46_sp17/42_cookie/02/templates/cat.gohtml @@ -0,0 +1,24 @@ + + + + + + + Cat + + + +

Cat

+ +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/42_cookie/02/templates/index.gohtml b/000_temp/46_sp17/42_cookie/02/templates/index.gohtml new file mode 100644 index 00000000..3da06dc0 --- /dev/null +++ b/000_temp/46_sp17/42_cookie/02/templates/index.gohtml @@ -0,0 +1,24 @@ + + + + + + + Document + + + +

Index

+ +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/43_cookie/main.go b/000_temp/46_sp17/43_cookie/main.go new file mode 100644 index 00000000..6f35e088 --- /dev/null +++ b/000_temp/46_sp17/43_cookie/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "github.com/satori/go.uuid" + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("session") + if err != nil { + u := uuid.NewV4() + c = &http.Cookie{ + Name: "session", + Value: u.String(), + Path: "/", + HttpOnly: true, + } + } + http.SetCookie(w, c) + tpl.ExecuteTemplate(w, "index.gohtml", c) +} diff --git a/000_temp/46_sp17/43_cookie/templates/index.gohtml b/000_temp/46_sp17/43_cookie/templates/index.gohtml new file mode 100644 index 00000000..34d82136 --- /dev/null +++ b/000_temp/46_sp17/43_cookie/templates/index.gohtml @@ -0,0 +1,21 @@ + + + + + + + INDEX PAGE + + + +

You are at index

+ +{{if .}} +

The Entire Cookie: {{.}}

+

Name {{.Name}}

+

Value {{.Value}}

+{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/44_map/main.go b/000_temp/46_sp17/44_map/main.go new file mode 100644 index 00000000..0cb04f35 --- /dev/null +++ b/000_temp/46_sp17/44_map/main.go @@ -0,0 +1,154 @@ +package main + +import ( + "fmt" + "github.com/satori/go.uuid" + "html/template" + "net/http" +) + +type user struct { + Id string + First string + Last string + Email string + Password string +} + +var tpl *template.Template + +var muser = map[string]user{} // key is userid, value is user +var msession = map[string]string{} // key is sessionid, value is userid + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/other", other) + http.HandleFunc("/login", login) + http.HandleFunc("/logout", logout) + http.HandleFunc("/signup", signup) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("mysess") + if err != nil { + u := uuid.NewV4() + c = &http.Cookie{ + Name: "mysess", + Value: u.String(), + Path: "/", + HttpOnly: true, + } + } + uid := msession[c.Value] + usr := muser[uid] + + fmt.Println("SESSION ID", c.Value) + + http.SetCookie(w, c) + tpl.ExecuteTemplate(w, "index.gohtml", usr) +} + +func other(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("mysess") + if err != nil { + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + uid := msession[c.Value] + usr := muser[uid] + + fmt.Println("SESSION ID", c.Value) + + http.SetCookie(w, c) + tpl.ExecuteTemplate(w, "other.gohtml", usr) +} + +func logout(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("mysess") + if err != nil { + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + delete(msession, c.Value) + c.MaxAge = -1 + http.SetCookie(w, c) + http.Redirect(w, r, "/", http.StatusSeeOther) + //fmt.Fprint(w, "You've been logged out") +} + +func login(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("mysess") + if err != nil { + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + + if r.Method == "POST" { + em := r.FormValue("email") + pw := r.FormValue("password") + // get all of the usernames and passwords + m := map[string]user{} + for _, v := range muser { + m[v.Email] = v + } + usr, ok := m[em] + if !ok { + http.Redirect(w, r, "/login", http.StatusForbidden) + return + } + if usr.Password != pw { + http.Redirect(w, r, "/login", http.StatusForbidden) + return + } + msession[c.Value] = usr.Id + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + + tpl.ExecuteTemplate(w, "login.gohtml", nil) +} + +func signup(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("mysess") + + // if no cookie, redirect to index + if err != nil { + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + + // user has already signed up, so redirect + uid := msession[c.Value] + usr := muser[uid] + if usr.Email != "" { + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + + if r.Method == "POST" { + fn := r.FormValue("first") + ln := r.FormValue("last") + em := r.FormValue("email") + pw := r.FormValue("password") + u := uuid.NewV4() + usr = user{ + Id: u.String(), + First: fn, + Last: ln, + Email: em, + Password: pw, + } + muser[usr.Id] = usr + msession[c.Value] = usr.Id + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + + tpl.ExecuteTemplate(w, "signup.gohtml", nil) +} diff --git a/000_temp/46_sp17/44_map/templates/index.gohtml b/000_temp/46_sp17/44_map/templates/index.gohtml new file mode 100644 index 00000000..1d71c626 --- /dev/null +++ b/000_temp/46_sp17/44_map/templates/index.gohtml @@ -0,0 +1,25 @@ + + + + + + + INDEX PAGE + + + +

You are at index

+ +

login

+

log out

+

sign up

+

some other page

+ +

First: {{.First}}

+

Last: {{.Last}}

+

Email: {{.Email}}

+

Password: {{.Password}}

+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/44_map/templates/login.gohtml b/000_temp/46_sp17/44_map/templates/login.gohtml new file mode 100644 index 00000000..a9e7d40b --- /dev/null +++ b/000_temp/46_sp17/44_map/templates/login.gohtml @@ -0,0 +1,26 @@ + + + + + + + LOGIN + + + + +

LOGIN

+ +
+
+
+ +
+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/44_map/templates/other.gohtml b/000_temp/46_sp17/44_map/templates/other.gohtml new file mode 100644 index 00000000..a5352a92 --- /dev/null +++ b/000_temp/46_sp17/44_map/templates/other.gohtml @@ -0,0 +1,25 @@ + + + + + + + OTHER + + + +

You are at some other page

+ +

login

+

log out

+

sign up

+

some other page

+ +

First: {{.First}}

+

Last: {{.Last}}

+

Email: {{.Email}}

+

Password: {{.Password}}

+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/44_map/templates/signup.gohtml b/000_temp/46_sp17/44_map/templates/signup.gohtml new file mode 100644 index 00000000..805742d1 --- /dev/null +++ b/000_temp/46_sp17/44_map/templates/signup.gohtml @@ -0,0 +1,28 @@ + + + + + + + signup + + + + +

You are at sign up

+ +
+
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/45_session/01_cookie/main.go b/000_temp/46_sp17/45_session/01_cookie/main.go new file mode 100644 index 00000000..5046f745 --- /dev/null +++ b/000_temp/46_sp17/45_session/01_cookie/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "fmt" + "github.com/satori/go.uuid" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + cookie, err := r.Cookie("session") + if err != nil { + id := uuid.NewV4() + cookie = &http.Cookie{ + Name: "session", + Value: id.String(), + HttpOnly: true, + Path: "/", + } + http.SetCookie(w, cookie) + } + fmt.Println(cookie) + fmt.Fprint(w, cookie) +} diff --git a/000_temp/46_sp17/45_session/02_session/main.go b/000_temp/46_sp17/45_session/02_session/main.go new file mode 100644 index 00000000..a598ab5b --- /dev/null +++ b/000_temp/46_sp17/45_session/02_session/main.go @@ -0,0 +1,76 @@ +package main + +import ( + "github.com/satori/go.uuid" + "html/template" + "net/http" +) + +type user struct { + UserName string + First string + Last string +} + +var tpl *template.Template +var dbUsers = map[string]user{} // user ID, user +var dbSessions = map[string]string{} // session ID, user ID (email) + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/bar", bar) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("session") + if err != nil { + id := uuid.NewV4() + c = &http.Cookie{ + Name: "session", + Value: id.String(), + HttpOnly: true, + Path: "/", + } + http.SetCookie(w, c) + } + + var u user + if uid, ok := dbSessions[c.Value]; ok { + u = dbUsers[uid] + } + + // process form submission + if r.Method == http.MethodPost { + e := r.FormValue("email") + f := r.FormValue("first") + l := r.FormValue("last") + u = user{e, f, l} + dbSessions[c.Value] = e + dbUsers[e] = u + } + + tpl.ExecuteTemplate(w, "index.gohtml", u) +} + +func bar(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("session") + if err != nil { + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + + e, ok := dbSessions[c.Value] + if !ok { + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + + u := dbUsers[e] + tpl.ExecuteTemplate(w, "bar.gohtml", u) +} diff --git a/000_temp/46_sp17/45_session/02_session/templates/bar.gohtml b/000_temp/46_sp17/45_session/02_session/templates/bar.gohtml new file mode 100644 index 00000000..884d3edd --- /dev/null +++ b/000_temp/46_sp17/45_session/02_session/templates/bar.gohtml @@ -0,0 +1,23 @@ + + + + + + + BAR PAGE + + + +

WELCOME TO THE BAR!

+ +{{if .First}} +Username {{.UserName}}
+First {{.First}}
+Last {{.Last}}
+{{end}} + +go to index + + + \ No newline at end of file diff --git a/000_temp/46_sp17/45_session/02_session/templates/index.gohtml b/000_temp/46_sp17/45_session/02_session/templates/index.gohtml new file mode 100644 index 00000000..49a26528 --- /dev/null +++ b/000_temp/46_sp17/45_session/02_session/templates/index.gohtml @@ -0,0 +1,28 @@ + + + + + + + INDEX PAGE + + + +{{if .First}} +Username {{.UserName}}
+First {{.First}}
+Last {{.Last}}
+{{end}} + +
+ + + + +
+ +go to bar + + + \ No newline at end of file diff --git a/000_temp/46_sp17/45_session/03_signup/main.go b/000_temp/46_sp17/45_session/03_signup/main.go new file mode 100644 index 00000000..c71be7c9 --- /dev/null +++ b/000_temp/46_sp17/45_session/03_signup/main.go @@ -0,0 +1,86 @@ +package main + +import ( + "github.com/satori/go.uuid" + "html/template" + "net/http" +) + +type user struct { + UserName string + Password string + First string + Last string +} + +var tpl *template.Template +var dbUsers = map[string]user{} // user ID, user +var dbSessions = map[string]string{} // session ID, user ID (email) + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/signup", signup) + http.HandleFunc("/bar", bar) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + u := getUser(w, r) + tpl.ExecuteTemplate(w, "index.gohtml", u) +} + +func signup(w http.ResponseWriter, r *http.Request) { + if alreadyLoggedIn(r) { + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + + // process form submission + if r.Method == http.MethodPost { + e := r.FormValue("email") + p := r.FormValue("password") + f := r.FormValue("first") + l := r.FormValue("last") + + // is username taken, eg, user already signed up? + if _, ok := dbUsers[e]; ok { + http.Error(w, "Username already taken", http.StatusForbidden) + return + } + + // create session + id := uuid.NewV4() + c := &http.Cookie{ + Name: "session", + Value: id.String(), + HttpOnly: true, + Path: "/", + } + http.SetCookie(w, c) + dbSessions[c.Value] = e + + // store user in dbUsers + u := user{e, p, f, l} + dbUsers[e] = u + + // all done processing form submission + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + + tpl.ExecuteTemplate(w, "signup.gohtml", nil) +} + +func bar(w http.ResponseWriter, r *http.Request) { + if !alreadyLoggedIn(r) { + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + u := getUser(w, r) + tpl.ExecuteTemplate(w, "bar.gohtml", u) +} diff --git a/000_temp/46_sp17/45_session/03_signup/session.go b/000_temp/46_sp17/45_session/03_signup/session.go new file mode 100644 index 00000000..6cf7975b --- /dev/null +++ b/000_temp/46_sp17/45_session/03_signup/session.go @@ -0,0 +1,36 @@ +package main + +import ( + "github.com/satori/go.uuid" + "net/http" +) + +func getUser(w http.ResponseWriter, r *http.Request) user { + c, err := r.Cookie("session") + if err != nil { + id := uuid.NewV4() + c = &http.Cookie{ + Name: "session", + Value: id.String(), + HttpOnly: true, + Path: "/", + } + http.SetCookie(w, c) + } + + var u user + if e, ok := dbSessions[c.Value]; ok { + u = dbUsers[e] + } + return u +} + +func alreadyLoggedIn(r *http.Request) bool { + c, err := r.Cookie("session") + if err != nil { + return false + } + e := dbSessions[c.Value] + _, ok := dbUsers[e] + return ok +} diff --git a/000_temp/46_sp17/45_session/03_signup/templates/bar.gohtml b/000_temp/46_sp17/45_session/03_signup/templates/bar.gohtml new file mode 100644 index 00000000..884d3edd --- /dev/null +++ b/000_temp/46_sp17/45_session/03_signup/templates/bar.gohtml @@ -0,0 +1,23 @@ + + + + + + + BAR PAGE + + + +

WELCOME TO THE BAR!

+ +{{if .First}} +Username {{.UserName}}
+First {{.First}}
+Last {{.Last}}
+{{end}} + +go to index + + + \ No newline at end of file diff --git a/000_temp/46_sp17/45_session/03_signup/templates/index.gohtml b/000_temp/46_sp17/45_session/03_signup/templates/index.gohtml new file mode 100644 index 00000000..9da7b4f2 --- /dev/null +++ b/000_temp/46_sp17/45_session/03_signup/templates/index.gohtml @@ -0,0 +1,22 @@ + + + + + + + INDEX PAGE + + + +{{if .First}} +Username {{.UserName}}
+First {{.First}}
+Last {{.Last}}
+{{end}} + +go to signup +go to bar + + + \ No newline at end of file diff --git a/000_temp/46_sp17/45_session/03_signup/templates/signup.gohtml b/000_temp/46_sp17/45_session/03_signup/templates/signup.gohtml new file mode 100644 index 00000000..5748cd84 --- /dev/null +++ b/000_temp/46_sp17/45_session/03_signup/templates/signup.gohtml @@ -0,0 +1,23 @@ + + + + + + + SIGNUP + + + +
+ + + + + +
+ +go to index + + + \ No newline at end of file diff --git a/000_temp/46_sp17/46_cookie/main.go b/000_temp/46_sp17/46_cookie/main.go new file mode 100644 index 00000000..1d731a2b --- /dev/null +++ b/000_temp/46_sp17/46_cookie/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", foo) + http.HandleFunc("/bar", bar) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + c := &http.Cookie{ + Name: "wasssup", + Value: "tecate", + Path: "/", + HttpOnly: true, + } + http.SetCookie(w, c) + io.WriteString(w, "

hello

") +} + +func bar(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("wasssup") + if err != nil { + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + io.WriteString(w, c.Value) +} diff --git a/000_temp/46_sp17/47_JSON/main.go b/000_temp/46_sp17/47_JSON/main.go new file mode 100644 index 00000000..048b1e1d --- /dev/null +++ b/000_temp/46_sp17/47_JSON/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "encoding/json" + "fmt" +) + +type person struct { + First string + Last string + Ltk bool + Items []string +} + +func main() { + p1 := person{ + First: "James", + Last: "Bond", + Ltk: true, + Items: []string{ + "Martini", + "Walther PPK", + "Astin Martin", + }, + } + bs, err := json.Marshal(p1) + if err != nil { + fmt.Println(err) + } + fmt.Println(p1) + fmt.Println("------------") + fmt.Println(string(bs)) +} diff --git a/000_temp/46_sp17/48_json/01_marshal/main.go b/000_temp/46_sp17/48_json/01_marshal/main.go new file mode 100644 index 00000000..3099ab33 --- /dev/null +++ b/000_temp/46_sp17/48_json/01_marshal/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "encoding/json" + "fmt" +) + +type person struct { + First string + Last string +} + +func main() { + p1 := person{ + First: "James", + Last: "Bond", + } + + p2 := person{ + First: "Miss", + Last: "Moneypenny", + } + + xp := []person{p1, p2} + + fmt.Printf("go data: %+v\n", xp) + + bs, err := json.Marshal(xp) + if err != nil { + fmt.Println(err) + } + fmt.Println("json:", string(bs)) +} diff --git a/000_temp/46_sp17/48_json/02_unmarshal/main.go b/000_temp/46_sp17/48_json/02_unmarshal/main.go new file mode 100644 index 00000000..a27aecaa --- /dev/null +++ b/000_temp/46_sp17/48_json/02_unmarshal/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "encoding/json" + "fmt" +) + +type person struct { + First string + Last string +} + +func main() { + j := `[{"First":"James","Last":"Bond"},{"First":"Miss","Last":"Moneypenny"}]` + fmt.Println("json:", j) + + xp := []person{} + + err := json.Unmarshal([]byte(j), &xp) + if err != nil { + fmt.Println(err) + } + fmt.Printf("go data: %+v\n", xp) + + for i, v := range xp { + fmt.Println(i, v) + fmt.Println("\t", v.First) + } +} diff --git a/000_temp/46_sp17/48_json/03_tags/main.go b/000_temp/46_sp17/48_json/03_tags/main.go new file mode 100644 index 00000000..d513161d --- /dev/null +++ b/000_temp/46_sp17/48_json/03_tags/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "encoding/json" + "fmt" +) + +type person struct { + First string `json:"fname"` + Last string +} + +func main() { + j := `[{"fname":"James","last":"Bond"},{"fname":"Miss","last":"Moneypenny"}]` + fmt.Println("json:", j) + + xp := []person{} + + err := json.Unmarshal([]byte(j), &xp) + if err != nil { + fmt.Println(err) + } + fmt.Printf("go data: %+v\n", xp) + + for i, v := range xp { + fmt.Println(i, v) + fmt.Println("\t", v.First) + } +} diff --git a/000_temp/46_sp17/48_json/04_encode/main.go b/000_temp/46_sp17/48_json/04_encode/main.go new file mode 100644 index 00000000..aa7dae49 --- /dev/null +++ b/000_temp/46_sp17/48_json/04_encode/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "encoding/json" + "fmt" + "net/http" +) + +type person struct { + First string + Last string +} + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + p1 := person{ + First: "James", + Last: "Bond", + } + + p2 := person{ + First: "Miss", + Last: "Moneypenny", + } + + xp := []person{p1, p2} + + err := json.NewEncoder(w).Encode(xp) + if err != nil { + fmt.Println(err) + } +} diff --git a/000_temp/46_sp17/48_json/05_decode/main.go b/000_temp/46_sp17/48_json/05_decode/main.go new file mode 100644 index 00000000..dbafdb3e --- /dev/null +++ b/000_temp/46_sp17/48_json/05_decode/main.go @@ -0,0 +1,66 @@ +package main + +import ( + "encoding/json" + "fmt" + "html/template" + "net/http" +) + +type person struct { + First string + Last string +} + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/send", send) + http.HandleFunc("/catch", catch) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + p1 := person{ + First: "James", + Last: "Bond", + } + + p2 := person{ + First: "Miss", + Last: "Moneypenny", + } + + xp := []person{p1, p2} + + err := json.NewEncoder(w).Encode(xp) + if err != nil { + fmt.Println(err) + } +} + +func send(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "send.gohtml", nil) +} + +var xp []person + +func catch(w http.ResponseWriter, r *http.Request) { + + if r.Method == http.MethodPost { + err := json.NewDecoder(r.Body).Decode(&xp) + if err != nil { + fmt.Println(err) + } + fmt.Println(xp) + } + + if r.Method == http.MethodGet { + tpl.ExecuteTemplate(w, "catch.gohtml", xp) + } +} diff --git a/000_temp/46_sp17/48_json/05_decode/templates/catch.gohtml b/000_temp/46_sp17/48_json/05_decode/templates/catch.gohtml new file mode 100644 index 00000000..74f50269 --- /dev/null +++ b/000_temp/46_sp17/48_json/05_decode/templates/catch.gohtml @@ -0,0 +1,20 @@ + + + + + + + Document + + + +{{range .}} +Here is the data: {{.}}
+FIRST: {{.First}}
+Last: {{.Last}} +

+{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/48_json/05_decode/templates/send.gohtml b/000_temp/46_sp17/48_json/05_decode/templates/send.gohtml new file mode 100644 index 00000000..610483b0 --- /dev/null +++ b/000_temp/46_sp17/48_json/05_decode/templates/send.gohtml @@ -0,0 +1,49 @@ + + + + + + + Document + + + + +

We are now going to send data to the /catch path

+ + + + + \ No newline at end of file diff --git a/000_temp/46_sp17/48_json/06_cookie/main.go b/000_temp/46_sp17/48_json/06_cookie/main.go new file mode 100644 index 00000000..21a39e25 --- /dev/null +++ b/000_temp/46_sp17/48_json/06_cookie/main.go @@ -0,0 +1,94 @@ +package main + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "html/template" + "io/ioutil" + "net/http" +) + +type person struct { + First string + Last string +} + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/send", send) + http.HandleFunc("/catch", catch) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + xp := getUsers(r) + + tpl.ExecuteTemplate(w, "index.gohtml", xp) +} + +func send(w http.ResponseWriter, r *http.Request) { + xp := getUsers(r) + + tpl.ExecuteTemplate(w, "send.gohtml", xp) +} + +func catch(w http.ResponseWriter, r *http.Request) { + xp := getUsers(r) + + if r.Method == http.MethodPost { + bs, err := ioutil.ReadAll(r.Body) + if err != nil { + fmt.Println(err) + } + + err = json.Unmarshal(bs, &xp) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(xp) + + s := base64.StdEncoding.EncodeToString(bs) + fmt.Println(s) + + c := &http.Cookie{ + Name: "userdata", + Value: s, + Path: "/", + HttpOnly: true, + } + http.SetCookie(w, c) + } + + if r.Method == http.MethodGet { + tpl.ExecuteTemplate(w, "catch.gohtml", xp) + } +} + +func getUsers(r *http.Request) []person { + var xp []person + + c, err := r.Cookie("userdata") + if err == nil { + bs, err := base64.StdEncoding.DecodeString(c.Value) + if err != nil { + fmt.Println(err) + return xp + } + + fmt.Println("just after base64 decode:", string(bs)) + + err = json.Unmarshal(bs, &xp) + if err != nil { + fmt.Println("unmarshalling in decode from b64", err) + } + } + return xp +} diff --git a/000_temp/46_sp17/48_json/06_cookie/templates/catch.gohtml b/000_temp/46_sp17/48_json/06_cookie/templates/catch.gohtml new file mode 100644 index 00000000..bb497a18 --- /dev/null +++ b/000_temp/46_sp17/48_json/06_cookie/templates/catch.gohtml @@ -0,0 +1,20 @@ + + + + + + + CATCH + + + +{{range .}} +Here is the data: {{.}}
+FIRST: {{.First}}
+Last: {{.Last}} +

+{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/48_json/06_cookie/templates/index.gohtml b/000_temp/46_sp17/48_json/06_cookie/templates/index.gohtml new file mode 100644 index 00000000..9ec8fd9c --- /dev/null +++ b/000_temp/46_sp17/48_json/06_cookie/templates/index.gohtml @@ -0,0 +1,20 @@ + + + + + + + INDEX + + + +{{range .}} +Here is the data: {{.}}
+FIRST: {{.First}}
+Last: {{.Last}} +

+{{end}} + + + \ No newline at end of file diff --git a/000_temp/46_sp17/48_json/06_cookie/templates/send.gohtml b/000_temp/46_sp17/48_json/06_cookie/templates/send.gohtml new file mode 100644 index 00000000..302b4b0e --- /dev/null +++ b/000_temp/46_sp17/48_json/06_cookie/templates/send.gohtml @@ -0,0 +1,56 @@ + + + + + + + SEND + + + + +

We are now going to send data to the /catch path

+

{{range .}} + Here is the data: {{.}}
+ FIRST: {{.First}}
+ Last: {{.Last}} +

+ {{end}} +

+ + + + + \ No newline at end of file diff --git a/000_temp/46_sp17/49_multiple-redirects/main.go b/000_temp/46_sp17/49_multiple-redirects/main.go new file mode 100644 index 00000000..97a5d8e2 --- /dev/null +++ b/000_temp/46_sp17/49_multiple-redirects/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/foo", foo) + http.HandleFunc("/bar", bar) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/", http.StatusSeeOther) + return // comment out and experiment to see what happens + http.Redirect(w, r, "/bar", http.StatusSeeOther) +} + +func bar(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "bar.gohtml", nil) +} diff --git a/000_temp/46_sp17/49_multiple-redirects/templates/bar.gohtml b/000_temp/46_sp17/49_multiple-redirects/templates/bar.gohtml new file mode 100644 index 00000000..0522363c --- /dev/null +++ b/000_temp/46_sp17/49_multiple-redirects/templates/bar.gohtml @@ -0,0 +1,25 @@ + + + + + + + BAR + + + + +

You are at BAR

+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/49_multiple-redirects/templates/index.gohtml b/000_temp/46_sp17/49_multiple-redirects/templates/index.gohtml new file mode 100644 index 00000000..27eea8db --- /dev/null +++ b/000_temp/46_sp17/49_multiple-redirects/templates/index.gohtml @@ -0,0 +1,26 @@ + + + + + + + index + + + + +

You are at INDEX

+ +

GO TO FOO

+ + \ No newline at end of file diff --git a/000_temp/46_sp17/50_mongo/main.go b/000_temp/46_sp17/50_mongo/main.go new file mode 100644 index 00000000..0e07afe5 --- /dev/null +++ b/000_temp/46_sp17/50_mongo/main.go @@ -0,0 +1,51 @@ +package main + +import ( + "fmt" + "gopkg.in/mgo.v2" + "gopkg.in/mgo.v2/bson" + "html/template" + "net/http" +) + +type customer struct { + Name string `json:"name" bson:"name"` +} + +var tpl *template.Template +var DB *mgo.Database +var Customer *mgo.Collection + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) + + // get a mongo sessions + //s, err := mgo.Dial("mongodb://bond:moneypenny007@localhost/bookstore") + s, err := mgo.Dial("mongodb://localhost/bookstore") + if err != nil { + panic(err) + } + + if err = s.Ping(); err != nil { + panic(err) + } + + DB = s.DB("bookstore") + Customer = DB.C("customer") + + fmt.Println("You connected to your mongo database.") +} + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + customers := []customer{} + err := Customer.Find(bson.M{}).All(&customers) + if err != nil { + fmt.Println(err) + } + tpl.ExecuteTemplate(w, "index.gohtml", customers) +} diff --git a/000_temp/46_sp17/50_mongo/templates/index.gohtml b/000_temp/46_sp17/50_mongo/templates/index.gohtml new file mode 100644 index 00000000..7b16697b --- /dev/null +++ b/000_temp/46_sp17/50_mongo/templates/index.gohtml @@ -0,0 +1,15 @@ + + + + + + + INDEX + + + +

{{.}}

+ + + \ No newline at end of file diff --git a/000_temp/46_sp17/51_question/01/main.go b/000_temp/46_sp17/51_question/01/main.go new file mode 100644 index 00000000..15fa7006 --- /dev/null +++ b/000_temp/46_sp17/51_question/01/main.go @@ -0,0 +1,52 @@ +package main + +import ( + "fmt" + "math/rand" + "sync" + "time" +) + +var wg sync.WaitGroup + +type SafeCounter struct { + c int + sync.Mutex +} + +func (c *SafeCounter) Add() { + c.Lock() + defer c.Unlock() + c.c++ +} + +var counter *SafeCounter = &SafeCounter{} + +func main() { + + fmt.Println(&counter.c) + + wg.Add(2) + go incrementor("Foo:") + go incrementor("Bar:") + wg.Wait() + fmt.Println("Final Counter:", counter.c) +} + +func incrementor(s string) { + rand.Seed(time.Now().UnixNano()) + for i := 0; i < 20; i++ { + x := counter + fmt.Println("1----", counter) + fmt.Println("2----", x) + x.Add() + counter = x + time.Sleep(time.Duration(rand.Intn(3)) * time.Millisecond) + fmt.Println(s, i, "Counter:", counter.c) + } + wg.Done() +} + +// go run -race main.go +// vs +// go run main.go diff --git a/000_temp/46_sp17/51_question/02/main.go b/000_temp/46_sp17/51_question/02/main.go new file mode 100644 index 00000000..dd1fee0d --- /dev/null +++ b/000_temp/46_sp17/51_question/02/main.go @@ -0,0 +1,48 @@ +package main + +import ( + "fmt" + "math/rand" + "sync" + "time" +) + +var wg sync.WaitGroup + +type SafeCounter struct { + c int + m sync.Mutex +} + +func (sc *SafeCounter) Add() { + sc.m.Lock() + defer sc.m.Unlock() + sc.c++ +} + +var counter *SafeCounter = &SafeCounter{} + +func main() { + + fmt.Println(&counter.c) + + wg.Add(2) + go incrementor("Foo:") + go incrementor("Bar:") + wg.Wait() + fmt.Println("Final Counter:", counter.c) +} + +func incrementor(s string) { + rand.Seed(time.Now().UnixNano()) + for i := 0; i < 20; i++ { + counter.Add() + time.Sleep(time.Duration(rand.Intn(3)) * time.Millisecond) + //fmt.Println(s, i, "Counter:", counter.c) // causes a race; no lock here; multiple goroutines accessing to READ the value + } + wg.Done() +} + +// go run -race main.go +// vs +// go run main.go diff --git a/000_temp/46_sp17/52-review/01/main.go b/000_temp/46_sp17/52-review/01/main.go new file mode 100644 index 00000000..1c0890fd --- /dev/null +++ b/000_temp/46_sp17/52-review/01/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "some text hello world") +} diff --git a/000_temp/46_sp17/52-review/02/main.go b/000_temp/46_sp17/52-review/02/main.go new file mode 100644 index 00000000..a619af57 --- /dev/null +++ b/000_temp/46_sp17/52-review/02/main.go @@ -0,0 +1,154 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, ` + + + + + Title + + + + +
+

hello world

+
+ + + + + `) +} diff --git a/000_temp/46_sp17/52-review/03/main.go b/000_temp/46_sp17/52-review/03/main.go new file mode 100644 index 00000000..7b469e6f --- /dev/null +++ b/000_temp/46_sp17/52-review/03/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + io.WriteString(w, `

Hello World

`) +} diff --git a/000_temp/46_sp17/52-review/04/main.go b/000_temp/46_sp17/52-review/04/main.go new file mode 100644 index 00000000..21ff5e92 --- /dev/null +++ b/000_temp/46_sp17/52-review/04/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} diff --git a/000_temp/46_sp17/52-review/04/templates/index.gohtml b/000_temp/46_sp17/52-review/04/templates/index.gohtml new file mode 100644 index 00000000..f0bd030e --- /dev/null +++ b/000_temp/46_sp17/52-review/04/templates/index.gohtml @@ -0,0 +1,138 @@ + + + + + Title + + + + +
+

hello world

+
+ + + + \ No newline at end of file diff --git a/000_temp/46_sp17/52-review/05/main.go b/000_temp/46_sp17/52-review/05/main.go new file mode 100644 index 00000000..f91303d3 --- /dev/null +++ b/000_temp/46_sp17/52-review/05/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + n := "James Bond" + tpl.ExecuteTemplate(w, "index.gohtml", n) +} diff --git a/000_temp/46_sp17/52-review/05/templates/index.gohtml b/000_temp/46_sp17/52-review/05/templates/index.gohtml new file mode 100644 index 00000000..229adf46 --- /dev/null +++ b/000_temp/46_sp17/52-review/05/templates/index.gohtml @@ -0,0 +1,138 @@ + + + + + Title + + + + +
+

{{.}}

+
+ + + + \ No newline at end of file diff --git a/000_temp/46_sp17/52-review/06/main.go b/000_temp/46_sp17/52-review/06/main.go new file mode 100644 index 00000000..cbabd247 --- /dev/null +++ b/000_temp/46_sp17/52-review/06/main.go @@ -0,0 +1,40 @@ +package main + +import ( + "html/template" + "net/http" +) + +type person struct { + First string + Last string + Saying string +} + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + p1 := person{ + First: "James", + Last: "Bond", + Saying: "Shaken, not stirred.", + } + + p2 := person{ + First: "Miss", + Last: "Moneypenny", + Saying: "Hello, James. It is sooooooooo good to see you.", + } + + xp := []person{p1, p2} + tpl.ExecuteTemplate(w, "index.gohtml", xp) +} diff --git a/000_temp/46_sp17/52-review/06/templates/index.gohtml b/000_temp/46_sp17/52-review/06/templates/index.gohtml new file mode 100644 index 00000000..0c3f8f59 --- /dev/null +++ b/000_temp/46_sp17/52-review/06/templates/index.gohtml @@ -0,0 +1,138 @@ + + + + + Title + + + + +
+ {{range .}} +

{{.First}} {{.Last}}

+

{{.Saying}}

+ {{end}} +
+ + + + \ No newline at end of file diff --git a/000_temp/46_sp17/52-review/07/main.go b/000_temp/46_sp17/52-review/07/main.go new file mode 100644 index 00000000..328f21e3 --- /dev/null +++ b/000_temp/46_sp17/52-review/07/main.go @@ -0,0 +1,41 @@ +package main + +import ( + "html/template" + "net/http" +) + +type person struct { + First string + Last string + Saying string +} + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("public")))) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + p1 := person{ + First: "James", + Last: "Bond", + Saying: "Shaken, not stirred.", + } + + p2 := person{ + First: "Miss", + Last: "Moneypenny", + Saying: "Hello, James. It is sooooooooo good to see you.", + } + + xp := []person{p1, p2} + tpl.ExecuteTemplate(w, "index.gohtml", xp) +} diff --git a/000_temp/46_sp17/52-review/07/public/css/index.css b/000_temp/46_sp17/52-review/07/public/css/index.css new file mode 100644 index 00000000..1dd9f35f --- /dev/null +++ b/000_temp/46_sp17/52-review/07/public/css/index.css @@ -0,0 +1,16 @@ +html, body, h1 { + padding: 0; + border: 0; + margin: 0; + box-sizing: border-box; +} + +main { + display: flex; + flex-direction: column; + flex-wrap: nowrap; + justify-content: center; + align-items: center; + background-image: linear-gradient(red, yellow, blue); + height: 100vh; +} \ No newline at end of file diff --git a/000_temp/46_sp17/52-review/07/templates/index.gohtml b/000_temp/46_sp17/52-review/07/templates/index.gohtml new file mode 100644 index 00000000..0788480b --- /dev/null +++ b/000_temp/46_sp17/52-review/07/templates/index.gohtml @@ -0,0 +1,120 @@ + + + + + Title + + + + +
+ {{range .}} +

{{.First}} {{.Last}}

+

{{.Saying}}

+ {{end}} +
+ + + + \ No newline at end of file diff --git a/000_temp/46_sp17/52-review/08/main.go b/000_temp/46_sp17/52-review/08/main.go new file mode 100644 index 00000000..1c692706 --- /dev/null +++ b/000_temp/46_sp17/52-review/08/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("public")))) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + s := "Paradise Found" + tpl.ExecuteTemplate(w, "index.gohtml", s) +} diff --git a/000_temp/46_sp17/52-review/08/public/css/index.css b/000_temp/46_sp17/52-review/08/public/css/index.css new file mode 100644 index 00000000..e51c29b4 --- /dev/null +++ b/000_temp/46_sp17/52-review/08/public/css/index.css @@ -0,0 +1,24 @@ +html, body, h1 { + padding: 0; + border: 0; + margin: 0; + box-sizing: border-box; +} + +main { + display: flex; + flex-direction: column; + flex-wrap: nowrap; + justify-content: center; + align-items: center; + background-image: url("http://github.com/assets/img/surf.png"); + background-size: cover; + background-repeat: no-repeat; + background-position: center; + height: 100vh; +} + +h1 { + font-size: 8rem; + color: white; +} \ No newline at end of file diff --git a/000_temp/46_sp17/52-review/08/public/img/surf.png b/000_temp/46_sp17/52-review/08/public/img/surf.png new file mode 100644 index 00000000..1636912e Binary files /dev/null and b/000_temp/46_sp17/52-review/08/public/img/surf.png differ diff --git a/000_temp/46_sp17/52-review/08/templates/index.gohtml b/000_temp/46_sp17/52-review/08/templates/index.gohtml new file mode 100644 index 00000000..386fb0fc --- /dev/null +++ b/000_temp/46_sp17/52-review/08/templates/index.gohtml @@ -0,0 +1,117 @@ + + + + + Title + + + + +
+

{{.}}

+
+ + + + \ No newline at end of file diff --git a/000_temp/46_sp17/52-review/09/app.yaml b/000_temp/46_sp17/52-review/09/app.yaml new file mode 100644 index 00000000..6816437c --- /dev/null +++ b/000_temp/46_sp17/52-review/09/app.yaml @@ -0,0 +1,2 @@ +runtime: go +env: flex \ No newline at end of file diff --git a/000_temp/46_sp17/52-review/09/main.go b/000_temp/46_sp17/52-review/09/main.go new file mode 100644 index 00000000..1c692706 --- /dev/null +++ b/000_temp/46_sp17/52-review/09/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("public")))) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + s := "Paradise Found" + tpl.ExecuteTemplate(w, "index.gohtml", s) +} diff --git a/000_temp/46_sp17/52-review/09/public/css/index.css b/000_temp/46_sp17/52-review/09/public/css/index.css new file mode 100644 index 00000000..e51c29b4 --- /dev/null +++ b/000_temp/46_sp17/52-review/09/public/css/index.css @@ -0,0 +1,24 @@ +html, body, h1 { + padding: 0; + border: 0; + margin: 0; + box-sizing: border-box; +} + +main { + display: flex; + flex-direction: column; + flex-wrap: nowrap; + justify-content: center; + align-items: center; + background-image: url("http://github.com/assets/img/surf.png"); + background-size: cover; + background-repeat: no-repeat; + background-position: center; + height: 100vh; +} + +h1 { + font-size: 8rem; + color: white; +} \ No newline at end of file diff --git a/000_temp/46_sp17/52-review/09/public/img/surf.png b/000_temp/46_sp17/52-review/09/public/img/surf.png new file mode 100644 index 00000000..1636912e Binary files /dev/null and b/000_temp/46_sp17/52-review/09/public/img/surf.png differ diff --git a/000_temp/46_sp17/52-review/09/templates/index.gohtml b/000_temp/46_sp17/52-review/09/templates/index.gohtml new file mode 100644 index 00000000..386fb0fc --- /dev/null +++ b/000_temp/46_sp17/52-review/09/templates/index.gohtml @@ -0,0 +1,117 @@ + + + + + Title + + + + +
+

{{.}}

+
+ + + + \ No newline at end of file diff --git a/000_temp/47_ajax/01/main.go b/000_temp/47_ajax/01/main.go new file mode 100644 index 00000000..3c40f998 --- /dev/null +++ b/000_temp/47_ajax/01/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/process", process) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func process(w http.ResponseWriter, r *http.Request) { + + subscribe := r.FormValue("subscribe") + dessert := r.FormValue("dessert") + dow := r.FormValue("dow") + fmt.Println("RESULTS:", subscribe, " - ", dessert, " - ", dow) +} diff --git a/000_temp/47_ajax/01/templates/index.gohtml b/000_temp/47_ajax/01/templates/index.gohtml new file mode 100644 index 00000000..c3080850 --- /dev/null +++ b/000_temp/47_ajax/01/templates/index.gohtml @@ -0,0 +1,55 @@ + + + + + Document + + + +
+ + + + + + + + + + + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/000_temp/48_gmail/main.go b/000_temp/48_gmail/main.go new file mode 100644 index 00000000..79058077 --- /dev/null +++ b/000_temp/48_gmail/main.go @@ -0,0 +1,5 @@ +package main + +func main() { + +} diff --git a/000_temp/49_interfaces/main.go b/000_temp/49_interfaces/main.go new file mode 100644 index 00000000..4fd7d004 --- /dev/null +++ b/000_temp/49_interfaces/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "fmt" + "github.com/GoesToEleven/golang-web-dev/000_temp/49_interfaces/species" + _ "github.com/GoesToEleven/golang-web-dev/000_temp/49_interfaces/species" +) + +type person struct { + first string +} + +func (person) Speak() { + fmt.Println("I'm a person") +} + +type secretAgent struct { + person + ltk bool +} + +func (secretAgent) Speak() { + fmt.Println("I'm a person and a secret agent") +} + +func foo(h species.Human) { + h.Speak() +} + +func main() { + p1 := person{ + first: "Miss Moneypenny", + } + + p2 := secretAgent{ + person{ + "James", + }, + true, + } + + foo(p1) + foo(p2) +} diff --git a/000_temp/49_interfaces/species/species.go b/000_temp/49_interfaces/species/species.go new file mode 100644 index 00000000..c54fe271 --- /dev/null +++ b/000_temp/49_interfaces/species/species.go @@ -0,0 +1,5 @@ +package species + +type Human interface { + Speak() +} diff --git a/000_temp/50_disney/01/main.go b/000_temp/50_disney/01/main.go new file mode 100644 index 00000000..f1f3f7e2 --- /dev/null +++ b/000_temp/50_disney/01/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", foo) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "Hellooooo!") +} diff --git a/000_temp/50_disney/02/main.go b/000_temp/50_disney/02/main.go new file mode 100644 index 00000000..d3b764c7 --- /dev/null +++ b/000_temp/50_disney/02/main.go @@ -0,0 +1,54 @@ +package main + +import ( + "encoding/json" + "fmt" + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.HandleFunc("/js", js) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} + +func js(w http.ResponseWriter, r *http.Request) { + nj := struct { + First string `json:"first-name"` + Last string `json:"last-name"` + }{ + "James", + "Bond", + } + + w.Header().Set("Content-Type", "application/json") + + err := json.NewEncoder(w).Encode(nj) + if err != nil { + fmt.Println(err) + return + } + //bs, err := json.Marshal(nj) + //if err != nil { + // fmt.Println(err) + // return + //} + //s := string(bs) + //tpl.ExecuteTemplate(w, "js.gohtml", s) +} diff --git a/000_temp/50_disney/02/templates/about.gohtml b/000_temp/50_disney/02/templates/about.gohtml new file mode 100644 index 00000000..e7bc7333 --- /dev/null +++ b/000_temp/50_disney/02/templates/about.gohtml @@ -0,0 +1,14 @@ + + + + + + About + + + +

All about Disney!

+ + + \ No newline at end of file diff --git a/000_temp/50_disney/02/templates/index.gohtml b/000_temp/50_disney/02/templates/index.gohtml new file mode 100644 index 00000000..edf0ff57 --- /dev/null +++ b/000_temp/50_disney/02/templates/index.gohtml @@ -0,0 +1,14 @@ + + + + + + Index + + + +

Hello Disney!

+ + + \ No newline at end of file diff --git a/000_temp/50_disney/02/templates/js.gohtml b/000_temp/50_disney/02/templates/js.gohtml new file mode 100644 index 00000000..41087b11 --- /dev/null +++ b/000_temp/50_disney/02/templates/js.gohtml @@ -0,0 +1,14 @@ + + + + + + About + + + +

{{.}}

+ + + \ No newline at end of file diff --git a/000_temp/50_disney/03/main.go b/000_temp/50_disney/03/main.go new file mode 100644 index 00000000..48f9645f --- /dev/null +++ b/000_temp/50_disney/03/main.go @@ -0,0 +1,13 @@ +package main + +import "fmt" + +var x int = 42 + +func init() { + fmt.Println("in init ", x) +} + +func main() { + fmt.Println("in main ", x) +} diff --git a/000_temp/50_disney/04/main.go b/000_temp/50_disney/04/main.go new file mode 100644 index 00000000..131d5fa6 --- /dev/null +++ b/000_temp/50_disney/04/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.HandleFunc("/dog", dog) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} + +func dog(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "public/img/toby.jpg") +} diff --git a/000_temp/50_disney/04/public/img/toby.jpg b/000_temp/50_disney/04/public/img/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/50_disney/04/public/img/toby.jpg differ diff --git a/000_temp/50_disney/04/templates/about.gohtml b/000_temp/50_disney/04/templates/about.gohtml new file mode 100644 index 00000000..e7bc7333 --- /dev/null +++ b/000_temp/50_disney/04/templates/about.gohtml @@ -0,0 +1,14 @@ + + + + + + About + + + +

All about Disney!

+ + + \ No newline at end of file diff --git a/000_temp/50_disney/04/templates/index.gohtml b/000_temp/50_disney/04/templates/index.gohtml new file mode 100644 index 00000000..eb1df9ba --- /dev/null +++ b/000_temp/50_disney/04/templates/index.gohtml @@ -0,0 +1,15 @@ + + + + + + Index + + + +

Hello Disney!

+ + + + \ No newline at end of file diff --git a/000_temp/50_disney/04/templates/js.gohtml b/000_temp/50_disney/04/templates/js.gohtml new file mode 100644 index 00000000..41087b11 --- /dev/null +++ b/000_temp/50_disney/04/templates/js.gohtml @@ -0,0 +1,14 @@ + + + + + + About + + + +

{{.}}

+ + + \ No newline at end of file diff --git a/000_temp/50_disney/05_to-illustrate-not-working/main.go b/000_temp/50_disney/05_to-illustrate-not-working/main.go new file mode 100644 index 00000000..749ae79d --- /dev/null +++ b/000_temp/50_disney/05_to-illustrate-not-working/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.HandleFunc("/dog", dog) + http.Handle("/public/", http.FileServer(http.Dir("./public"))) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} + +func dog(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "public/img/toby.jpg") +} diff --git a/000_temp/50_disney/05_to-illustrate-not-working/public/img/toby.jpg b/000_temp/50_disney/05_to-illustrate-not-working/public/img/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/50_disney/05_to-illustrate-not-working/public/img/toby.jpg differ diff --git a/000_temp/50_disney/05_to-illustrate-not-working/templates/about.gohtml b/000_temp/50_disney/05_to-illustrate-not-working/templates/about.gohtml new file mode 100644 index 00000000..e7bc7333 --- /dev/null +++ b/000_temp/50_disney/05_to-illustrate-not-working/templates/about.gohtml @@ -0,0 +1,14 @@ + + + + + + About + + + +

All about Disney!

+ + + \ No newline at end of file diff --git a/000_temp/50_disney/05_to-illustrate-not-working/templates/index.gohtml b/000_temp/50_disney/05_to-illustrate-not-working/templates/index.gohtml new file mode 100644 index 00000000..3a62d64b --- /dev/null +++ b/000_temp/50_disney/05_to-illustrate-not-working/templates/index.gohtml @@ -0,0 +1,15 @@ + + + + + + Index + + + +

Hello Disney!

+ + + + \ No newline at end of file diff --git a/000_temp/50_disney/05_to-illustrate-not-working/templates/js.gohtml b/000_temp/50_disney/05_to-illustrate-not-working/templates/js.gohtml new file mode 100644 index 00000000..41087b11 --- /dev/null +++ b/000_temp/50_disney/05_to-illustrate-not-working/templates/js.gohtml @@ -0,0 +1,14 @@ + + + + + + About + + + +

{{.}}

+ + + \ No newline at end of file diff --git a/000_temp/50_disney/06/main.go b/000_temp/50_disney/06/main.go new file mode 100644 index 00000000..8361c048 --- /dev/null +++ b/000_temp/50_disney/06/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.HandleFunc("/dog", dog) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./public")))) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} + +func dog(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "public/img/toby.jpg") +} diff --git a/000_temp/50_disney/06/public/img/toby.jpg b/000_temp/50_disney/06/public/img/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/50_disney/06/public/img/toby.jpg differ diff --git a/000_temp/50_disney/06/templates/about.gohtml b/000_temp/50_disney/06/templates/about.gohtml new file mode 100644 index 00000000..e7bc7333 --- /dev/null +++ b/000_temp/50_disney/06/templates/about.gohtml @@ -0,0 +1,14 @@ + + + + + + About + + + +

All about Disney!

+ + + \ No newline at end of file diff --git a/000_temp/50_disney/06/templates/index.gohtml b/000_temp/50_disney/06/templates/index.gohtml new file mode 100644 index 00000000..7b9a9951 --- /dev/null +++ b/000_temp/50_disney/06/templates/index.gohtml @@ -0,0 +1,15 @@ + + + + + + Index + + + +

Hello Disney!

+ + + + \ No newline at end of file diff --git a/000_temp/50_disney/06/templates/js.gohtml b/000_temp/50_disney/06/templates/js.gohtml new file mode 100644 index 00000000..41087b11 --- /dev/null +++ b/000_temp/50_disney/06/templates/js.gohtml @@ -0,0 +1,14 @@ + + + + + + About + + + +

{{.}}

+ + + \ No newline at end of file diff --git a/000_temp/50_disney/07/main.go b/000_temp/50_disney/07/main.go new file mode 100644 index 00000000..8361c048 --- /dev/null +++ b/000_temp/50_disney/07/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.HandleFunc("/dog", dog) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./public")))) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} + +func dog(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "public/img/toby.jpg") +} diff --git a/000_temp/50_disney/07/public/css/index.css b/000_temp/50_disney/07/public/css/index.css new file mode 100644 index 00000000..f12e4201 --- /dev/null +++ b/000_temp/50_disney/07/public/css/index.css @@ -0,0 +1,4 @@ + +h1 { + color: red; +} \ No newline at end of file diff --git a/000_temp/50_disney/07/public/img/toby.jpg b/000_temp/50_disney/07/public/img/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/50_disney/07/public/img/toby.jpg differ diff --git a/000_temp/50_disney/07/templates/about.gohtml b/000_temp/50_disney/07/templates/about.gohtml new file mode 100644 index 00000000..e7bc7333 --- /dev/null +++ b/000_temp/50_disney/07/templates/about.gohtml @@ -0,0 +1,14 @@ + + + + + + About + + + +

All about Disney!

+ + + \ No newline at end of file diff --git a/000_temp/50_disney/07/templates/index.gohtml b/000_temp/50_disney/07/templates/index.gohtml new file mode 100644 index 00000000..5d448c0b --- /dev/null +++ b/000_temp/50_disney/07/templates/index.gohtml @@ -0,0 +1,16 @@ + + + + + + Index + + + + +

Hello Disney!

+ + + + \ No newline at end of file diff --git a/000_temp/50_disney/07/templates/js.gohtml b/000_temp/50_disney/07/templates/js.gohtml new file mode 100644 index 00000000..41087b11 --- /dev/null +++ b/000_temp/50_disney/07/templates/js.gohtml @@ -0,0 +1,14 @@ + + + + + + About + + + +

{{.}}

+ + + \ No newline at end of file diff --git a/000_temp/50_disney/08/main.go b/000_temp/50_disney/08/main.go new file mode 100644 index 00000000..8361c048 --- /dev/null +++ b/000_temp/50_disney/08/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.HandleFunc("/dog", dog) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./public")))) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} + +func dog(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "public/img/toby.jpg") +} diff --git a/000_temp/50_disney/08/public/css/index.css b/000_temp/50_disney/08/public/css/index.css new file mode 100644 index 00000000..9c412bd7 --- /dev/null +++ b/000_temp/50_disney/08/public/css/index.css @@ -0,0 +1,25 @@ +html, body, h1 { + padding: 0; + border: 0; + margin: 0; + box-sizing: border-box; +} + +h1 { + color: blue; +} + +main { + height: 100vh; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: center; + align-items: center; + font-size: 5vw; + background-image: url("http://github.com/assets/img/neu.jpg"); + background-size: cover; + background-attachment: fixed; + background-repeat: no-repeat; + background-position: center; +} \ No newline at end of file diff --git a/000_temp/50_disney/08/public/img/neu.jpg b/000_temp/50_disney/08/public/img/neu.jpg new file mode 100644 index 00000000..cc2a09cd Binary files /dev/null and b/000_temp/50_disney/08/public/img/neu.jpg differ diff --git a/000_temp/50_disney/08/templates/about.gohtml b/000_temp/50_disney/08/templates/about.gohtml new file mode 100644 index 00000000..e7bc7333 --- /dev/null +++ b/000_temp/50_disney/08/templates/about.gohtml @@ -0,0 +1,14 @@ + + + + + + About + + + +

All about Disney!

+ + + \ No newline at end of file diff --git a/000_temp/50_disney/08/templates/index.gohtml b/000_temp/50_disney/08/templates/index.gohtml new file mode 100644 index 00000000..1b274b04 --- /dev/null +++ b/000_temp/50_disney/08/templates/index.gohtml @@ -0,0 +1,220 @@ + + + + + + Index + + + + +
+

Hello From Disney!

+
+ + + + + \ No newline at end of file diff --git a/000_temp/50_disney/08/templates/js.gohtml b/000_temp/50_disney/08/templates/js.gohtml new file mode 100644 index 00000000..41087b11 --- /dev/null +++ b/000_temp/50_disney/08/templates/js.gohtml @@ -0,0 +1,14 @@ + + + + + + About + + + +

{{.}}

+ + + \ No newline at end of file diff --git a/000_temp/51_bcrypt/main.go b/000_temp/51_bcrypt/main.go new file mode 100644 index 00000000..c417ff68 --- /dev/null +++ b/000_temp/51_bcrypt/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "fmt" + "golang.org/x/crypto/bcrypt" +) + +func main() { + s := `password123` + bs, err := bcrypt.GenerateFromPassword([]byte(s), bcrypt.MinCost) + if err != nil { + fmt.Println(err) + } + fmt.Println(s) + fmt.Println(bs) + + loginPword1 := `password1234` + + err = bcrypt.CompareHashAndPassword(bs, []byte(loginPword1)) + if err != nil { + fmt.Println("YOU CAN'T LOGIN") + return + } + + fmt.Println("You're logged in") +} diff --git a/000_temp/52-race-condition/01/main.go b/000_temp/52-race-condition/01/main.go new file mode 100644 index 00000000..3b3bc863 --- /dev/null +++ b/000_temp/52-race-condition/01/main.go @@ -0,0 +1,33 @@ +package _1 + +import ( + "fmt" + "runtime" + "sync" +) + +var counter = 0 +var mu sync.Mutex + +func main() { + + const gs = 4 + var wg sync.WaitGroup + wg.Add(gs) + + for i := 0; i < gs; i++ { + go func() { + mu.Lock() + v := counter + // time.Sleep(time.Second * 2) + runtime.Gosched() // tells runtime to yield processor to other goroutine + v++ + counter = v + mu.Unlock() + wg.Done() + }() + } + wg.Wait() + + fmt.Println(counter) +} diff --git a/000_temp/52-race-condition/02/main.go b/000_temp/52-race-condition/02/main.go new file mode 100644 index 00000000..75458660 --- /dev/null +++ b/000_temp/52-race-condition/02/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "fmt" + "runtime" + "sync" +) + +var wg sync.WaitGroup +var counter int + +func main() { + fmt.Println(runtime.NumCPU()) + + const gs = 100 + wg.Add(gs) + + for i := 0; i < gs; i++ { + go func() { + v := counter + // time.Sleep(time.Second) + runtime.Gosched() + v++ + counter = v + wg.Done() + }() + fmt.Println(runtime.NumGoroutine()) + fmt.Println(runtime.NumCPU()) + } + fmt.Println(runtime.NumGoroutine()) + wg.Wait() + fmt.Println(counter) +} diff --git a/000_temp/52-race-condition/03_race/main.go b/000_temp/52-race-condition/03_race/main.go new file mode 100644 index 00000000..991a46a6 --- /dev/null +++ b/000_temp/52-race-condition/03_race/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "fmt" + "runtime" + "sync" +) + +func main() { + fmt.Println("CPUs:", runtime.NumCPU()) + fmt.Println("Goroutines:", runtime.NumGoroutine()) + + counter := 0 + + const gs = 100 + var wg sync.WaitGroup + wg.Add(gs) + + for i := 0; i < gs; i++ { + go func() { + v := counter + // time.Sleep(time.Second) + runtime.Gosched() + v++ + counter = v + wg.Done() + }() + fmt.Println("Goroutines:", runtime.NumGoroutine()) + } + wg.Wait() + fmt.Println("Goroutines:", runtime.NumGoroutine()) + fmt.Println("count:", counter) +} diff --git a/000_temp/52-race-condition/04_mutex/main.go b/000_temp/52-race-condition/04_mutex/main.go new file mode 100644 index 00000000..27f64acc --- /dev/null +++ b/000_temp/52-race-condition/04_mutex/main.go @@ -0,0 +1,37 @@ +package main + +import ( + "fmt" + "runtime" + "sync" +) + +func main() { + fmt.Println("CPUs:", runtime.NumCPU()) + fmt.Println("Goroutines:", runtime.NumGoroutine()) + + counter := 0 + + const gs = 100 + var wg sync.WaitGroup + wg.Add(gs) + + var mu sync.Mutex + + for i := 0; i < gs; i++ { + go func() { + mu.Lock() + v := counter + // time.Sleep(time.Second) + runtime.Gosched() + v++ + counter = v + mu.Unlock() + wg.Done() + }() + fmt.Println("Goroutines:", runtime.NumGoroutine()) + } + wg.Wait() + fmt.Println("Goroutines:", runtime.NumGoroutine()) + fmt.Println("count:", counter) +} diff --git a/000_temp/52-race-condition/05_atomic/main.go b/000_temp/52-race-condition/05_atomic/main.go new file mode 100644 index 00000000..77c01daf --- /dev/null +++ b/000_temp/52-race-condition/05_atomic/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "fmt" + "runtime" + "sync" + "sync/atomic" +) + +func main() { + fmt.Println("CPUs:", runtime.NumCPU()) + fmt.Println("Goroutines:", runtime.NumGoroutine()) + + var counter int64 + + const gs = 100 + var wg sync.WaitGroup + wg.Add(gs) + + for i := 0; i < gs; i++ { + go func() { + atomic.AddInt64(&counter, 1) + runtime.Gosched() + fmt.Println("Counter\t", atomic.LoadInt64(&counter)) + wg.Done() + }() + fmt.Println("Goroutines:", runtime.NumGoroutine()) + } + wg.Wait() + fmt.Println("Goroutines:", runtime.NumGoroutine()) + fmt.Println("count:", counter) +} diff --git a/000_temp/52-race-condition/06_chan-pre-lecture/main.go b/000_temp/52-race-condition/06_chan-pre-lecture/main.go new file mode 100644 index 00000000..e3083e04 --- /dev/null +++ b/000_temp/52-race-condition/06_chan-pre-lecture/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "fmt" + "runtime" + "sync" +) + +func main() { + counter := 0 + + c := make(chan int) + + const gs = 100 + var wg sync.WaitGroup + wg.Add(gs) + + go func() { + counter += <-c + fmt.Println("counter:\t", counter) + }() + + for i := 0; i < gs; i++ { + go func() { + c <- 1 + wg.Done() + }() + fmt.Println("Goroutines:", runtime.NumGoroutine()) + } + wg.Wait() + close(c) + fmt.Println("total count:", counter) +} diff --git a/000_temp/53-hello-world/main.go b/000_temp/53-hello-world/main.go new file mode 100644 index 00000000..68b2a816 --- /dev/null +++ b/000_temp/53-hello-world/main.go @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main() { + fmt.Println("Hello WORLD") +} diff --git a/000_temp/53_chan/main.go b/000_temp/53_chan/main.go new file mode 100644 index 00000000..e0372a36 --- /dev/null +++ b/000_temp/53_chan/main.go @@ -0,0 +1,31 @@ +package main + +import "fmt" + +func foo(f, b chan int) { + for i := 0; i < 10000; i++ { + select { + case v := <-f: + fmt.Println("from foo:", v) + case v := <-b: + fmt.Println("from bar:", v) + } + } + fmt.Println("about to exit") +} + +func main() { + f := make(chan int) + b := make(chan int) + go func() { + for i := 0; i < 5000; i++ { + f <- i + } + }() + go func() { + for i := 0; i < 5000; i++ { + b <- i + } + }() + foo(f, b) +} diff --git a/000_temp/54-paradise-html-css/01_html-css/index.html b/000_temp/54-paradise-html-css/01_html-css/index.html new file mode 100644 index 00000000..f68b77f0 --- /dev/null +++ b/000_temp/54-paradise-html-css/01_html-css/index.html @@ -0,0 +1,227 @@ + + + + + Title + + + + +
+
Company Logo
+
+ About + Contact + Sales +
+
+ +
+

PARADISE

+
+ + + + + \ No newline at end of file diff --git a/000_temp/54-paradise-html-css/01_html-css/main.css b/000_temp/54-paradise-html-css/01_html-css/main.css new file mode 100644 index 00000000..35b0ccc9 --- /dev/null +++ b/000_temp/54-paradise-html-css/01_html-css/main.css @@ -0,0 +1,55 @@ +html, body, header, main, h1, div { + border: 0; + padding: 0; + margin: 0; +} + + +header { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 6vh; + border-bottom: 1px solid gray; + display: flex; + justify-content: space-between; + align-items: center; + background-color: rgba(21, 85, 138, 0.25); +} + +header > div { + /*border: 2px solid orange;*/ + height: 100%; + display: flex; + justify-content: center; + align-items: center; + font-size: 2.5rem; + color: white; + padding: 0 2rem; +} + +header > div > span { + padding: 0 2rem; +} + +header > div > span:hover { + color: blue; +} + +main { + height: 100vh; + display: flex; + justify-content: center; + align-items: center; + background-image: url(http://github.com/paradise.jpeg); + background-position: center; + background-repeat: no-repeat; + background-attachment: fixed; + background-size: cover; +} + +h1 { + color: white; + font-size: 12vw; +} \ No newline at end of file diff --git a/000_temp/54-paradise-html-css/01_html-css/main.go b/000_temp/54-paradise-html-css/01_html-css/main.go new file mode 100644 index 00000000..b05a38b6 --- /dev/null +++ b/000_temp/54-paradise-html-css/01_html-css/main.go @@ -0,0 +1 @@ +package _1_html_cs diff --git a/000_temp/55-website/files/css/index.css b/000_temp/55-website/files/css/index.css new file mode 100644 index 00000000..724561ab --- /dev/null +++ b/000_temp/55-website/files/css/index.css @@ -0,0 +1,15 @@ +main { + height: 100vh; + display: flex; + justify-content: center; + align-items: center; + background-image: url("http://github.com/imgs/paradise.jpeg"); + background-size: cover; + background-repeat: no-repeat; + background-position: center; +} + +h1 { + font-size: 8rem; + color: white; +} \ No newline at end of file diff --git a/000_temp/55-website/files/css/reset.css b/000_temp/55-website/files/css/reset.css new file mode 100644 index 00000000..f4670548 --- /dev/null +++ b/000_temp/55-website/files/css/reset.css @@ -0,0 +1,61 @@ +html, body, div, span, h1, h2, h3, h4, h5, h6, button, p, blockquote, pre, a, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strong, sub, sup, b, u, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, figure, figcaption, footer, header, nav, output, section, time, mark, audio, video, input, textarea, select { + margin: 0; + padding: 0; + border: 0; + /* inherits the browser's font properties: font-size 16px */ + font: inherit; + /* specifies the vertical alignment of an inline element */ + vertical-align: baseline; + + box-sizing: border-box; + + /* specifies the height of line boxes within the element. */ + line-height: 1; + + border-radius: 0; + + /* no outline around anything */ + outline: none; + + /* inherit the color value of the parent */ + color: inherit; +} + +ol, ul { + /* no bullets in lists */ + list-style: none; +} + +a { + /* no underline */ + text-decoration: none; +} + +button { + cursor: pointer; + background-color: transparent; +} + +blockquote, q { + /* no quotes */ + quotes: none; +} + +table { + /* no spacing between cells*/ + border-spacing: 0; + /*borders are collapsed - adjacent table cells share borders */ + border-collapse: collapse; +} + +input, select, progress{ + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + +svg { + width: 1.9em; + height: 1.9em; + fill: currentColor; +} \ No newline at end of file diff --git a/000_temp/55-website/files/imgs/paradise.jpeg b/000_temp/55-website/files/imgs/paradise.jpeg new file mode 100644 index 00000000..8e2b075a Binary files /dev/null and b/000_temp/55-website/files/imgs/paradise.jpeg differ diff --git a/000_temp/55-website/main.go b/000_temp/55-website/main.go new file mode 100644 index 00000000..51e61ade --- /dev/null +++ b/000_temp/55-website/main.go @@ -0,0 +1,17 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + loadRoutes() + http.ListenAndServe(":8080", nil) +} diff --git a/000_temp/55-website/rAbout.go b/000_temp/55-website/rAbout.go new file mode 100644 index 00000000..12e1a845 --- /dev/null +++ b/000_temp/55-website/rAbout.go @@ -0,0 +1,13 @@ +package main + +import ( + "log" + "net/http" +) + +func about(w http.ResponseWriter, r *http.Request) { + err := tpl.ExecuteTemplate(w, "about.gohtml", nil) + if err != nil { + log.Println(err) + } +} diff --git a/000_temp/55-website/rIndex.go b/000_temp/55-website/rIndex.go new file mode 100644 index 00000000..fbf9401c --- /dev/null +++ b/000_temp/55-website/rIndex.go @@ -0,0 +1,13 @@ +package main + +import ( + "log" + "net/http" +) + +func index(w http.ResponseWriter, r *http.Request) { + err := tpl.ExecuteTemplate(w, "index.gohtml", nil) + if err != nil { + log.Println(err) + } +} diff --git a/000_temp/55-website/routes.go b/000_temp/55-website/routes.go new file mode 100644 index 00000000..fa2bc17a --- /dev/null +++ b/000_temp/55-website/routes.go @@ -0,0 +1,9 @@ +package main + +import "net/http" + +func loadRoutes() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./files")))) +} diff --git a/000_temp/55-website/templates/about.gohtml b/000_temp/55-website/templates/about.gohtml new file mode 100644 index 00000000..36065e4a --- /dev/null +++ b/000_temp/55-website/templates/about.gohtml @@ -0,0 +1,14 @@ + + + + + + + Document + + + +

About

+ + \ No newline at end of file diff --git a/000_temp/55-website/templates/index.gohtml b/000_temp/55-website/templates/index.gohtml new file mode 100644 index 00000000..a4698a8a --- /dev/null +++ b/000_temp/55-website/templates/index.gohtml @@ -0,0 +1,19 @@ + + + + + + + Document + + + + + +
+

PARADISE

+
+ + + \ No newline at end of file diff --git a/000_temp/56_SVCC-17/01a/main.go b/000_temp/56_SVCC-17/01a/main.go new file mode 100644 index 00000000..4900f12c --- /dev/null +++ b/000_temp/56_SVCC-17/01a/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", foo) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "Hello world") +} diff --git a/000_temp/56_SVCC-17/01b/main.go b/000_temp/56_SVCC-17/01b/main.go new file mode 100644 index 00000000..279761d5 --- /dev/null +++ b/000_temp/56_SVCC-17/01b/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", foo) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "hello world") +} diff --git a/000_temp/56_SVCC-17/01c/main.go b/000_temp/56_SVCC-17/01c/main.go new file mode 100644 index 00000000..c48636a0 --- /dev/null +++ b/000_temp/56_SVCC-17/01c/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "Hello SVCC from Paypal") +} diff --git a/000_temp/56_SVCC-17/01d/main.go b/000_temp/56_SVCC-17/01d/main.go new file mode 100644 index 00000000..68f251c9 --- /dev/null +++ b/000_temp/56_SVCC-17/01d/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "Hello GDG Fresno") +} diff --git a/000_temp/56_SVCC-17/02a/main.go b/000_temp/56_SVCC-17/02a/main.go new file mode 100644 index 00000000..ffcebebe --- /dev/null +++ b/000_temp/56_SVCC-17/02a/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", foo) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} diff --git a/000_temp/56_SVCC-17/02a/templates/index.gohtml b/000_temp/56_SVCC-17/02a/templates/index.gohtml new file mode 100644 index 00000000..a905aa5b --- /dev/null +++ b/000_temp/56_SVCC-17/02a/templates/index.gohtml @@ -0,0 +1,12 @@ + + + + + Document + + + +

Hello world

+ + + \ No newline at end of file diff --git a/000_temp/56_SVCC-17/02b/main.go b/000_temp/56_SVCC-17/02b/main.go new file mode 100644 index 00000000..ffcebebe --- /dev/null +++ b/000_temp/56_SVCC-17/02b/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", foo) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} diff --git a/000_temp/56_SVCC-17/02b/templates/index.gohtml b/000_temp/56_SVCC-17/02b/templates/index.gohtml new file mode 100644 index 00000000..f86b947c --- /dev/null +++ b/000_temp/56_SVCC-17/02b/templates/index.gohtml @@ -0,0 +1,12 @@ + + + + + Document + + + +

HELLO FROM PAYPAL IN CALIFORNIA

+ + + \ No newline at end of file diff --git a/000_temp/56_SVCC-17/02c/main.go b/000_temp/56_SVCC-17/02c/main.go new file mode 100644 index 00000000..3c978b33 --- /dev/null +++ b/000_temp/56_SVCC-17/02c/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} diff --git a/000_temp/56_SVCC-17/02c/templates/index.gohtml b/000_temp/56_SVCC-17/02c/templates/index.gohtml new file mode 100644 index 00000000..30bdf087 --- /dev/null +++ b/000_temp/56_SVCC-17/02c/templates/index.gohtml @@ -0,0 +1,12 @@ + + + + + Document + + + +

HELLO FROM SVCC 2017 WOOHOOO!!!

+ + + \ No newline at end of file diff --git a/000_temp/56_SVCC-17/02d/main.go b/000_temp/56_SVCC-17/02d/main.go new file mode 100644 index 00000000..21ff5e92 --- /dev/null +++ b/000_temp/56_SVCC-17/02d/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} diff --git a/000_temp/56_SVCC-17/02d/templates/index.gohtml b/000_temp/56_SVCC-17/02d/templates/index.gohtml new file mode 100644 index 00000000..8e1962ae --- /dev/null +++ b/000_temp/56_SVCC-17/02d/templates/index.gohtml @@ -0,0 +1,15 @@ + + + + + + + Document + + + +

HELLO FRESNO GDG

+ + + \ No newline at end of file diff --git a/000_temp/56_SVCC-17/03a/main.go b/000_temp/56_SVCC-17/03a/main.go new file mode 100644 index 00000000..ffcebebe --- /dev/null +++ b/000_temp/56_SVCC-17/03a/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", foo) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} diff --git a/000_temp/56_SVCC-17/03a/templates/incl-footer.gohtml b/000_temp/56_SVCC-17/03a/templates/incl-footer.gohtml new file mode 100644 index 00000000..37bdaade --- /dev/null +++ b/000_temp/56_SVCC-17/03a/templates/incl-footer.gohtml @@ -0,0 +1,4 @@ +{{define "footer"}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/03a/templates/incl-header.gohtml b/000_temp/56_SVCC-17/03a/templates/incl-header.gohtml new file mode 100644 index 00000000..66c6b210 --- /dev/null +++ b/000_temp/56_SVCC-17/03a/templates/incl-header.gohtml @@ -0,0 +1,9 @@ +{{define "header"}} + + + + + GOODNESS + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/03a/templates/index.gohtml b/000_temp/56_SVCC-17/03a/templates/index.gohtml new file mode 100644 index 00000000..febe83e7 --- /dev/null +++ b/000_temp/56_SVCC-17/03a/templates/index.gohtml @@ -0,0 +1,5 @@ +{{template "header"}} + +

Hello world

+ +{{template "footer"}} diff --git a/000_temp/56_SVCC-17/03b/main.go b/000_temp/56_SVCC-17/03b/main.go new file mode 100644 index 00000000..ffcebebe --- /dev/null +++ b/000_temp/56_SVCC-17/03b/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", foo) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} diff --git a/000_temp/56_SVCC-17/03b/templates/incl-footer.gohtml b/000_temp/56_SVCC-17/03b/templates/incl-footer.gohtml new file mode 100644 index 00000000..37bdaade --- /dev/null +++ b/000_temp/56_SVCC-17/03b/templates/incl-footer.gohtml @@ -0,0 +1,4 @@ +{{define "footer"}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/03b/templates/incl-header.gohtml b/000_temp/56_SVCC-17/03b/templates/incl-header.gohtml new file mode 100644 index 00000000..66c6b210 --- /dev/null +++ b/000_temp/56_SVCC-17/03b/templates/incl-header.gohtml @@ -0,0 +1,9 @@ +{{define "header"}} + + + + + GOODNESS + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/03b/templates/index.gohtml b/000_temp/56_SVCC-17/03b/templates/index.gohtml new file mode 100644 index 00000000..a060f207 --- /dev/null +++ b/000_temp/56_SVCC-17/03b/templates/index.gohtml @@ -0,0 +1,4 @@ + +{{template "header"}} +

HELLO FROM PAYPAL IN CALIFORNIA

+{{template "footer"}} diff --git a/000_temp/56_SVCC-17/03c/main.go b/000_temp/56_SVCC-17/03c/main.go new file mode 100644 index 00000000..3c978b33 --- /dev/null +++ b/000_temp/56_SVCC-17/03c/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} diff --git a/000_temp/56_SVCC-17/03c/templates/incl-footer.gohtml b/000_temp/56_SVCC-17/03c/templates/incl-footer.gohtml new file mode 100644 index 00000000..37bdaade --- /dev/null +++ b/000_temp/56_SVCC-17/03c/templates/incl-footer.gohtml @@ -0,0 +1,4 @@ +{{define "footer"}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/03c/templates/incl-header.gohtml b/000_temp/56_SVCC-17/03c/templates/incl-header.gohtml new file mode 100644 index 00000000..e3ce1c54 --- /dev/null +++ b/000_temp/56_SVCC-17/03c/templates/incl-header.gohtml @@ -0,0 +1,7 @@ +{{define "header"}} + + + + + Document +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/03c/templates/index.gohtml b/000_temp/56_SVCC-17/03c/templates/index.gohtml new file mode 100644 index 00000000..43777d3f --- /dev/null +++ b/000_temp/56_SVCC-17/03c/templates/index.gohtml @@ -0,0 +1,7 @@ +{{template "header"}} + + + +

HELLO FROM SVCC 2017 WOOHOOO!!!

+ +{{template "footer"}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/03d/main.go b/000_temp/56_SVCC-17/03d/main.go new file mode 100644 index 00000000..21ff5e92 --- /dev/null +++ b/000_temp/56_SVCC-17/03d/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} diff --git a/000_temp/56_SVCC-17/03d/templates/inc-footer.gohtml b/000_temp/56_SVCC-17/03d/templates/inc-footer.gohtml new file mode 100644 index 00000000..37bdaade --- /dev/null +++ b/000_temp/56_SVCC-17/03d/templates/inc-footer.gohtml @@ -0,0 +1,4 @@ +{{define "footer"}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/03d/templates/inc-header.gohtml b/000_temp/56_SVCC-17/03d/templates/inc-header.gohtml new file mode 100644 index 00000000..757bd31c --- /dev/null +++ b/000_temp/56_SVCC-17/03d/templates/inc-header.gohtml @@ -0,0 +1,9 @@ +{{define "header"}} + + + + + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/03d/templates/index.gohtml b/000_temp/56_SVCC-17/03d/templates/index.gohtml new file mode 100644 index 00000000..412ba59a --- /dev/null +++ b/000_temp/56_SVCC-17/03d/templates/index.gohtml @@ -0,0 +1,8 @@ +{{template "header"}} + Document + + + +

HELLO FRESNO GDG

+ +{{template "footer"}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/04a/main.go b/000_temp/56_SVCC-17/04a/main.go new file mode 100644 index 00000000..d24c8f45 --- /dev/null +++ b/000_temp/56_SVCC-17/04a/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", "ACME, INC") +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", "OUR TEAM") +} diff --git a/000_temp/56_SVCC-17/04a/templates/about.gohtml b/000_temp/56_SVCC-17/04a/templates/about.gohtml new file mode 100644 index 00000000..4b76c606 --- /dev/null +++ b/000_temp/56_SVCC-17/04a/templates/about.gohtml @@ -0,0 +1,5 @@ +{{template "header" .}} + +

ABOUT OUR TEAM

+ +{{template "footer"}} diff --git a/000_temp/56_SVCC-17/04a/templates/incl-footer.gohtml b/000_temp/56_SVCC-17/04a/templates/incl-footer.gohtml new file mode 100644 index 00000000..37bdaade --- /dev/null +++ b/000_temp/56_SVCC-17/04a/templates/incl-footer.gohtml @@ -0,0 +1,4 @@ +{{define "footer"}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/04a/templates/incl-header.gohtml b/000_temp/56_SVCC-17/04a/templates/incl-header.gohtml new file mode 100644 index 00000000..16cfc4a3 --- /dev/null +++ b/000_temp/56_SVCC-17/04a/templates/incl-header.gohtml @@ -0,0 +1,9 @@ +{{define "header"}} + + + + + {{.}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/04a/templates/index.gohtml b/000_temp/56_SVCC-17/04a/templates/index.gohtml new file mode 100644 index 00000000..3ccfd708 --- /dev/null +++ b/000_temp/56_SVCC-17/04a/templates/index.gohtml @@ -0,0 +1,5 @@ +{{template "header" .}} + +

Hello from ACME INC

+ +{{template "footer"}} diff --git a/000_temp/56_SVCC-17/04b/main.go b/000_temp/56_SVCC-17/04b/main.go new file mode 100644 index 00000000..a6b8f5ca --- /dev/null +++ b/000_temp/56_SVCC-17/04b/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", "ACME INC") +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", "THE TEAM") +} diff --git a/000_temp/56_SVCC-17/04b/templates/about.gohtml b/000_temp/56_SVCC-17/04b/templates/about.gohtml new file mode 100644 index 00000000..d0cd00ab --- /dev/null +++ b/000_temp/56_SVCC-17/04b/templates/about.gohtml @@ -0,0 +1,4 @@ + +{{template "header" .}} +

all about our team

+{{template "footer"}} diff --git a/000_temp/56_SVCC-17/04b/templates/incl-footer.gohtml b/000_temp/56_SVCC-17/04b/templates/incl-footer.gohtml new file mode 100644 index 00000000..37bdaade --- /dev/null +++ b/000_temp/56_SVCC-17/04b/templates/incl-footer.gohtml @@ -0,0 +1,4 @@ +{{define "footer"}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/04b/templates/incl-header.gohtml b/000_temp/56_SVCC-17/04b/templates/incl-header.gohtml new file mode 100644 index 00000000..16cfc4a3 --- /dev/null +++ b/000_temp/56_SVCC-17/04b/templates/incl-header.gohtml @@ -0,0 +1,9 @@ +{{define "header"}} + + + + + {{.}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/04b/templates/index.gohtml b/000_temp/56_SVCC-17/04b/templates/index.gohtml new file mode 100644 index 00000000..1abb7d76 --- /dev/null +++ b/000_temp/56_SVCC-17/04b/templates/index.gohtml @@ -0,0 +1,4 @@ + +{{template "header" .}} +

all about acme inc

+{{template "footer"}} diff --git a/000_temp/56_SVCC-17/04c/main.go b/000_temp/56_SVCC-17/04c/main.go new file mode 100644 index 00000000..dfb4b33f --- /dev/null +++ b/000_temp/56_SVCC-17/04c/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", "ACME INC") +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", "ABOUT OUR TEAM") +} diff --git a/000_temp/56_SVCC-17/04c/templates/about.gohtml b/000_temp/56_SVCC-17/04c/templates/about.gohtml new file mode 100644 index 00000000..22f0b58b --- /dev/null +++ b/000_temp/56_SVCC-17/04c/templates/about.gohtml @@ -0,0 +1,7 @@ +{{template "header" .}} + + + +

ABOUT US

+ +{{template "footer"}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/04c/templates/incl-footer.gohtml b/000_temp/56_SVCC-17/04c/templates/incl-footer.gohtml new file mode 100644 index 00000000..37bdaade --- /dev/null +++ b/000_temp/56_SVCC-17/04c/templates/incl-footer.gohtml @@ -0,0 +1,4 @@ +{{define "footer"}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/04c/templates/incl-header.gohtml b/000_temp/56_SVCC-17/04c/templates/incl-header.gohtml new file mode 100644 index 00000000..c9b0ef1e --- /dev/null +++ b/000_temp/56_SVCC-17/04c/templates/incl-header.gohtml @@ -0,0 +1,7 @@ +{{define "header"}} + + + + + {{.}} +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/04c/templates/index.gohtml b/000_temp/56_SVCC-17/04c/templates/index.gohtml new file mode 100644 index 00000000..f904703d --- /dev/null +++ b/000_temp/56_SVCC-17/04c/templates/index.gohtml @@ -0,0 +1,7 @@ +{{template "header" .}} + + + +

HELLO FROM SVCC 2017 WOOHOOO!!!

+ +{{template "footer"}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/04d/main.go b/000_temp/56_SVCC-17/04d/main.go new file mode 100644 index 00000000..99d15727 --- /dev/null +++ b/000_temp/56_SVCC-17/04d/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about/", about) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} diff --git a/000_temp/56_SVCC-17/04d/templates/about.gohtml b/000_temp/56_SVCC-17/04d/templates/about.gohtml new file mode 100644 index 00000000..25c194ca --- /dev/null +++ b/000_temp/56_SVCC-17/04d/templates/about.gohtml @@ -0,0 +1,8 @@ +{{template "header"}} + ABOUT + + + +

ABOUT

+ +{{template "footer"}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/04d/templates/inc-footer.gohtml b/000_temp/56_SVCC-17/04d/templates/inc-footer.gohtml new file mode 100644 index 00000000..37bdaade --- /dev/null +++ b/000_temp/56_SVCC-17/04d/templates/inc-footer.gohtml @@ -0,0 +1,4 @@ +{{define "footer"}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/04d/templates/inc-header.gohtml b/000_temp/56_SVCC-17/04d/templates/inc-header.gohtml new file mode 100644 index 00000000..757bd31c --- /dev/null +++ b/000_temp/56_SVCC-17/04d/templates/inc-header.gohtml @@ -0,0 +1,9 @@ +{{define "header"}} + + + + + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/04d/templates/index.gohtml b/000_temp/56_SVCC-17/04d/templates/index.gohtml new file mode 100644 index 00000000..412ba59a --- /dev/null +++ b/000_temp/56_SVCC-17/04d/templates/index.gohtml @@ -0,0 +1,8 @@ +{{template "header"}} + Document + + + +

HELLO FRESNO GDG

+ +{{template "footer"}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/05a/main.go b/000_temp/56_SVCC-17/05a/main.go new file mode 100644 index 00000000..1ea5b277 --- /dev/null +++ b/000_temp/56_SVCC-17/05a/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", "ACME, INC") +} + +func about(w http.ResponseWriter, r *http.Request) { + type customData struct { + Title string + Members []string + } + + cd := customData{ + Title: "OUR TEAM", + Members: []string{"Moneypenny", "Bond", "Q", "M"}, + } + + tpl.ExecuteTemplate(w, "about.gohtml", cd) +} diff --git a/000_temp/56_SVCC-17/05a/templates/about.gohtml b/000_temp/56_SVCC-17/05a/templates/about.gohtml new file mode 100644 index 00000000..55ae202e --- /dev/null +++ b/000_temp/56_SVCC-17/05a/templates/about.gohtml @@ -0,0 +1,9 @@ +{{template "header" .Title}} + +

ABOUT OUR TEAM

+ +{{range .Members}} +{{.}}
+{{end}} + +{{template "footer"}} diff --git a/000_temp/56_SVCC-17/05a/templates/incl-footer.gohtml b/000_temp/56_SVCC-17/05a/templates/incl-footer.gohtml new file mode 100644 index 00000000..37bdaade --- /dev/null +++ b/000_temp/56_SVCC-17/05a/templates/incl-footer.gohtml @@ -0,0 +1,4 @@ +{{define "footer"}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/05a/templates/incl-header.gohtml b/000_temp/56_SVCC-17/05a/templates/incl-header.gohtml new file mode 100644 index 00000000..16cfc4a3 --- /dev/null +++ b/000_temp/56_SVCC-17/05a/templates/incl-header.gohtml @@ -0,0 +1,9 @@ +{{define "header"}} + + + + + {{.}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/05a/templates/index.gohtml b/000_temp/56_SVCC-17/05a/templates/index.gohtml new file mode 100644 index 00000000..3ccfd708 --- /dev/null +++ b/000_temp/56_SVCC-17/05a/templates/index.gohtml @@ -0,0 +1,5 @@ +{{template "header" .}} + +

Hello from ACME INC

+ +{{template "footer"}} diff --git a/000_temp/56_SVCC-17/05b/main.go b/000_temp/56_SVCC-17/05b/main.go new file mode 100644 index 00000000..4f1d2d8a --- /dev/null +++ b/000_temp/56_SVCC-17/05b/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", "ACME INC") +} + +func about(w http.ResponseWriter, r *http.Request) { + type customData struct { + Title string + Members []string + } + + cd := customData{ + Title: "THE TEAM", + Members: []string{"Moneypenny", "Bond", "Q", "M"}, + } + + tpl.ExecuteTemplate(w, "about.gohtml", cd) +} diff --git a/000_temp/56_SVCC-17/05b/templates/about.gohtml b/000_temp/56_SVCC-17/05b/templates/about.gohtml new file mode 100644 index 00000000..e145ec66 --- /dev/null +++ b/000_temp/56_SVCC-17/05b/templates/about.gohtml @@ -0,0 +1,7 @@ + +{{template "header" .Title}} +

all about our team

+{{range .Members}} +{{.}}
+{{end}} +{{template "footer"}} diff --git a/000_temp/56_SVCC-17/05b/templates/incl-footer.gohtml b/000_temp/56_SVCC-17/05b/templates/incl-footer.gohtml new file mode 100644 index 00000000..37bdaade --- /dev/null +++ b/000_temp/56_SVCC-17/05b/templates/incl-footer.gohtml @@ -0,0 +1,4 @@ +{{define "footer"}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/05b/templates/incl-header.gohtml b/000_temp/56_SVCC-17/05b/templates/incl-header.gohtml new file mode 100644 index 00000000..16cfc4a3 --- /dev/null +++ b/000_temp/56_SVCC-17/05b/templates/incl-header.gohtml @@ -0,0 +1,9 @@ +{{define "header"}} + + + + + {{.}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/05b/templates/index.gohtml b/000_temp/56_SVCC-17/05b/templates/index.gohtml new file mode 100644 index 00000000..1abb7d76 --- /dev/null +++ b/000_temp/56_SVCC-17/05b/templates/index.gohtml @@ -0,0 +1,4 @@ + +{{template "header" .}} +

all about acme inc

+{{template "footer"}} diff --git a/000_temp/56_SVCC-17/05c/main.go b/000_temp/56_SVCC-17/05c/main.go new file mode 100644 index 00000000..f96b5c90 --- /dev/null +++ b/000_temp/56_SVCC-17/05c/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", "ACME INC") +} + +func about(w http.ResponseWriter, r *http.Request) { + type customData struct { + Title string + Members []string + } + + cd := customData{ + Title: "ABOUT OUR TEAM", + Members: []string{"Moneypenny", "Bond", "Q", "M"}, + } + + tpl.ExecuteTemplate(w, "about.gohtml", cd) +} diff --git a/000_temp/56_SVCC-17/05c/templates/about.gohtml b/000_temp/56_SVCC-17/05c/templates/about.gohtml new file mode 100644 index 00000000..4a05bdf1 --- /dev/null +++ b/000_temp/56_SVCC-17/05c/templates/about.gohtml @@ -0,0 +1,10 @@ +{{template "header" .Title}} + + + +

ABOUT US

+{{range .Members}} +{{.}}
+{{end}} + +{{template "footer"}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/05c/templates/incl-footer.gohtml b/000_temp/56_SVCC-17/05c/templates/incl-footer.gohtml new file mode 100644 index 00000000..37bdaade --- /dev/null +++ b/000_temp/56_SVCC-17/05c/templates/incl-footer.gohtml @@ -0,0 +1,4 @@ +{{define "footer"}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/05c/templates/incl-header.gohtml b/000_temp/56_SVCC-17/05c/templates/incl-header.gohtml new file mode 100644 index 00000000..c9b0ef1e --- /dev/null +++ b/000_temp/56_SVCC-17/05c/templates/incl-header.gohtml @@ -0,0 +1,7 @@ +{{define "header"}} + + + + + {{.}} +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/05c/templates/index.gohtml b/000_temp/56_SVCC-17/05c/templates/index.gohtml new file mode 100644 index 00000000..f904703d --- /dev/null +++ b/000_temp/56_SVCC-17/05c/templates/index.gohtml @@ -0,0 +1,7 @@ +{{template "header" .}} + + + +

HELLO FROM SVCC 2017 WOOHOOO!!!

+ +{{template "footer"}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/05d/main.go b/000_temp/56_SVCC-17/05d/main.go new file mode 100644 index 00000000..d0b8460f --- /dev/null +++ b/000_temp/56_SVCC-17/05d/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about/", about) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", 42) +} + +func about(w http.ResponseWriter, r *http.Request) { + type customData struct { + Title string + Members []string + } + + cd := customData{ + Title: "ABOUT OUR TEAM", + Members: []string{"Moneypenny", "Bond", "Q", "M"}, + } + + tpl.ExecuteTemplate(w, "about.gohtml", cd) +} diff --git a/000_temp/56_SVCC-17/05d/templates/about.gohtml b/000_temp/56_SVCC-17/05d/templates/about.gohtml new file mode 100644 index 00000000..260fa388 --- /dev/null +++ b/000_temp/56_SVCC-17/05d/templates/about.gohtml @@ -0,0 +1,16 @@ +{{template "header"}} + {{.Title}} + + + +

{{.}}

+

{{.Title}}

+

{{.Members}}

+ + + +{{template "footer"}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/05d/templates/inc-footer.gohtml b/000_temp/56_SVCC-17/05d/templates/inc-footer.gohtml new file mode 100644 index 00000000..37bdaade --- /dev/null +++ b/000_temp/56_SVCC-17/05d/templates/inc-footer.gohtml @@ -0,0 +1,4 @@ +{{define "footer"}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/05d/templates/inc-header.gohtml b/000_temp/56_SVCC-17/05d/templates/inc-header.gohtml new file mode 100644 index 00000000..757bd31c --- /dev/null +++ b/000_temp/56_SVCC-17/05d/templates/inc-header.gohtml @@ -0,0 +1,9 @@ +{{define "header"}} + + + + + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/05d/templates/index.gohtml b/000_temp/56_SVCC-17/05d/templates/index.gohtml new file mode 100644 index 00000000..28444399 --- /dev/null +++ b/000_temp/56_SVCC-17/05d/templates/index.gohtml @@ -0,0 +1,8 @@ +{{template "header"}} + Document + + + +

{{.}}

+ +{{template "footer"}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/06a/assets/index.css b/000_temp/56_SVCC-17/06a/assets/index.css new file mode 100644 index 00000000..4717ad4b --- /dev/null +++ b/000_temp/56_SVCC-17/06a/assets/index.css @@ -0,0 +1,3 @@ +h1 { + color: red; +} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/06a/assets/paradise.jpeg b/000_temp/56_SVCC-17/06a/assets/paradise.jpeg new file mode 100644 index 00000000..8e2b075a Binary files /dev/null and b/000_temp/56_SVCC-17/06a/assets/paradise.jpeg differ diff --git a/000_temp/56_SVCC-17/06a/main.go b/000_temp/56_SVCC-17/06a/main.go new file mode 100644 index 00000000..2c2eb857 --- /dev/null +++ b/000_temp/56_SVCC-17/06a/main.go @@ -0,0 +1,37 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./assets")))) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", "ACME, INC") +} + +func about(w http.ResponseWriter, r *http.Request) { + type customData struct { + Title string + Members []string + } + + cd := customData{ + Title: "OUR TEAM", + Members: []string{"Moneypenny", "Bond", "Q", "M"}, + } + + tpl.ExecuteTemplate(w, "about.gohtml", cd) +} diff --git a/000_temp/56_SVCC-17/06a/templates/about.gohtml b/000_temp/56_SVCC-17/06a/templates/about.gohtml new file mode 100644 index 00000000..55ae202e --- /dev/null +++ b/000_temp/56_SVCC-17/06a/templates/about.gohtml @@ -0,0 +1,9 @@ +{{template "header" .Title}} + +

ABOUT OUR TEAM

+ +{{range .Members}} +{{.}}
+{{end}} + +{{template "footer"}} diff --git a/000_temp/56_SVCC-17/06a/templates/incl-footer.gohtml b/000_temp/56_SVCC-17/06a/templates/incl-footer.gohtml new file mode 100644 index 00000000..37bdaade --- /dev/null +++ b/000_temp/56_SVCC-17/06a/templates/incl-footer.gohtml @@ -0,0 +1,4 @@ +{{define "footer"}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/06a/templates/incl-header.gohtml b/000_temp/56_SVCC-17/06a/templates/incl-header.gohtml new file mode 100644 index 00000000..f4a24be7 --- /dev/null +++ b/000_temp/56_SVCC-17/06a/templates/incl-header.gohtml @@ -0,0 +1,10 @@ +{{define "header"}} + + + + + {{.}} + + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/06a/templates/index.gohtml b/000_temp/56_SVCC-17/06a/templates/index.gohtml new file mode 100644 index 00000000..4e33f167 --- /dev/null +++ b/000_temp/56_SVCC-17/06a/templates/index.gohtml @@ -0,0 +1,7 @@ +{{template "header" .}} + +

Hello from ACME INC

+ + + +{{template "footer"}} diff --git a/000_temp/56_SVCC-17/06b/assets/paradise.jpeg b/000_temp/56_SVCC-17/06b/assets/paradise.jpeg new file mode 100644 index 00000000..8e2b075a Binary files /dev/null and b/000_temp/56_SVCC-17/06b/assets/paradise.jpeg differ diff --git a/000_temp/56_SVCC-17/06b/main.go b/000_temp/56_SVCC-17/06b/main.go new file mode 100644 index 00000000..029717f3 --- /dev/null +++ b/000_temp/56_SVCC-17/06b/main.go @@ -0,0 +1,37 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./assets")))) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", "ACME INC") +} + +func about(w http.ResponseWriter, r *http.Request) { + type customData struct { + Title string + Members []string + } + + cd := customData{ + Title: "THE TEAM", + Members: []string{"Moneypenny", "Bond", "Q", "M"}, + } + + tpl.ExecuteTemplate(w, "about.gohtml", cd) +} diff --git a/000_temp/56_SVCC-17/06b/templates/about.gohtml b/000_temp/56_SVCC-17/06b/templates/about.gohtml new file mode 100644 index 00000000..e145ec66 --- /dev/null +++ b/000_temp/56_SVCC-17/06b/templates/about.gohtml @@ -0,0 +1,7 @@ + +{{template "header" .Title}} +

all about our team

+{{range .Members}} +{{.}}
+{{end}} +{{template "footer"}} diff --git a/000_temp/56_SVCC-17/06b/templates/incl-footer.gohtml b/000_temp/56_SVCC-17/06b/templates/incl-footer.gohtml new file mode 100644 index 00000000..37bdaade --- /dev/null +++ b/000_temp/56_SVCC-17/06b/templates/incl-footer.gohtml @@ -0,0 +1,4 @@ +{{define "footer"}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/06b/templates/incl-header.gohtml b/000_temp/56_SVCC-17/06b/templates/incl-header.gohtml new file mode 100644 index 00000000..16cfc4a3 --- /dev/null +++ b/000_temp/56_SVCC-17/06b/templates/incl-header.gohtml @@ -0,0 +1,9 @@ +{{define "header"}} + + + + + {{.}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/06b/templates/index.gohtml b/000_temp/56_SVCC-17/06b/templates/index.gohtml new file mode 100644 index 00000000..dbf294c5 --- /dev/null +++ b/000_temp/56_SVCC-17/06b/templates/index.gohtml @@ -0,0 +1,5 @@ + +{{template "header" .}} +

all about acme inc

+ +{{template "footer"}} diff --git a/000_temp/56_SVCC-17/06c/assets/index.css b/000_temp/56_SVCC-17/06c/assets/index.css new file mode 100644 index 00000000..46d4f979 --- /dev/null +++ b/000_temp/56_SVCC-17/06c/assets/index.css @@ -0,0 +1,22 @@ +html, body, h1 { + padding: 0; + border: 0; + margin: 0; + box-sizing: border-box; +} + +body { + display: flex; + justify-content: center; + align-items: center; + background-image: url("http://github.com/assets/paradise.jpeg"); + background-position: center; + background-size: cover; + background-repeat: no-repeat; + height: 100vh; +} + +h1 { + font-size: 12vw; + color: white; +} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/06c/assets/paradise.jpeg b/000_temp/56_SVCC-17/06c/assets/paradise.jpeg new file mode 100644 index 00000000..8e2b075a Binary files /dev/null and b/000_temp/56_SVCC-17/06c/assets/paradise.jpeg differ diff --git a/000_temp/56_SVCC-17/06c/main.go b/000_temp/56_SVCC-17/06c/main.go new file mode 100644 index 00000000..2052430b --- /dev/null +++ b/000_temp/56_SVCC-17/06c/main.go @@ -0,0 +1,37 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./assets")))) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", "ACME INC") +} + +func about(w http.ResponseWriter, r *http.Request) { + type customData struct { + Title string + Members []string + } + + cd := customData{ + Title: "ABOUT OUR TEAM", + Members: []string{"Moneypenny", "Bond", "Q", "M"}, + } + + tpl.ExecuteTemplate(w, "about.gohtml", cd) +} diff --git a/000_temp/56_SVCC-17/06c/templates/about.gohtml b/000_temp/56_SVCC-17/06c/templates/about.gohtml new file mode 100644 index 00000000..4a05bdf1 --- /dev/null +++ b/000_temp/56_SVCC-17/06c/templates/about.gohtml @@ -0,0 +1,10 @@ +{{template "header" .Title}} + + + +

ABOUT US

+{{range .Members}} +{{.}}
+{{end}} + +{{template "footer"}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/06c/templates/incl-footer.gohtml b/000_temp/56_SVCC-17/06c/templates/incl-footer.gohtml new file mode 100644 index 00000000..37bdaade --- /dev/null +++ b/000_temp/56_SVCC-17/06c/templates/incl-footer.gohtml @@ -0,0 +1,4 @@ +{{define "footer"}} + + +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/06c/templates/incl-header.gohtml b/000_temp/56_SVCC-17/06c/templates/incl-header.gohtml new file mode 100644 index 00000000..c9b0ef1e --- /dev/null +++ b/000_temp/56_SVCC-17/06c/templates/incl-header.gohtml @@ -0,0 +1,7 @@ +{{define "header"}} + + + + + {{.}} +{{end}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/06c/templates/index.gohtml b/000_temp/56_SVCC-17/06c/templates/index.gohtml new file mode 100644 index 00000000..32700220 --- /dev/null +++ b/000_temp/56_SVCC-17/06c/templates/index.gohtml @@ -0,0 +1,8 @@ +{{template "header" .}} + + + + +

PARADISE

+ +{{template "footer"}} \ No newline at end of file diff --git a/000_temp/56_SVCC-17/07-concurrency/main.go b/000_temp/56_SVCC-17/07-concurrency/main.go new file mode 100644 index 00000000..ad6b5cf4 --- /dev/null +++ b/000_temp/56_SVCC-17/07-concurrency/main.go @@ -0,0 +1,11 @@ +package main + +import "fmt" + +func main() { + c := make(chan int) + go func() { + c <- 42 + }() + fmt.Println(<-c) +} diff --git a/000_temp/57-form/01/main.go b/000_temp/57-form/01/main.go new file mode 100644 index 00000000..7b7e8f29 --- /dev/null +++ b/000_temp/57-form/01/main.go @@ -0,0 +1,15 @@ +package _1 + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "Hello fcc") +} diff --git a/000_temp/57-form/02/main.go b/000_temp/57-form/02/main.go new file mode 100644 index 00000000..68b3556c --- /dev/null +++ b/000_temp/57-form/02/main.go @@ -0,0 +1,49 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/process", processor) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func processor(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + + fname := r.FormValue("firster") + lname := r.FormValue("laster") + surf := r.FormValue("surf") + snow := r.FormValue("snow") + skate := r.FormValue("skate") + radio := r.FormValue("cow") + + d := struct { + First, Last, Surf, Snow, Skate, Radio string + }{ + First: fname, + Last: lname, + Surf: surf, + Snow: snow, + Skate: skate, + Radio: radio, + } + + tpl.ExecuteTemplate(w, "processor.gohtml", d) +} diff --git a/000_temp/57-form/02/templates/index.gohtml b/000_temp/57-form/02/templates/index.gohtml new file mode 100644 index 00000000..ae69cdd6 --- /dev/null +++ b/000_temp/57-form/02/templates/index.gohtml @@ -0,0 +1,55 @@ + + + + + + INDEX + + + +

OUR FORM EXAMPLE

+ +
+
+ + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +

RADIO BUTTON

+ + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/000_temp/57-form/02/templates/processor.gohtml b/000_temp/57-form/02/templates/processor.gohtml new file mode 100644 index 00000000..9fdda392 --- /dev/null +++ b/000_temp/57-form/02/templates/processor.gohtml @@ -0,0 +1,20 @@ + + + + + + PROCESSOR + + + +

{{.First}} {{.Last}}

+ +

Surf {{.Surf}}

+

Snow {{.Snow}}

+

Skate {{.Skate}}

+ +

radio button {{.Radio}}

+ + + \ No newline at end of file diff --git a/000_temp/58-simple/main.go b/000_temp/58-simple/main.go new file mode 100644 index 00000000..99fd8050 --- /dev/null +++ b/000_temp/58-simple/main.go @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main() { + fmt.Println("Hello") +} diff --git a/000_temp/59-html-form/assets/form.css b/000_temp/59-html-form/assets/form.css new file mode 100644 index 00000000..65d03ff9 --- /dev/null +++ b/000_temp/59-html-form/assets/form.css @@ -0,0 +1,9 @@ +form { + display: flex; + flex-direction: column; + font-size: 6rem; +} + +input { + height: 5vh; +} \ No newline at end of file diff --git a/000_temp/59-html-form/assets/main.css b/000_temp/59-html-form/assets/main.css new file mode 100644 index 00000000..af55a75d --- /dev/null +++ b/000_temp/59-html-form/assets/main.css @@ -0,0 +1,58 @@ +html, body, main, header, div, a { + padding: 0; + border: 0; + margin: 0; + box-sizing: border-box; +} + +main { + height: 100vh; + background-image: url("http://github.com/assets/paradise.jpeg"); + background-repeat: no-repeat; + background-size: cover; + background-position: center; + display: flex; + justify-content: center; + align-items: center; + color: white; + font-size: 12rem; +} + +header { + position: fixed; + top: 0; + left: 0; + height: 4vh; + background-color: rgba(121, 200, 255, 0.39); + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + border-bottom: 1px solid gray; +} + +header > div { + height: 100%; + font-size: 1.5rem; + color: white; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + margin: 20px; +} + +header > div > a { + padding: 20px; + text-decoration: none; + color: white; +} + +header > div > a:hover { + color: blue; +} + +footer { + font-size: 12rem; + color: black; +} \ No newline at end of file diff --git a/000_temp/59-html-form/assets/paradise.jpeg b/000_temp/59-html-form/assets/paradise.jpeg new file mode 100644 index 00000000..8e2b075a Binary files /dev/null and b/000_temp/59-html-form/assets/paradise.jpeg differ diff --git a/000_temp/59-html-form/main.go b/000_temp/59-html-form/main.go new file mode 100644 index 00000000..992111d9 --- /dev/null +++ b/000_temp/59-html-form/main.go @@ -0,0 +1,74 @@ +package main + +import ( + "html/template" + "net/http" +) + +type GData struct { + Title string +} + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.HandleFunc("/contact", contact) + http.HandleFunc("/signup", signup) + http.HandleFunc("/process", process) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./assets")))) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + gd := GData{ + Title: "Acme Inc", + } + tpl.ExecuteTemplate(w, "index.gohtml", gd) +} + +func about(w http.ResponseWriter, r *http.Request) { + gd := GData{ + Title: "ABOUT", + } + tpl.ExecuteTemplate(w, "about.gohtml", gd) +} + +func contact(w http.ResponseWriter, r *http.Request) { + gd := GData{ + Title: "CONTACT", + } + tpl.ExecuteTemplate(w, "contact.gohtml", gd) +} + +func signup(w http.ResponseWriter, r *http.Request) { + gd := GData{ + Title: "SIGNUP", + } + tpl.ExecuteTemplate(w, "signup.gohtml", gd) +} + +func process(w http.ResponseWriter, r *http.Request) { + + fn := r.FormValue("first") + ln := r.FormValue("last") + + d := struct { + GData + First string + Last string + }{ + GData: GData{ + Title: "PROCESS", + }, + First: fn, + Last: ln, + } + + tpl.ExecuteTemplate(w, "process.gohtml", d) +} diff --git a/000_temp/59-html-form/templates/about.gohtml b/000_temp/59-html-form/templates/about.gohtml new file mode 100644 index 00000000..1c6a92c4 --- /dev/null +++ b/000_temp/59-html-form/templates/about.gohtml @@ -0,0 +1,20 @@ + + + + + + {{.Title}} + + + + +{{template "header"}} + +
+

{{.Title}}

+
+ + + + \ No newline at end of file diff --git a/000_temp/59-html-form/templates/contact.gohtml b/000_temp/59-html-form/templates/contact.gohtml new file mode 100644 index 00000000..94e82bcd --- /dev/null +++ b/000_temp/59-html-form/templates/contact.gohtml @@ -0,0 +1,21 @@ + + + + + + {{.Title}} + + + + +{{template "header"}} + +
+

{{.Title}}

+
+ + + + + \ No newline at end of file diff --git a/000_temp/59-html-form/templates/incl-header.gohtml b/000_temp/59-html-form/templates/incl-header.gohtml new file mode 100644 index 00000000..00c340cf --- /dev/null +++ b/000_temp/59-html-form/templates/incl-header.gohtml @@ -0,0 +1,11 @@ +{{define "header"}} +
+
Company Logo
+
+ home
+ about
+ contact
+ signup
+
+
+{{end}} \ No newline at end of file diff --git a/000_temp/59-html-form/templates/incl-links.gohtml b/000_temp/59-html-form/templates/incl-links.gohtml new file mode 100644 index 00000000..fcf7cd42 --- /dev/null +++ b/000_temp/59-html-form/templates/incl-links.gohtml @@ -0,0 +1,3 @@ +{{define "links"}} + +{{end}} \ No newline at end of file diff --git a/000_temp/59-html-form/templates/index.gohtml b/000_temp/59-html-form/templates/index.gohtml new file mode 100644 index 00000000..94e82bcd --- /dev/null +++ b/000_temp/59-html-form/templates/index.gohtml @@ -0,0 +1,21 @@ + + + + + + {{.Title}} + + + + +{{template "header"}} + +
+

{{.Title}}

+
+ + + + + \ No newline at end of file diff --git a/000_temp/59-html-form/templates/process.gohtml b/000_temp/59-html-form/templates/process.gohtml new file mode 100644 index 00000000..b315f758 --- /dev/null +++ b/000_temp/59-html-form/templates/process.gohtml @@ -0,0 +1,25 @@ + + + + + + {{.Title}} + + + + +{{template "header"}} + +
+

{{.Title}}

+
+ + + + + + \ No newline at end of file diff --git a/000_temp/59-html-form/templates/signup.gohtml b/000_temp/59-html-form/templates/signup.gohtml new file mode 100644 index 00000000..e1b7145b --- /dev/null +++ b/000_temp/59-html-form/templates/signup.gohtml @@ -0,0 +1,38 @@ + + + + + + {{.Title}} + + + + + +{{template "header"}} + +
+

{{.Title}}

+
+ +
+ + + + + + + + + +
+ + + + + + + \ No newline at end of file diff --git a/000_temp/60-redirect/main.go b/000_temp/60-redirect/main.go new file mode 100644 index 00000000..57fad399 --- /dev/null +++ b/000_temp/60-redirect/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/new", newplace) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/new", http.StatusSeeOther) + io.WriteString(w, "You are at index") +} + +func newplace(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "You are at newplace") +} diff --git a/000_temp/61-assertion/main.go b/000_temp/61-assertion/main.go new file mode 100644 index 00000000..9fd92895 --- /dev/null +++ b/000_temp/61-assertion/main.go @@ -0,0 +1,16 @@ +package main + +import "fmt" + +func main() { + var s interface{} + s = struct { + name string + }{ + name: "james bond", + } + fmt.Printf("%T\n", s) + s = "James Bond" + fmt.Printf("%T\n", s) + fmt.Println(s) +} diff --git a/000_temp/62-kelowna/00-prep/01/main.go b/000_temp/62-kelowna/00-prep/01/main.go new file mode 100644 index 00000000..f98e0ff9 --- /dev/null +++ b/000_temp/62-kelowna/00-prep/01/main.go @@ -0,0 +1,57 @@ +package main + +import "fmt" + +type person struct { + first string + last string +} + +type secretAgent struct { + person + ltk bool +} + +func (p person) speak() { + fmt.Println("hello from", p.first) +} + +func (sa secretAgent) speak() { + fmt.Println("hello from", sa.first) +} + +type human interface { + speak() +} + +func foo(h human) { + h.speak() +} + +func bar(h human) { + h.speak() +} + +func main() { + x := person{ + first: "miss", + last: "money", + } + + y := secretAgent{ + person: person{ + first: "james", + last: "bond", + }, + ltk: true, + } + + x.speak() + y.speak() + + foo(x) + foo(y) + + fmt.Println("Hello", x) + fmt.Println("Hello", y) +} diff --git a/000_temp/62-kelowna/00-prep/02/main.go b/000_temp/62-kelowna/00-prep/02/main.go new file mode 100644 index 00000000..96ff7e59 --- /dev/null +++ b/000_temp/62-kelowna/00-prep/02/main.go @@ -0,0 +1,20 @@ +package main + +import "fmt" + +func main() { + xi := []int{4, 5, 6, 7} + + for n, i := range xi { + fmt.Println(n, i) + } + + m := map[string]int{ + "mcleod": 47, + "bond": 27, + } + + for k, v := range m { + fmt.Println(k, v) + } +} diff --git a/000_temp/62-kelowna/01-present/01/main.go b/000_temp/62-kelowna/01-present/01/main.go new file mode 100644 index 00000000..f7689e16 --- /dev/null +++ b/000_temp/62-kelowna/01-present/01/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/about", about) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", 42) + //io.WriteString(w, "Hello Kelowna") +} + +func about(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", "JAMES BOND") +} diff --git a/000_temp/62-kelowna/01-present/01/templates/about.gohtml b/000_temp/62-kelowna/01-present/01/templates/about.gohtml new file mode 100644 index 00000000..47cd1272 --- /dev/null +++ b/000_temp/62-kelowna/01-present/01/templates/about.gohtml @@ -0,0 +1,14 @@ + + + + + ABOUT + + + +

This is the about page

+ +{{.}} + + + \ No newline at end of file diff --git a/000_temp/62-kelowna/01-present/01/templates/index.gohtml b/000_temp/62-kelowna/01-present/01/templates/index.gohtml new file mode 100644 index 00000000..0966d1d4 --- /dev/null +++ b/000_temp/62-kelowna/01-present/01/templates/index.gohtml @@ -0,0 +1,14 @@ + + + + + INDEX + + + +

Hello, Kelowna

+ +{{.}} + + + \ No newline at end of file diff --git a/000_temp/62-kelowna/01-present/02/main.go b/000_temp/62-kelowna/01-present/02/main.go new file mode 100644 index 00000000..96ff7e59 --- /dev/null +++ b/000_temp/62-kelowna/01-present/02/main.go @@ -0,0 +1,20 @@ +package main + +import "fmt" + +func main() { + xi := []int{4, 5, 6, 7} + + for n, i := range xi { + fmt.Println(n, i) + } + + m := map[string]int{ + "mcleod": 47, + "bond": 27, + } + + for k, v := range m { + fmt.Println(k, v) + } +} diff --git a/000_temp/62-kelowna/01-present/03/main.go b/000_temp/62-kelowna/01-present/03/main.go new file mode 100644 index 00000000..39635b81 --- /dev/null +++ b/000_temp/62-kelowna/01-present/03/main.go @@ -0,0 +1,59 @@ +package main + +import "fmt" + +// https://play.golang.org/p/gLdpEzVm54U + +type person struct { + first string + last string +} + +type secretAgent struct { + person + ltk bool +} + +// func (r receiver) identifier(parameters) (returns) {code} + +func (p person) speak() { + fmt.Println(p.first, `says, "Why, James. Helllllo."`) +} + +func (sa secretAgent) speak() { + fmt.Println(sa.first, `says, "Why Miss Moneypenny. So good to see you. One martini please. Shaken, not stirred."`) +} + +type human interface { + speak() +} + +func foo(h human) { + h.speak() +} + +func main() { + p1 := person{ + first: "Missy", + last: "Moneypenny", + } + + p2 := secretAgent{ + person: person{ + first: "James", + last: "Bond", + }, + ltk: true, + } + + fmt.Println(p1) + + fmt.Println(p2) + + p1.speak() + + p2.speak() + + foo(p1) + foo(p2) +} diff --git a/000_temp/62-kelowna/02/temp.txt b/000_temp/62-kelowna/02/temp.txt new file mode 100644 index 00000000..20c8f38e --- /dev/null +++ b/000_temp/62-kelowna/02/temp.txt @@ -0,0 +1,55 @@ +INSERT INTO customers VALUES (12, 'Jamesx', 8000, 'CA'), (13, 'Jennyx', 11000, 'WA'), (14, 'Toddx', 9950, 'OR'), (15, 'Rickx', 10500, 'WA'), (16, 'Stevex', 10250, 'CA'), (17, 'Andrewx', 7750, 'OR'), (18, 'Josephinex', 13000, 'WA'), (19, 'Maxx', 12000, 'CA'), (20, 'Stephaniex', 8000, 'OR'), (21, 'Agnesx', 9999, 'WA'); + + + +INSERT INTO ingredients VALUES (1, 'Kale', '1 cup, pulled from stem'), (2, 'blueberries', 'a handful'), (3, 'pineapple', 'a handful'), (4, 'ice', 'a handful'), (5, 'juice', '1 cup'), (6, 'water', 'as much as needed'), (7, 'peanut butter', '3/4 cup'), (8, 'old-fashioned rolled oats', '1.5 cups'), (9, 'all-purpose flour', '2 cups'), (10, 'baking powder', '1 teaspoon'), (11, 'baking soda', '1 teaspon'), (12, 'salt', '1 teaspoon'), (13, 'butter', '2 sticks, softended'), (14, 'granulated sugar', '1 cup'), (15, 'brown sugar', '1 cup firmly packed'), (16, 'vanilla extract', '1 tablespoon'), (17, 'eggs', '2 large'), (18, 'semisweet chocolate chips', '12 ounces'), (19, 'semisweet chocolate, grated', '8 ounces'); + +INSERT INTO recipeingredients VALUES (1, 2, 1), (2, 2, 2), (3, 2, 3), (4, 2, 4), (5, 2, 5), (6, 2, 6), (7, 1, 7), (8,1,8), (9,1,9), (10,1,10), (11,1,11), (12,1,12), (13,1,13), (14,1,14), (15,1,15), (16,1,16), (17,1,17), (18,1,18), (19,1,19); + +SELECT rname, iname, iamount FROM recipes JOIN recipeingredients ON recipes.rid = recipeingredients.rid JOIN ingredients ON recipeingredients.iid = ingredients.iid; + + +CREATE DATABASE climbing; + +\c climbing + +CREATE TABLE categories (catID INT PRIMARY KEY NOT NULL, catName TEXT NOT NULL); + +INSERT INTO categories VALUES (1, 'easy'), (2, 'medium'), (3, 'hard'), (4, 'impossible'); + +CREATE TABLE climbs (cID INT PRIMARY KEY NOT NULL, cName TEXT NOT NULL, catID INT REFERENCES categories(catID)); + +INSERT INTO climbs VALUES (1, 'metal mark', 1), (2, 'tollhouse slab', 1), (3, 'pinnacles', 2), (4, 'Arroyo', 3), (5, 'El Cap', 3), (6, 'North Face', 4); + +SELECT cname, catname FROM climbs INNER JOIN categories ON climbs.catid = categories.catid; + + +SELECT c.cname, m.mname FROM customers AS c JOIN rentals AS r ON c.cid = r.cid JOIN movies AS m ON m.mid =r.mid; + + +CREATE TABLE actors(aid INT PRIMARY KEY NOT NULL, aname TEXT NOT NULL); + +INSERT INTO actors VALUES (1, 'James'), (2, 'Jenny'), (3, 'Rock'), (4, 'Rick'), (5, 'Steve'), (6, 'Andrew'); + +CREATE TABLE moviecast (caid INT PRIMARY KEY NOT NULL, mid INT REFERENCES movies(MID), aid INT REFERENCES actors(AID)); + +INSERT INTO moviecast VALUES (1, 2, 1), (2, 2, 2), (3, 2, 3), (4, 2, 4), (5, 2, 5), (6, 2, 6), (7, 1, 3), (8,1,2), (9,1,1), (10,1,5), (11,2,5), (12,2,6), (13,3,1), (14,3,4), (15,4,5), (16,4,2), (17,5,1), (18,6,3), (19,6,4); + + +SELECT cname, rid, mname, aname FROM customers AS c JOIN rentals as r ON c.cid = r.cid JOIN movies AS m ON r.mid = m.mid JOIN moviecast AS mc ON m.mid = mc.mid JOIN actors AS a ON mc.aid = a.aid; + +CREATE TABLE cphone (cpID INT PRIMARY KEY NOT NULL, cID INT REFERENCES customers(CID), cpPHONE TEXT NOT NULL); + +INSERT INTO cphone VALUES (1, 1, '007-0077'), (2, 2, '008-0088'), (3, 3, '009-0099'), (4, 4, '001,0011'), (5, 5, '002-0022'), (6, 6, '003-0033'), (7, 1, '777-8888'), (8, 2, '888-7777'), (9, 2, '999-3231'); + +CREATE TABLE aphone (apID INT PRIMARY KEY NOT NULL, aID INT REFERENCES actors(AID), apPHONE TEXT NOT NULL); + +INSERT INTO aphone VALUES (1, 1, '997-9977'), (2, 2, '998-9988'), (3, 3, '999-9999'), (4, 4, '991,9911'), (5, 5, '992-9922'), (6, 6, '993-9933'), (7, 1, '888-8888'), (8, 2, '888-8887'), (9, 2, '444-3231'); + +SELECT cname, cpphone FROM cphone AS cp JOIN customers AS c ON cp.cid = c.cid; + +SELECT aname, apphone FROM actors AS a JOIN aphone AS ap ON a.aid = ap.aid; + +SELECT cname, cpphone, aname, apphone FROM cphone AS cp JOIN customers AS c ON cp.cid = c.cid JOIN rentals AS r ON c.cid = r.cid JOIN movies AS m ON r.mid = m.mid JOIN moviecast AS mc ON m.mid = mc.mid JOIN actors AS a ON mc.aid = a.aid JOIN aphone AS ap ON a.aid = ap.aid; + +SELECT cname, cpphone, rid, mname, aname, apphone FROM cphone AS cp JOIN customers AS c ON cp.cid = c.cid JOIN rentals AS r ON c.cid = r.cid JOIN movies AS m ON r.mid = m.mid JOIN moviecast AS mc ON m.mid = mc.mid JOIN actors AS a ON mc.aid = a.aid JOIN aphone AS ap ON a.aid = ap.aid; \ No newline at end of file diff --git a/000_temp/62-kelowna/03/sql b/000_temp/62-kelowna/03/sql new file mode 100644 index 00000000..efde806d --- /dev/null +++ b/000_temp/62-kelowna/03/sql @@ -0,0 +1,80 @@ +INSERT INTO recipeclasses VALUES (1, 'italian'), (2,'french'), (3,'indian'), (4,'mexican'), (5,'thai'), (6,'chinese'), (7,'swiss'), (8,'german'), (9,'american'), (10,'japanese'), (11,'hungarian'), (12,'english'); + +INSERT INTO recipes VALUES (1,'hamburger',9,'bbq','include pickles'), (2,'bratwurst',8,'grill','drink beer while eating'), (3,'chow meain',6,'wok it','not so good as leftovers'), (4,'canoli',1,'lots of cream','wonderful dessert'), (5,'chai',3,'milk and spices baby','delicious to drink'), (6,'red wine',2,'enjoy za life','not so much for me'), (7,'burrito',4,'beans please','add hot sauce'), (8,'pad thai',5,'no fish sauce','put a fried egg on top'), (9,'swiss cheese',7,'put in the holes','melt it on crackers'), (10,'sushi',10,'do not cook the fish','add miso soup on the side'); + +SELECT recipeclassdescription, recipetitle FROM recipeclasses LEFT OUTER JOIN recipes ON recipeclasses.recipeclassid = recipes.recipeclassid; + +SELECT recipeclassdescription, recipetitle FROM recipeclasses LEFT JOIN recipes ON recipeclasses.recipeclassid = recipes.recipeclassid; + +SELECT rc.recipeclassdescription, r.recipetitle FROM recipeclasses AS rc LEFT JOIN recipes AS r ON rc.recipeclassid = r.recipeclassid; + +SELECT rc.recipeclassdescription FROM recipeclasses AS rc LEFT JOIN recipes AS r ON rc.recipeclassid = r.recipeclassid WHERE r.recipeid IS NULL; + +SELECT f.recipeclassdescription, r.recipetitle FROM (SELECT recipeclassid, recipeclassdescription FROM recipeclasses AS rc where rc.recipeclassdescription = 'german' OR rc.recipeclassdescription = 'italian' OR rc.recipeclassdescription = 'french') AS f LEFT JOIN recipes AS r ON f.recipeclassid = r.recipeclassid; + +SELECT f.recipetitle, rc.recipeclassdescription FROM (SELECT recipetitle, recipeclassid FROM recipes WHERE recipetitle LIKE '%a%') AS f RIGHT JOIN recipeclasses AS rc ON f.recipeclassid = rc.recipeclassid; + + + +CREATE DATABASE humanity; + +\c humanity + +CREATE TABLE humans (hid INT PRIMARY KEY NOT NULL, hname TEXT, hage INT); + +INSERT INTO humans VALUES (1,'',18), (2,'',22), (3,'jenny',27), (4,'james',32), (5,'ian',36), (6,'stephen',42), (7,'stephanie',47), (8,'agnes',49), (9,'portia',50), (10,'fidel',55), (11,'rich',62), (12,'al',78); + +SELECT f.hname FROM (SELECT hname FROM humans WHERE hname LIKE '%a%') AS f; + +SELECT f.hname, f.hage FROM (SELECT hname, hage FROM humans WHERE hage > 40) AS f; + + +SELECT f1.recipeclassdescription, f2.recipetitle FROM (SELECT recipeclasses.recipeclassid, recipeclassdescription FROM recipeclasses WHERE recipeclassdescription = 'german' OR recipeclassdescription = 'italian' OR recipeclassdescription = 'french' OR recipeclassdescription = 'hungarian') AS f1 LEFT JOIN (SELECT recipes.recipeclassid, recipetitle FROM recipes WHERE recipetitle LIKE '%o%') AS f2 on f1.recipeclassid = f2.recipeclassid; + +CREATE TABLE ingredients (ingredientid INT PRIMARY KEY NOT NULL, ingredientname TEXT); + +CREATE TABLE measurements (measurementsid INT PRIMARY KEY NOT NULL, measurementdescription TEXT); + +CREATE TABLE recipeingredients (riid INT PRIMARY KEY NOT NULL, recipeid INT NOT NULL REFERENCES recipes(recipeid), recipeseqno INT, ingredientid INT NOT NULL REFERENCES ingredients(ingredientid), measurementsid INT NOT NULL REFERENCES measurements(measurementsid)); + +INSERT INTO ingredients VALUES (1,'chocolate'), (2,'chipotle'), (3,'chicken'), (4,'beef'), (5,'flower'), (6,'butter'), (7,'milk'), (8,'broth'), (9,'salt'), (10,'baking soda'); + +INSERT INTO measurements VALUES (1,'some'), (2,'a little'), (3,'a lot'), (4,'a pinch'), (5,'until it tastes good'), (6,'not too much'), (7,'not too little'), (8,'just a pinch'), (9,'a smidge'), (10,'a generous scoop'), (11,'more than you think'), (12,'less than youd imagine'); + +INSERT INTO recipeingredients VALUES (1,6,1,7,10),(2,3,2,5,5),(3,8,3,9,7),(4,7,4,6,1),(5,4,5,3,2),(6,9,6,1,6),(7,3,7,6,9),(8,1,8,6,11),(9,1,9,8,6),(10,2,10,7,10),(11,5,11,7,6),(12,6,12,4,1),(13,7,13,8,2),(14,1,14,8,7),(15,2,15,1,3),(16,1,16,8,1),(17,2,17,4,5),(18,8,18,1,6),(19,5,19,8,3),(20,4,20,8,2),(21,9,21,7,6),(22,4,22,2,1),(23,9,23,9,1),(24,3,24,2,3),(25,9,25,6,2),(26,1,26,2,10),(27,8,27,9,6),(28,1,28,8,5),(29,3,29,8,5),(30,6,30,9,10),(31,3,31,5,10),(32,2,32,1,11),(33,4,33,1,9),(34,3,34,4,4),(35,4,35,9,8),(36,3,36,2,5),(37,4,37,2,10),(38,2,38,5,4),(39,1,39,5,6),(40,5,40,4,10),(41,3,41,2,8),(42,4,42,5,9),(43,6,43,5,2),(44,1,44,1,3),(45,8,45,9,11),(46,8,46,9,5),(47,1,47,7,3),(48,9,48,5,2),(49,9,49,6,5),(50,3,50,9,8),(51,5,51,8,5),(52,2,52,3,2),(53,4,53,4,8),(54,3,54,5,4),(55,5,55,7,1),(56,1,56,7,3),(57,7,57,8,3),(58,1,58,9,10),(59,9,59,5,11),(60,1,60,4,3),(61,2,61,1,7),(62,4,62,6,10),(63,4,63,4,9),(64,8,64,6,6),(65,6,65,7,6),(66,2,66,9,11),(67,6,67,3,11),(68,4,68,6,6),(69,6,69,3,6),(70,1,70,8,3),(71,2,71,7,4),(72,4,72,2,8),(73,8,73,3,5),(74,4,74,4,7),(75,6,75,8,9),(76,7,76,2,1),(77,8,77,3,2),(78,6,78,8,9),(79,3,79,5,10),(80,3,80,4,9),(81,7,81,7,4),(82,6,82,7,6),(83,3,83,2,10),(84,7,84,2,7),(85,9,85,2,10),(86,3,86,1,5),(87,8,87,4,2),(88,5,88,3,5),(89,6,89,4,9),(90,5,90,6,4),(91,9,91,2,9),(92,7,92,4,1),(93,7,93,4,2),(94,6,94,4,8),(95,4,95,2,5),(96,2,96,3,8),(97,5,97,3,9),(98,4,98,9,2),(99,7,99,5,2),(100,4,100,7,10); + + +SELECT recipetitle, recipeclassdescription, recipeseqno, ingredientname, measurementdescription FROM recipes AS r INNER JOIN recipeclasses AS rc ON r.recipeclassid = rc.recipeclassid INNER JOIN recipeingredients AS ri ON r.recipeid = ri.recipeid INNER JOIN ingredients AS i ON ri.ingredientid = i.ingredientid INNER JOIN measurements AS m ON ri.measurementsid = m.measurementsid ORDER BY r.recipeid, ri.recipeseqno; + +INSERT INTO recipeclasses VALUES (13, 'cambodian'), (14, 'nepalese'), (15, 'tazmanian'); + +SELECT recipeclassdescription, recipetitle FROM (recipeclasses AS rc LEFT JOIN recipes AS r ON r.recipeclassid = rc.recipeclassid); + + +--- does not work --- +SELECT recipeclassdescription, recipetitle, recipeseqno, ingredientname, measurementdescription FROM (((recipeclasses AS rc LEFT JOIN recipes AS r ON r.recipeclassid = rc.recipeclassid) INNER JOIN recipeingredients AS ri ON r.recipeid = ri.recipeid) INNER JOIN ingredients AS i ON ri.ingredientid = i.ingredientid) INNER JOIN measurements AS m ON ri.measurementsid = m.measurementsid; + +--- does work --- +SELECT recipeclassdescription, recipetitle, recipeseqno, ingredientname, measurementdescription FROM recipes AS r INNER JOIN recipeingredients AS ri ON r.recipeid = ri.recipeid INNER JOIN ingredients AS i ON ri.ingredientid = i.ingredientid INNER JOIN measurements AS m ON ri.measurementsid = m.measurementsid RIGHT JOIN recipeclasses AS rc ON r.recipeclassid = rc.recipeclassid; + +SELECT recipeclassdescription, recipetitle, recipeseqno, ingredientname, measurementdescription FROM recipes AS r INNER JOIN recipeingredients AS ri ON r.recipeid = ri.recipeid INNER JOIN ingredients AS i ON ri.ingredientid = i.ingredientid INNER JOIN measurements AS m ON ri.measurementsid = m.measurementsid RIGHT JOIN recipeclasses AS rc ON r.recipeclassid = rc.recipeclassid ORDER BY r.recipeid, ri.recipeseqno; + +SELECT recipeclassdescription, recipetitle, recipeseqno, ingredientname, measurementdescription FROM (((recipeclasses AS rc LEFT JOIN recipes AS r ON r.recipeclassid = rc.recipeclassid) LEFT JOIN recipeingredients AS ri ON r.recipeid = ri.recipeid) LEFT JOIN ingredients AS i ON ri.ingredientid = i.ingredientid) LEFT JOIN measurements AS m ON ri.measurementsid = m.measurementsid; + +SELECT recipeclassdescription, recipetitle, recipeseqno, ingredientname, measurementdescription FROM (((recipeclasses AS rc LEFT JOIN recipes AS r ON r.recipeclassid = rc.recipeclassid) LEFT JOIN recipeingredients AS ri ON r.recipeid = ri.recipeid) LEFT JOIN ingredients AS i ON ri.ingredientid = i.ingredientid) LEFT JOIN measurements AS m ON ri.measurementsid = m.measurementsid ORDER BY r.recipeid, ri.recipeseqno; + + +INSERT INTO recipes VALUES (11, 'reuben sandwich', NULL ,'put pastrami on rye and grill', 'butter your bread'), (12, 'thai chicken soup', NULL, 'use lemongrass', 'so delicious'); + + +SELECT rc.recipeclassdescription, r.recipetitle, ri.recipeseqno, i.ingredientname, m.measurementdescription FROM ((((recipeclasses AS rc JOIN recipes AS r ON rc.recipeclassid = r.recipeclassid) JOIN recipeingredients AS ri ON r.recipeid = ri.recipeid) JOIN ingredients AS i ON ri.ingredientid = i.ingredientid) JOIN measurements AS m ON ri.measurementsid = m.measurementsid); + +SELECT rc.recipeclassdescription, r.recipetitle, ri.recipeseqno, i.ingredientname, m.measurementdescription FROM ((((recipeclasses AS rc JOIN recipes AS r ON rc.recipeclassid = r.recipeclassid) JOIN recipeingredients AS ri ON r.recipeid = ri.recipeid) JOIN ingredients AS i ON ri.ingredientid = i.ingredientid) JOIN measurements AS m ON ri.measurementsid = m.measurementsid) ORDER BY r.recipetitle, ri.recipeseqno; + +SELECT rc.recipeclassdescription, r.recipetitle, ri.recipeseqno, i.ingredientname, m.measurementdescription FROM ((((recipeclasses AS rc LEFT JOIN recipes AS r ON rc.recipeclassid = r.recipeclassid) LEFT JOIN recipeingredients AS ri ON r.recipeid = ri.recipeid) LEFT JOIN ingredients AS i ON ri.ingredientid = i.ingredientid) LEFT JOIN measurements AS m ON ri.measurementsid = m.measurementsid); + +SELECT rc.recipeclassdescription, r.recipetitle, ri.recipeseqno, i.ingredientname, m.measurementdescription FROM ((((recipeclasses AS rc JOIN recipes AS r ON rc.recipeclassid = r.recipeclassid) JOIN recipeingredients AS ri ON r.recipeid = ri.recipeid) JOIN ingredients AS i ON ri.ingredientid = i.ingredientid) RIGHT JOIN measurements AS m ON ri.measurementsid = m.measurementsid); + +SELECT rc.recipeclassdescription, r.recipetitle, ri.recipeseqno, i.ingredientname, m.measurementdescription FROM ((((recipeclasses AS rc JOIN recipes AS r ON rc.recipeclassid = r.recipeclassid) JOIN recipeingredients AS ri ON r.recipeid = ri.recipeid) RIGHT JOIN ingredients AS i ON ri.ingredientid = i.ingredientid) LEFT JOIN measurements AS m ON ri.measurementsid = m.measurementsid); + +SELECT rc.recipeclassdescription, r.recipetitle, ri.recipeseqno, i.ingredientname, m.measurementdescription FROM ((((recipeclasses AS rc JOIN recipes AS r ON rc.recipeclassid = r.recipeclassid) JOIN recipeingredients AS ri ON r.recipeid = ri.recipeid) RIGHT JOIN ingredients AS i ON ri.ingredientid = i.ingredientid) FULL JOIN measurements AS m ON ri.measurementsid = m.measurementsid); \ No newline at end of file diff --git a/000_temp/62-kelowna/04-sql-union/union.sql b/000_temp/62-kelowna/04-sql-union/union.sql new file mode 100644 index 00000000..c58cf47e --- /dev/null +++ b/000_temp/62-kelowna/04-sql-union/union.sql @@ -0,0 +1,31 @@ +CREATE DATABASE exampleunion; + +\c exampleunion + +CREATE TABLE customers (cid INT PRIMARY KEY NOT NULL, first TEXT); + +INSERT INTO customers VALUES (1, 'James'), (2, 'Sergey'), (3, 'Vladimir'), (4, 'Putin'), (5, 'Coup'); + +CREATE TABLE vendors (vid INT PRIMARY KEY NOT NULL, first TEXT); + +INSERT INTO vendors VALUES (1, 'Stacey'), (2, 'Shelley'), (3, 'Sherry'), (4, 'Suzy'), (5, 'Sandy'); + +CREATE TABLE employees (eid INT PRIMARY KEY NOT NULL, first TEXT); + +INSERT INTO employees VALUES (1, 'Jeff'), (2, 'John'), (3, 'Jerry'), (4, 'Jose'), (5, 'Juan'); + +SELECT v.first FROM vendors AS v UNION SELECT e.first FROM employees AS e; + +SELECT 'customer' AS category, c.first FROM customers AS c UNION SELECT 'employee' AS category, e.first FROM employees AS e UNION SELECT 'vendor' AS category, v.first FROM vendors AS v UNION SELECT 'stuffedanimal' AS category, sa.saAnimalName FROM stuffedanimals AS sa; + +SELECT 'vendor' AS rowid, v.first FROM vendors AS v UNION SELECT 'employee' AS rowid, e.first FROM employees AS e; + +SELECT 'vendor' AS rowid, v.first FROM vendors AS v UNION SELECT 'employee' AS rowid, e.first FROM employees AS e UNION SELECT 'customer' AS rowid, c.first FROM customers AS c; + +SELECT 'vendor' AS rowid, v.first FROM vendors AS v UNION SELECT 'employee' AS rowid, e.first FROM employees AS e UNION SELECT 'customer' AS rowid, c.first FROM customers AS c ORDER BY rowid; + +SELECT 'vendor' AS rowid, v.first FROM vendors AS v UNION SELECT 'employee' AS rowid, e.first FROM employees AS e UNION SELECT 'customer' AS rowid, c.first FROM customers AS c ORDER BY first; + +SELECT 'vendor' AS rowid, v.first FROM vendors AS v UNION SELECT 'employee' AS rowid, e.first FROM employees AS e UNION SELECT 'customer' AS rowid, c.first FROM customers AS c ORDER BY rowid, first; + +SELECT 'vendor' AS rowid, v.first AS name FROM vendors AS v UNION SELECT 'employee' AS rowid, e.first AS name FROM employees AS e UNION SELECT 'customer' AS rowid, c.first AS name FROM customers AS c ORDER BY rowid, name; \ No newline at end of file diff --git a/000_temp/62-kelowna/05-subqueries/subqueries.sql b/000_temp/62-kelowna/05-subqueries/subqueries.sql new file mode 100644 index 00000000..fda030de --- /dev/null +++ b/000_temp/62-kelowna/05-subqueries/subqueries.sql @@ -0,0 +1,79 @@ +CREATE DATABASE acmesales; + +\c acmesales + +CREATE TABLE customers (cid INT PRIMARY KEY NOT NULL, cfirst TEXT); + +INSERT INTO customers VALUES (1,'Cory'), (2,'Casey'), (3,'Canard'), (4,'Cully'), (5,'Coffer'), (6,'Homey'); + +CREATE TABLE items (iid INT PRIMARY KEY NOT NULL, iitem TEXT); + +INSERT INTO items VALUES (1,'dog food'), (2,'tiramisu'), (3,'vino'), (4,'cheese'), (5,'chocolate'), (6,'gummy worms'), (7,'mango'); + +CREATE TABLE orders (oid INT PRIMARY KEY NOT NULL, cid INT REFERENCES customers(cid), odate TEXT); + +INSERT INTO orders VALUES (1,2,'tuesday'), (2,5,'wednesday'), (3,1,'thursday'), (4,3,'sunday'), (5,4,'saturday'), (6,5,'friday'); + +CREATE TABLE orderitems (oiid INT PRIMARY KEY NOT NULL, oid INT REFERENCES orders(oid), iid INT REFERENCES items(iid)); + +INSERT INTO orderitems VALUES (1,4,6), (2,4,5), (3,5,4), (4,6,3), (5,1,2), (6,2,1), (7,3,6), (8,4,5), (9,5,4), (10,6,3); + +SELECT c.cfirst, o.oid, o.odate, i.iitem FROM customers AS c JOIN orders AS o ON c.cid = o.cid JOIN orderitems AS oi ON o.oid = oi.oid JOIN items AS i ON oi.iid = i.iid; + +SELECT c.cfirst, o.oid, o.odate, i.iitem FROM customers AS c FULL JOIN orders AS o ON c.cid = o.cid FULL JOIN orderitems AS oi ON o.oid = oi.oid FULL JOIN items AS i ON oi.iid = i.iid; + +// SCALAR +// an expression that evaluates to one value +// aka, one column & one row = one field value + +SELECT o.oid, o.odate, (SELECT c.cfirst FROM customers AS c WHERE c.cid = o.cid) FROM orders AS o; + +// could have also done the above this way + +SELECT o.oid, o.odate, c.cfirst FROM customers AS c JOIN orders AS o ON c.cid = o.cid; + +// aggregate function COUNT + +SELECT COUNT(cfirst) AS ourcustomers FROM customers; + +SELECT c.cfirst, (SELECT COUNT(*) FROM orders AS o WHERE c.cid = o.cid) AS ordercount FROM customers AS c; + +// aggregate function MAX + +SELECT MAX(cid) AS highestcid FROM customers; + +SELECT MAX(odate) AS maxday FROM orders; + +SELECT c.cfirst, (SELECT MAX(o.oid) FROM orders AS o WHERE c.cid = o.cid) AS maxoid FROM customers AS c; + +// subquery as filters +// subquery with the WHERE clause +SELECT o.oid, o.odate, c.cfirst FROM customers AS c JOIN orders AS o ON c.cid = o.cid WHERE o.odate = (SELECT MAX(odate) FROM orders); + +// subquery as filters +// subquery with the IN keyword +SELECT o.oid, o.odate, c.cfirst FROM customers AS c JOIN orders AS o ON c.cid = o.cid WHERE o.odate IN (SELECT odate FROM orders WHERE odate LIKE '%u%'); + +// ALL, SOME, ANY keywords +SELECT o.oid, o.odate, c.cfirst FROM customers AS c JOIN orders AS o ON c.cid = o.cid WHERE o.odate = ANY (SELECT odate FROM orders WHERE odate LIKE '%u%'); + +SELECT o.oid, o.odate, c.cfirst FROM customers AS c JOIN orders AS o ON c.cid = o.cid WHERE o.odate = SOME (SELECT odate FROM orders WHERE odate LIKE '%u%'); + +SELECT o.oid, o.odate, c.cfirst FROM customers AS c JOIN orders AS o ON c.cid = o.cid WHERE o.odate = ALL (SELECT odate FROM orders WHERE odate LIKE '%u%'); + +SELECT o.oid, o.odate, c.cfirst FROM customers AS c JOIN orders AS o ON c.cid = o.cid WHERE o.odate = ALL (SELECT odate FROM orders WHERE odate LIKE 'thur%'); + +SELECT o.oid, o.odate, c.cfirst FROM customers AS c JOIN orders AS o ON c.cid = o.cid WHERE o.odate > ALL (SELECT odate FROM orders WHERE odate LIKE 'thur%'); + +// EXISTS +// I DO NOT KNOW HOW THIS WORKS +// MORE RESEARCH AND EXPERIMENTATION ARE NEEDED +SELECT c.cfirst, o.oid, o.odate, i.iitem FROM customers AS c JOIN orders AS o ON c.cid = o.cid JOIN orderitems AS oi ON o.oid = oi.oid JOIN items AS i ON oi.iid = i.iid; + +SELECT c.cfirst, o.oid, o.odate, i.iitem FROM customers AS c JOIN orders AS o ON c.cid = o.cid JOIN orderitems AS oi ON o.oid = oi.oid JOIN items AS i ON oi.iid = i.iid WHERE i.iitem = 'chocolate'; + +SELECT c.cfirst, o.oid, o.odate, i.iitem FROM customers AS c JOIN orders AS o ON c.cid = o.cid JOIN orderitems AS oi ON o.oid = oi.oid JOIN items AS i ON oi.iid = i.iid WHERE EXISTS (SELECT c.cfirst, o.oid, o.odate, i.iitem FROM customers AS c JOIN orders AS o ON c.cid = o.cid JOIN orderitems AS oi ON o.oid = oi.oid JOIN items AS i ON oi.iid = i.iid WHERE i.iitem = 'chocolate'); + + + + diff --git a/000_temp/62-kelowna/06-hollywood/subqueries.sql b/000_temp/62-kelowna/06-hollywood/subqueries.sql new file mode 100644 index 00000000..cd457ca0 --- /dev/null +++ b/000_temp/62-kelowna/06-hollywood/subqueries.sql @@ -0,0 +1,39 @@ +CREATE DATABASE hollywood; + +\l + +\c hollywood + +CREATE TABLE customers (cid INT PRIMARY KEY NOT NULL, cname TEXT); + +INSERT INTO customers VALUES (1,'Charlie'), (2,'Chris'), (3,'Christina'), (4,'Cassandra'), (5,'Cull'), (6,'Cabron'), (7,'Carla'), (8,'Caitland'), (9,'Colleen'), (10,'Christian'); + +CREATE TABLE movies (mid INT PRIMARY KEY NOT NULL, mname TEXT); + +INSERT INTO movies VALUES (1,'Jaws'), (2,'First Blood'), (3,'Rambo'), (4,'Terms of Endearment'), (5,'Heat'), (6,'The Lives of Others'), (7,'A Man Called Ove'), (8,'Disconnect'), (9,'Ex Machina'), (10,'Castle'); + +CREATE TABLE actors (aid INT PRIMARY KEY NOT NULL, aname TEXT); + +INSERT INTO actors VALUES (1,'Alfred'), (2,'Albert'), (3,'Angel'), (4,'Angelina'), (5,'Angie'), (6,'Agnes'), (7,'Amnia'), (8,'Allison'), (9,'Alejandro'), (10,'Aerial'); + +CREATE TABLE rentals (rid INT PRIMARY KEY NOT NULL, cid INT NOT NULL REFERENCES customers(cid), mid INT NOT NULL REFERENCES movies(mid)); + +INSERT INTO rentals VALUES (1,2,8),(2,8,10),(3,2,9),(4,6,1),(5,7,1),(6,5,2),(7,3,10),(8,9,5),(9,2,6),(10,8,7),(11,6,7),(12,9,9),(13,8,8),(14,8,9),(15,1,6),(16,2,9),(17,8,2),(18,10,7),(19,8,2),(20,6,7),(21,4,1),(22,5,4),(23,4,8),(24,9,5),(25,10,4),(26,8,2),(27,10,10),(28,1,6),(29,9,9),(30,4,6),(31,2,1),(32,6,7),(33,7,9),(34,2,3),(35,4,7),(36,4,7),(37,3,9),(38,8,5),(39,8,4),(40,7,1),(41,4,4),(42,8,4),(43,2,10),(44,4,4),(45,2,3),(46,9,7),(47,7,8),(48,1,4),(49,3,4),(50,6,9),(51,6,2),(52,6,8),(53,8,1),(54,1,6),(55,1,3),(56,9,4),(57,2,3),(58,5,8),(59,8,8),(60,2,5),(61,7,3),(62,2,10),(63,7,1),(64,4,7),(65,10,2),(66,3,6),(67,6,1),(68,8,10),(69,9,9),(70,5,4),(71,5,8),(72,3,3),(73,7,10),(74,1,7),(75,2,7),(76,1,2),(77,5,5),(78,6,4),(79,2,1),(80,3,9),(81,8,2),(82,9,5),(83,3,4),(84,3,9),(85,4,9),(86,7,1),(87,6,1),(88,5,3),(89,8,6),(90,2,10),(91,1,4),(92,1,10),(93,1,4),(94,1,5),(95,8,1),(96,6,3),(97,10,1),(98,9,7),(99,6,7),(100,1,7); + +CREATE TABLE castmembers (caid INT PRIMARY KEY NOT NULL, mid INT NOT NULL REFERENCES movies(mid), aid INT NOT NULL REFERENCES actors(aid)); + +INSERT INTO castmembers VALUES (1,2,8),(2,8,10),(3,2,9),(4,6,1),(5,7,1),(6,5,2),(7,3,10),(8,9,5),(9,2,6),(10,8,7),(11,6,7),(12,9,9),(13,8,8),(14,8,9),(15,1,6),(16,2,9),(17,8,2),(18,10,7),(19,8,2),(20,6,7),(21,4,1),(22,5,4),(23,4,8),(24,9,5),(25,10,4),(26,8,2),(27,10,10),(28,1,6),(29,9,9),(30,4,6),(31,2,1),(32,6,7),(33,7,9),(34,2,3),(35,4,7),(36,4,7),(37,3,9),(38,8,5),(39,8,4),(40,7,1),(41,4,4),(42,8,4),(43,2,10),(44,4,4),(45,2,3),(46,9,7),(47,7,8),(48,1,4),(49,3,4),(50,6,9),(51,6,2),(52,6,8),(53,8,1),(54,1,6),(55,1,3),(56,9,4),(57,2,3),(58,5,8),(59,8,8),(60,2,5),(61,7,3),(62,2,10),(63,7,1),(64,4,7),(65,10,2),(66,3,6),(67,6,1),(68,8,10),(69,9,9),(70,5,4),(71,5,8),(72,3,3),(73,7,10),(74,1,7),(75,2,7),(76,1,2),(77,5,5),(78,6,4),(79,2,1),(80,3,9),(81,8,2),(82,9,5),(83,3,4),(84,3,9),(85,4,9),(86,7,1),(87,6,1),(88,5,3),(89,8,6),(90,2,10),(91,1,4),(92,1,10),(93,1,4),(94,1,5),(95,8,1),(96,6,3),(97,10,1),(98,9,7),(99,6,7),(100,1,7); + + +SELECT c.cname, m.mname FROM customers AS c JOIN rentals AS r ON c.cid = r.cid JOIN movies AS m ON r.mid = m.mid; + +SELECT a.aname, m.mname FROM actors AS a JOIN castmembers AS cm ON a.aid = cm.aid JOIN movies AS m ON cm.mid = m.mid; + +INSERT INTO customers VALUES (101, 'Mike'), (102, 'Max'); + +INSERT INTO movies VALUES (101, 'Aliens'), (102, 'Ragoon'); + +INSERT INTO actors VALUES (101, 'Milfred'), (102, 'Martine'); + +SELECT c.cname, m.mname, a.aname FROM customers AS c FULL JOIN rentals AS r ON c.cid = r.cid FULL JOIN movies AS m ON r.mid = m.mid FULL JOIN castmembers AS cm ON m.mid = cm.mid FULL JOIN actors AS a ON cm.aid = a.aid; + diff --git a/000_temp/62-kelowna/07-sql-aggregate-funcs/agg.sql b/000_temp/62-kelowna/07-sql-aggregate-funcs/agg.sql new file mode 100644 index 00000000..95ac5eb3 --- /dev/null +++ b/000_temp/62-kelowna/07-sql-aggregate-funcs/agg.sql @@ -0,0 +1,85 @@ +/* COUNT */ + +/* from cooking database */ + +SELECT COUNT(recipetitle) AS totalRecipes FROM recipes; + +SELECT COUNT(DISTINCT recipetitle) AS totalDistRecipes FROM recipes; + +/* from hollywood database*/ +SELECT c.cname, m.mname, a.aname FROM ((((customers AS c JOIN rentals AS r ON c.cid = r.cid) JOIN movies AS m ON r.mid = m.mid) JOIN castmembers AS cm ON m.mid = cm.mid) JOIN actors AS a ON cm.aid = a.aid); + +SELECT c.cname, m.mname, a.aname FROM ((((customers AS c LEFT JOIN rentals AS r ON c.cid = r.cid) LEFT JOIN movies AS m ON r.mid = m.mid) LEFT JOIN castmembers AS cm ON m.mid = cm.mid) LEFT JOIN actors AS a ON cm.aid = a.aid); + +SELECT r.rid, m.mname FROM rentals AS r JOIN movies AS m ON r.mid = m.mid; + +SELECT r.rid, m.mname FROM rentals AS r RIGHT JOIN movies AS m ON r.mid = m.mid; + +SELECT cm.caid, a.aname FROM castmembers AS cm RIGHT JOIN actors AS a ON cm.aid = a.aid; + +SELECT cm.caid, a.aname FROM actors AS a LEFT JOIN castmembers AS cm ON a.aid = cm.aid; + +SELECT c.cname, m.mname, a.aname FROM ((((customers AS c FULL JOIN rentals AS r ON c.cid = r.cid) FULL JOIN movies AS m ON r.mid = m.mid) FULL JOIN castmembers AS cm ON m.mid = cm.mid) FULL JOIN actors AS a ON cm.aid = a.aid); + +SELECT COUNT(*) AS totalRentals FROM rentals; + +SELECT COUNT(cname) AS custs FROM customers; + +SELECT COUNT(DISTINCT cname) AS distinctCusts FROM customers; + + + +/* SUM */ + +DROP TABLE rentals; + +CREATE TABLE rentals (rid INT PRIMARY KEY NOT NULL, cid INT NOT NULL REFERENCES customers(cid), mid INT NOT NULL REFERENCES movies(mid), rAmount INT NOT NULL); + +https://play.golang.org/p/H7afRPh5bUd + +INSERT INTO rentals VALUES (1,2,8,5),(2,4,2,6),(3,8,1,4),(4,7,5,4),(5,11,10,6),(6,7,2,3),(7,9,7,3),(8,1,9,6),(9,10,8,5),(10,7,1,3),(11,1,9,5),(12,2,10,4),(13,2,2,3),(14,5,4,3),(15,6,4,6),(16,5,9,7),(17,6,4,5),(18,8,10,7),(19,8,6,6),(20,11,4,3),(21,5,1,3),(22,3,7,6),(23,2,3,6),(24,4,4,4),(25,6,9,5),(26,1,8,6),(27,7,1,6),(28,11,8,6),(29,11,10,6),(30,9,2,5),(31,4,7,4),(32,11,1,6),(33,4,4,3),(34,10,6,4),(35,1,8,5),(36,4,1,3),(37,7,3,6),(38,4,2,5),(39,11,8,5),(40,8,2,7),(41,4,3,4),(42,10,7,3),(43,1,7,7),(44,6,3,3),(45,10,1,5),(46,7,9,6),(47,1,4,7),(48,4,3,5),(49,7,10,3),(50,5,2,4),(51,7,2,7),(52,10,6,6),(53,4,1,5),(54,3,8,4),(55,7,5,5),(56,7,3,6),(57,8,9,4),(58,5,6,3),(59,8,3,5),(60,5,2,7),(61,3,4,3),(62,7,1,6),(63,1,5,5),(64,3,6,5),(65,10,1,6),(66,7,6,4),(67,11,7,7),(68,8,2,5),(69,5,1,7),(70,5,8,5),(71,8,2,6),(72,1,9,4),(73,5,8,5),(74,8,6,4),(75,11,6,5),(76,9,1,4),(77,11,3,3),(78,10,3,7),(79,5,1,3),(80,7,5,7),(81,10,2,4),(82,2,7,3),(83,3,8,6),(84,6,5,3),(85,1,6,7),(86,5,1,5),(87,9,1,7),(88,6,6,6),(89,7,1,7),(90,3,1,4),(91,11,3,7),(92,2,5,5),(93,4,4,4),(94,5,3,3),(95,8,2,5),(96,9,6,5),(97,10,3,7),(98,10,2,3),(99,9,4,6),(100,8,10,5); + +SELECT c.cname, m.mname, a.aname, r.rAmount FROM ((((customers AS c FULL JOIN rentals AS r ON c.cid = r.cid) FULL JOIN movies AS m ON r.mid = m.mid) FULL JOIN castmembers AS cm ON m.mid = cm.mid) FULL JOIN actors AS a ON cm.aid = a.aid); + +SELECT SUM(rAmount) AS totalRev FROM rentals; + +select c.cname, r.ramount from customers AS c JOIN rentals AS r ON c.cid = r.cid; + +select c.cname, r.rid, r.ramount from customers AS c JOIN rentals AS r ON c.cid = r.cid; + +select c.cname, r.rid, r.ramount from customers AS c FULL JOIN rentals AS r ON c.cid = r.cid; + +SELECT c.cid, c.cname, r.rid, r.ramount FROM customers AS c FULL JOIN rentals AS r ON c.cid = r.cid; + +SELECT c.cid, c.cname, r.rid, r.ramount, m.mname, a.aname FROM ((((customers AS c FULL JOIN rentals AS r ON c.cid = r.cid) FULL JOIN movies AS m ON r.mid = m.mid) FULL JOIN castmembers AS cm ON m.mid = cm.mid) FULL JOIN actors AS a ON cm.aid = a.aid); + +SELECT c.cid, c.cname, SUM(r.ramount) AS bigSpend FROM customers AS c FULL JOIN rentals AS r ON c.cid = r.cid GROUP BY c.cid; + +SELECT c.cid, c.cname, SUM(r.ramount) AS bigSpend FROM customers AS c FULL JOIN rentals AS r ON c.cid = r.cid GROUP BY c.cid ORDER BY bigSpend DESC; + + + +/* AVG */ + +SELECT AVG(ramount) FROM rentals; + +SELECT c.cid, c.cname, AVG(r.ramount) AS bigSpend FROM customers AS c FULL JOIN rentals AS r ON c.cid = r.cid GROUP BY c.cid; + + + +/* MAX */ +SELECT MAX(ramount) FROM rentals; + +SELECT c.cid, c.cname, MAX(r.ramount) AS bigSpend FROM customers AS c FULL JOIN rentals AS r ON c.cid = r.cid GROUP BY c.cid; + + + +/* MIN */ +SELECT MIN(ramount) FROM rentals; + +SELECT c.cid, c.cname, MIN(r.ramount) AS bigSpend FROM customers AS c FULL JOIN rentals AS r ON c.cid = r.cid GROUP BY c.cid; + + +/* AFTER CLASS */ + +SELECT cu.cname AS firstName FROM customers AS cu; \ No newline at end of file diff --git a/000_temp/62-kelowna/08-sql-group/agg.sql b/000_temp/62-kelowna/08-sql-group/agg.sql new file mode 100644 index 00000000..86c51d35 --- /dev/null +++ b/000_temp/62-kelowna/08-sql-group/agg.sql @@ -0,0 +1,86 @@ +CREATE DATABASE entertainers; + +\l + +\c entertainers + +CREATE TABLE entertainers (eid INT PRIMARY KEY NOT NULL, ename TEXT NOT NULL); + +\d + +\d entertainers + +CREATE TABLE engagements (enID INT PRIMARY KEY NOT NULL, eid INT NOT NULL REFERENCES entertainers(eid), encontractprice INT NOT NULL); + +INSERT INTO entertainers VALUES (1, 'WOOKIE-WOOKIE'), (2, 'HodgePodge'), (3, 'ScarlettLetters'), (4, 'TomorrowsSun'), (5, 'WhereWithAll'), (6, 'CowboyFutures'), (7, 'DesperateTortillas'), (8, 'CaldenarFlippers'), (9, 'LaughingJackals'), (10, 'CareeningForthright'); + + +generate values +https://play.golang.org/p/iET0hmFrcgf + +INSERT INTO engagements VALUES (1,2,9888),(2,8,6060),(3,2,3319),(4,6,4541),(5,7,5301),(6,5,10512),(7,3,7090),(8,9,5275),(9,2,3446),(10,8,11107),(11,6,7467),(12,9,8259),(13,8,11948),(14,8,4889),(15,1,5016),(16,2,2409),(17,8,8832),(18,10,7357),(19,8,2632),(20,6,7027),(21,4,5091),(22,5,2564),(23,4,6148),(24,9,6325),(25,10,3354),(26,8,5722),(27,10,4200),(28,1,10706),(29,9,6539),(30,4,11356),(31,2,10511),(32,6,2157),(33,7,11829),(34,2,9203),(35,4,7747),(36,4,6377),(37,3,11719),(38,8,7095),(39,8,9464),(40,7,8421),(41,4,2954),(42,8,5134),(43,2,2060),(44,4,10644),(45,2,4003),(46,9,11337),(47,7,11108),(48,1,8504),(49,3,11844),(50,6,3599),(51,6,3352),(52,6,11758),(53,8,10011),(54,1,7286),(55,1,5633),(56,9,10554),(57,2,10583),(58,5,3298),(59,8,8138),(60,2,7895),(61,7,7803),(62,2,4080),(63,7,3271),(64,4,5087),(65,10,10982),(66,3,9176),(67,6,7711),(68,8,5750),(69,9,4819),(70,5,9904),(71,5,6548),(72,3,3533),(73,7,9840),(74,1,7787),(75,2,10077),(76,1,9352),(77,5,2365),(78,6,11184),(79,2,2091),(80,3,4259),(81,8,5232),(82,9,10155),(83,3,3224),(84,3,6209),(85,4,3969),(86,7,5711),(87,6,2441),(88,5,5163),(89,8,6416),(90,2,5040),(91,1,11514),(92,1,3360),(93,1,2784),(94,1,4985),(95,8,10011),(96,6,6163),(97,10,9921),(98,9,8757),(99,6,10667),(100,1,11457); + +SELECT e.ename, en.encontractprice FROM entertainers AS e INNER JOIN engagements AS en ON e.eid = en.eid; + +SELECT e.ename, en.encontractprice FROM entertainers AS e JOIN engagements AS en ON e.eid = en.eid; + +INSERT INTO entertainers VALUES (11, 'SomebodyNobodyLoves'); + +SELECT e.ename, en.encontractprice FROM entertainers AS e LEFT JOIN engagements AS en ON e.eid = en.eid; + +SELECT e.ename, en.encontractprice FROM entertainers AS e FULL JOIN engagements AS en ON e.eid = en.eid; + +SELECT COUNT(encontractprice) as TotalEngagements FROM engagements; +SELECT SUM(encontractprice) as TotalRevenue FROM engagements; +SELECT MAX(encontractprice) as MaxContractPrice FROM engagements; +SELECT MIN(encontractprice) as MinContractPrice FROM engagements; +SELECT AVG(encontractprice) as AvgContractPrice FROM engagements; + +SELECT e.ename, MAX(en.encontractprice) as MaxContractPrice FROM entertainers AS e JOIN engagements AS en ON e.eid = en.eid GROUP BY e.ename; + +SELECT e.ename, MIN(en.encontractprice) as MinContractPrice FROM entertainers AS e JOIN engagements AS en ON e.eid = en.eid GROUP BY e.ename ORDER BY MinContractPrice; + +SELECT e.ename, AVG(en.encontractprice) as AvgContractPrice FROM entertainers AS e JOIN engagements AS en ON e.eid = en.eid GROUP BY e.ename ORDER BY AvgContractPrice; + +SELECT e.ename, SUM(en.encontractprice) as SumContractPrice FROM entertainers AS e JOIN engagements AS en ON e.eid = en.eid GROUP BY e.ename ORDER BY SumContractPrice; + +SELECT e.ename, COUNT(en.encontractprice) as CountContractPrice FROM entertainers AS e JOIN engagements AS en ON e.eid = en.eid GROUP BY e.ename ORDER BY CountContractPrice; + +SELECT e.ename, COUNT(en.encontractprice) AS NumContracts, SUM(en.encontractprice) AS TotalRevenue, MIN(en.encontractprice) AS MinRev, MAX(en.encontractprice) AS MaxRev, AVG(en.encontractprice) AS AvgRev FROM entertainers AS e JOIN engagements AS en ON e.eid = en.eid GROUP BY e.ename ORDER BY NumContracts; + +SELECT e.ename, COUNT(en.encontractprice) AS NumContracts, SUM(en.encontractprice) AS TotalRevenue, MIN(en.encontractprice) AS MinRev, MAX(en.encontractprice) AS MaxRev, AVG(en.encontractprice) AS AvgRev FROM entertainers AS e LEFT JOIN engagements AS en ON e.eid = en.eid GROUP BY e.ename ORDER BY NumContracts; + +SELECT e.ename, COUNT(*) AS NumContracts, SUM(en.encontractprice) AS TotalRevenue, MIN(en.encontractprice) AS MinRev, MAX(en.encontractprice) AS MaxRev, AVG(en.encontractprice) AS AvgRev FROM entertainers AS e LEFT JOIN engagements AS en ON e.eid = en.eid GROUP BY e.ename ORDER BY NumContracts; + + + +/* multiple fields in group by*/ + +DROP TABLE engagements; + +DROP TABLE entertainers; + +CREATE TABLE entertainers (eid INT PRIMARY KEY NOT NULL, ename TEXT NOT NULL, ecity TEXT NOT NULL); + +INSERT INTO entertainers VALUES (1, 'WOOKIE-WOOKIE', 'Paris'), (2, 'HodgePodge', 'Paris'), (3, 'ScarlettLetters', 'Paris'), (4, 'TomorrowsSun', 'Hollywood'), (5, 'WhereWithAll', 'Hollywood'), (6, 'CowboyFutures', 'Hollywood'), (7, 'DesperateTortillas', 'New York'), (8, 'CaldenarFlippers', 'New York'), (9, 'LaughingJackals', 'San Francisco'), (10, 'CareeningForthright', 'San Francisco'); + +CREATE TABLE engagements (enID INT PRIMARY KEY NOT NULL, eid INT NOT NULL REFERENCES entertainers(eid), encontractprice INT NOT NULL); + +generate values +https://play.golang.org/p/iET0hmFrcgf + +INSERT INTO engagements VALUES (1,2,9888),(2,8,6060),(3,2,3319),(4,6,4541),(5,7,5301),(6,5,10512),(7,3,7090),(8,9,5275),(9,2,3446),(10,8,11107),(11,6,7467),(12,9,8259),(13,8,11948),(14,8,4889),(15,1,5016),(16,2,2409),(17,8,8832),(18,10,7357),(19,8,2632),(20,6,7027),(21,4,5091),(22,5,2564),(23,4,6148),(24,9,6325),(25,10,3354),(26,8,5722),(27,10,4200),(28,1,10706),(29,9,6539),(30,4,11356),(31,2,10511),(32,6,2157),(33,7,11829),(34,2,9203),(35,4,7747),(36,4,6377),(37,3,11719),(38,8,7095),(39,8,9464),(40,7,8421),(41,4,2954),(42,8,5134),(43,2,2060),(44,4,10644),(45,2,4003),(46,9,11337),(47,7,11108),(48,1,8504),(49,3,11844),(50,6,3599),(51,6,3352),(52,6,11758),(53,8,10011),(54,1,7286),(55,1,5633),(56,9,10554),(57,2,10583),(58,5,3298),(59,8,8138),(60,2,7895),(61,7,7803),(62,2,4080),(63,7,3271),(64,4,5087),(65,10,10982),(66,3,9176),(67,6,7711),(68,8,5750),(69,9,4819),(70,5,9904),(71,5,6548),(72,3,3533),(73,7,9840),(74,1,7787),(75,2,10077),(76,1,9352),(77,5,2365),(78,6,11184),(79,2,2091),(80,3,4259),(81,8,5232),(82,9,10155),(83,3,3224),(84,3,6209),(85,4,3969),(86,7,5711),(87,6,2441),(88,5,5163),(89,8,6416),(90,2,5040),(91,1,11514),(92,1,3360),(93,1,2784),(94,1,4985),(95,8,10011),(96,6,6163),(97,10,9921),(98,9,8757),(99,6,10667),(100,1,11457); + +SELECT e.ecity, e.ename, COUNT(*) AS NumContracts, SUM(en.encontractprice) AS TotalRevenue, MIN(en.encontractprice) AS MinRev, MAX(en.encontractprice) AS MaxRev, AVG(en.encontractprice) AS AvgRev FROM entertainers AS e LEFT JOIN engagements AS en ON e.eid = en.eid GROUP BY e.ecity, e.ename ORDER BY e.ecity, NumContracts; + +/* simulating DISTINCT */ + +SELECT ecity FROM entertainers; + +SELECT DISTINCT(ecity) FROM entertainers; + +SELECT ecity FROM entertainers GROUP BY ecity; + +SELECT ecity, COUNT(*) AS bandspercity FROM entertainers GROUP BY ecity; + + diff --git a/000_temp/63-fall-2018/001-hello-world/hello.go b/000_temp/63-fall-2018/001-hello-world/hello.go new file mode 100644 index 00000000..d2c4e91e --- /dev/null +++ b/000_temp/63-fall-2018/001-hello-world/hello.go @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main() { + fmt.Println("Hello world") +} diff --git a/000_temp/63-fall-2018/002-hello-world/hello.go b/000_temp/63-fall-2018/002-hello-world/hello.go new file mode 100644 index 00000000..24dcac87 --- /dev/null +++ b/000_temp/63-fall-2018/002-hello-world/hello.go @@ -0,0 +1,9 @@ +package main + +import ( + "fmt" +) + +func main() { + fmt.Println("Hello world") +} diff --git a/000_temp/63-fall-2018/003-func/func.go b/000_temp/63-fall-2018/003-func/func.go new file mode 100644 index 00000000..d267b4f3 --- /dev/null +++ b/000_temp/63-fall-2018/003-func/func.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" +) + +func main() { + fmt.Println("Hello world") + secondStatement() + finalStat() +} + +// func receiver identifier(parameters) returns {code} + +func secondStatement() { + fmt.Println("Here is my second statement") +} + +func finalStat() { + fmt.Println("about to exit") +} diff --git a/000_temp/63-fall-2018/004-variables/main.go b/000_temp/63-fall-2018/004-variables/main.go new file mode 100644 index 00000000..12ea85a5 --- /dev/null +++ b/000_temp/63-fall-2018/004-variables/main.go @@ -0,0 +1,20 @@ +package main + +import ( + "fmt" +) + +func main() { + fname := "James" + lname := "Bond" + fmt.Println(fname, lname) + girlfriend := "Miss Moneypenny" + fmt.Println(girlfriend) +} + +/* +declare, assign, initialize +DECLARE a VARIABLE stores a VALUE of a certain TYPE +we ASSIGN a VALUE of a certain TYPE to a VARIABLE +declare & assign ==> initialize +*/ diff --git a/000_temp/63-fall-2018/005-variables/main.go b/000_temp/63-fall-2018/005-variables/main.go new file mode 100644 index 00000000..d25fc1d4 --- /dev/null +++ b/000_temp/63-fall-2018/005-variables/main.go @@ -0,0 +1,18 @@ +package main + +import ( + "fmt" +) + +var x int +var y string + +func main() { + fmt.Println(x) + fmt.Println("|", y, "|") +} + +// zero value +// if you declare a VAR of a certain TYPE +// and do not ASSIGN a VALUE to that VAR +// a ZERO VALUE will be ASSIGNED to that VAR diff --git a/000_temp/63-fall-2018/006-variables/main.go b/000_temp/63-fall-2018/006-variables/main.go new file mode 100644 index 00000000..20e52d13 --- /dev/null +++ b/000_temp/63-fall-2018/006-variables/main.go @@ -0,0 +1,13 @@ +package main + +import ( + "fmt" +) + +var x = 42 +var y = "M" + +func main() { + fmt.Println(x) + fmt.Println(y) +} diff --git a/000_temp/63-fall-2018/007-params/main.go b/000_temp/63-fall-2018/007-params/main.go new file mode 100644 index 00000000..257099fe --- /dev/null +++ b/000_temp/63-fall-2018/007-params/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "fmt" +) + +func main() { + fmt.Println("Begin") + + // pass in an ARGUMENT to the func when you CALL IT + foo("James Bond") + + x := "Miss Moneypenny" + // pass in an ARGUMENT to the func when you CALL IT + foo(x) + + n, _ := fmt.Println("1") + + fmt.Println("number of bytes written", n) +} + +// foo takes a VALUE of TYPE string +// we could also say: +// foo has a parameter which is a VALUE of TYPE string +// funcs may be defined with PARAMETER(S) +func foo(name string) { + fmt.Println("Hello", name) +} diff --git a/000_temp/63-fall-2018/008-review-var-type-value/main.go b/000_temp/63-fall-2018/008-review-var-type-value/main.go new file mode 100644 index 00000000..d8b22e01 --- /dev/null +++ b/000_temp/63-fall-2018/008-review-var-type-value/main.go @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" +) + +// DECLARE a variable to be of a certain TYPE +// we can only ever store VALUES of that TYPE in that VARIABLE +// the VARIABLE has an IDENTIFIER +// STATIC programming language +// IDIOMATIC - idioms are patterns of speech +// COMPILER will check to make sure our code is IDIOMATIC + +var x int + +func main() { + x = 7 + fmt.Println(x) +} diff --git a/000_temp/63-fall-2018/009-review-func/main.go b/000_temp/63-fall-2018/009-review-func/main.go new file mode 100644 index 00000000..8d9f014a --- /dev/null +++ b/000_temp/63-fall-2018/009-review-func/main.go @@ -0,0 +1,31 @@ +package main + +import "fmt" + +func main() { + fmt.Println("This is the entry point beginning of the programming") + + foo() + + // call bar with ARGUMENTS + a, b := bar("James Bond", 32) + fmt.Println(a) + fmt.Println("In 10 years Bond will be", b, "years old.") + + fmt.Println(`Program "about" to exit`) +} + +func foo() { + fmt.Println("Foo is here") +} + +// define bar with PARAMETERS +// EXPRESSIONS evaluate to some VALUE, eg, y + 10 +// STATEMENT is a line of code to be executed +func bar(x string, y int) (string, int) { + return fmt.Sprint(x, " is here and he is ", y, " years old"), y + 10 +} + +// we will pass ARGUMENTS in to a function that has been defined with PARAMETERS + +// func receiver identifier(parameters) return(s) {code} diff --git a/000_temp/63-fall-2018/010-hands-on/01/main.go b/000_temp/63-fall-2018/010-hands-on/01/main.go new file mode 100644 index 00000000..1e763f95 --- /dev/null +++ b/000_temp/63-fall-2018/010-hands-on/01/main.go @@ -0,0 +1,10 @@ +package main + +import "fmt" + +func main() { + x := 40 + y := 2 + z := x * y + fmt.Println(z) +} diff --git a/000_temp/63-fall-2018/010-hands-on/02/main.go b/000_temp/63-fall-2018/010-hands-on/02/main.go new file mode 100644 index 00000000..0e8d297b --- /dev/null +++ b/000_temp/63-fall-2018/010-hands-on/02/main.go @@ -0,0 +1,16 @@ +package main + +import "fmt" + +func main() { + foo() +} + + +// func receiver identifier(parameters) return(s) {code} + +func foo() { + x := "James Bond" + y := 32 + fmt.Println(x, y) +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/010-hands-on/03/main.go b/000_temp/63-fall-2018/010-hands-on/03/main.go new file mode 100644 index 00000000..e15ff88c --- /dev/null +++ b/000_temp/63-fall-2018/010-hands-on/03/main.go @@ -0,0 +1,21 @@ +package main + +import "fmt" + +func main() { + + // when we call a func, we pass in ARGUMENTS + foo("Todd", 42) + foo("James", 32) + foo("Jenny", 27) + foo("Cole", 19) +} + + +// func +// modularize our code and DRY (don't repeat yourself) +// funcs are defined with parameters +// parameters specify a VALUE of a certain TYPE to be passed in when the func is called +func foo(x string, y int) { + fmt.Println(x, y) +} diff --git a/000_temp/63-fall-2018/010-hands-on/04/main.go b/000_temp/63-fall-2018/010-hands-on/04/main.go new file mode 100644 index 00000000..9d790777 --- /dev/null +++ b/000_temp/63-fall-2018/010-hands-on/04/main.go @@ -0,0 +1,14 @@ +package main + +import "fmt" + +func main() { + z := foo(40, 45) + fmt.Println(z) +} + + +// func receiver identifier(parameters) returns {code} +func foo(x int, y int) int { + return x * y +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/010-hands-on/05/main.go b/000_temp/63-fall-2018/010-hands-on/05/main.go new file mode 100644 index 00000000..53cb74c7 --- /dev/null +++ b/000_temp/63-fall-2018/010-hands-on/05/main.go @@ -0,0 +1,15 @@ +package main + +import "fmt" + +func main() { + x := foo("Todd") + fmt.Println(x) +} + + +// func receiver identifier(parameters) returns {code} +func foo(s string) string { + //return fmt.Sprint("Hello ", s, "!") + return "Hello " + s + "!" +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/011-loops/main.go b/000_temp/63-fall-2018/011-loops/main.go new file mode 100644 index 00000000..330652c9 --- /dev/null +++ b/000_temp/63-fall-2018/011-loops/main.go @@ -0,0 +1,15 @@ +package main + +import "fmt" + +func main() { + foo() +} + + +// func receiver identifier(parameters) returns {code} +func foo() { + for i := 0; i <= 100; i++ { + fmt.Println(i) + } +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/012-conditional/main.go b/000_temp/63-fall-2018/012-conditional/main.go new file mode 100644 index 00000000..c7f06600 --- /dev/null +++ b/000_temp/63-fall-2018/012-conditional/main.go @@ -0,0 +1,17 @@ +package main + +import "fmt" + +func main() { + foo() +} + + +// func receiver identifier(parameters) returns {code} +func foo() { + for i := 0; i <= 100; i++ { + if i % 2 == 0 { + fmt.Println(i) + } + } +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/013-slice/main.go b/000_temp/63-fall-2018/013-slice/main.go new file mode 100644 index 00000000..bc594823 --- /dev/null +++ b/000_temp/63-fall-2018/013-slice/main.go @@ -0,0 +1,20 @@ +package main + +import "fmt" + +func main() { + xi := []int{2,3,4,5,6,7,8} + fmt.Println(xi) + + for i, v := range xi { + fmt.Println(i, v) + } + + xs := []string{"James", "Jenny", "M", "Q"} + + fmt.Println(xs) + + for i, v := range xs { + fmt.Println(i, v) + } +} diff --git a/000_temp/63-fall-2018/014-maps/main.go b/000_temp/63-fall-2018/014-maps/main.go new file mode 100644 index 00000000..5d2ab53f --- /dev/null +++ b/000_temp/63-fall-2018/014-maps/main.go @@ -0,0 +1,12 @@ +package main + +import "fmt" + +func main() { + m := map[string]int{"James":32, "Jenny":27,} + fmt.Println(m) + + for k, v := range m { + fmt.Println(k, v) + } +} diff --git a/000_temp/63-fall-2018/015-struct/main.go b/000_temp/63-fall-2018/015-struct/main.go new file mode 100644 index 00000000..8fcf44d6 --- /dev/null +++ b/000_temp/63-fall-2018/015-struct/main.go @@ -0,0 +1,45 @@ +package main + +import "fmt" + +type person struct { + first string + last string + age int + sayings []string +} + +func main() { + p1 := person{ + first: "James", + last: "Bond", + age: 32, + sayings: []string{"Shaken, not stirred", "Bond, James Bond",}, + } + fmt.Println(p1) + + p2 := person{ + first: "Jenny", + last: "Moneypenny", + age: 27, + sayings: []string{"Danger knows no gender", "A woman's place is in control",}, + } + fmt.Println(p2) + + xp := []person{p1, p2} + + fmt.Println("---------") + for i, v := range xp { + fmt.Println(i, v, v.first) + for j, w := range v.sayings { + fmt.Println(j, w) + } + } + fmt.Println("---------") + + m := map[string]person{"James":p1, "Jenny":p2,} + + for k, p := range m { + fmt.Println(k, p) + } +} diff --git a/000_temp/63-fall-2018/016-fun-with-text/main.go b/000_temp/63-fall-2018/016-fun-with-text/main.go new file mode 100644 index 00000000..bc445452 --- /dev/null +++ b/000_temp/63-fall-2018/016-fun-with-text/main.go @@ -0,0 +1,18 @@ +package main + +import "fmt" + +func main() { + x := "ABCDE" + fmt.Println(x) + + fmt.Printf("%T\n", x) + + xr := []rune(x) + fmt.Println(xr) + + for _, v := range xr { + fmt.Printf("%d - %b - %#X\n", v, v, v) + } + +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/017-slice/main.go b/000_temp/63-fall-2018/017-slice/main.go new file mode 100644 index 00000000..ea59942c --- /dev/null +++ b/000_temp/63-fall-2018/017-slice/main.go @@ -0,0 +1,25 @@ +package main + +import "fmt" + +func main() { + x := 42 + y := 43 + xi := []int{x, y} + + fmt.Printf("%T\n", x) + fmt.Printf("%T\n", y) + fmt.Printf("%T\n", xi) + + fmt.Println(xi) + + a := "James" + b := "Jenny" + xs := []string{a, b} + + fmt.Printf("%T\n", a) + fmt.Printf("%T\n", b) + fmt.Printf("%T\n", xs) + fmt.Println(xs) + +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/018-map/main.go b/000_temp/63-fall-2018/018-map/main.go new file mode 100644 index 00000000..c84807fd --- /dev/null +++ b/000_temp/63-fall-2018/018-map/main.go @@ -0,0 +1,11 @@ +package main + +import "fmt" + +func main() { + m := map[string]int{"James":7, "Jenny":8,} + fmt.Printf("%T\n", m) + fmt.Println(m) + + fmt.Println(m["James"]) +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/019-struct/01/main.go b/000_temp/63-fall-2018/019-struct/01/main.go new file mode 100644 index 00000000..d32ae55d --- /dev/null +++ b/000_temp/63-fall-2018/019-struct/01/main.go @@ -0,0 +1,16 @@ +package _1 + +import "fmt" + +type hotdog int +var x hotdog + +func main() { + x = 7 + fmt.Printf("%T\n", x) + fmt.Println(x) + y := int(x) + fmt.Printf("%T\n", y) + fmt.Println(y) + +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/019-struct/02/main.go b/000_temp/63-fall-2018/019-struct/02/main.go new file mode 100644 index 00000000..7cb3b388 --- /dev/null +++ b/000_temp/63-fall-2018/019-struct/02/main.go @@ -0,0 +1,18 @@ +package main + +import "fmt" + +type person struct { + first string + license int + sayings []string +} + +func main() { + p1 := person{ + first: "James", + license: 007, + sayings: []string{"Shaken, not stirred", "Bond, James Bond",}, + } + fmt.Println(p1) +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/019-struct/03/main.go b/000_temp/63-fall-2018/019-struct/03/main.go new file mode 100644 index 00000000..61de635f --- /dev/null +++ b/000_temp/63-fall-2018/019-struct/03/main.go @@ -0,0 +1,31 @@ +package main + +import "fmt" + +type person struct { + first string + license int + sayings []string +} + +func main() { + p1 := person{ + first: "James", + license: 7, + sayings: []string{"Shaken, not stirred", "Bond, James Bond",}, + } + fmt.Println(p1) + + p2 := person{ + first: "Jenny", + license: 8, + sayings: []string{"When Bond can't handle it, call me", "I will always love Bond",}, + } + fmt.Println(p2) + + xp := []person{p1, p2} + fmt.Println(xp) + + mp := map[string]person{"Mr":p1, "Ms":p2,} + fmt.Println(mp) +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/020-looping/01/main.go b/000_temp/63-fall-2018/020-looping/01/main.go new file mode 100644 index 00000000..b73205fc --- /dev/null +++ b/000_temp/63-fall-2018/020-looping/01/main.go @@ -0,0 +1,25 @@ +package main + +import "fmt" + +func main() { + + /* + for { + fmt.Println("hello") + } + */ + + // for init; cond; incrementor {code} + for i := 0; i <= 10; i++ { + fmt.Println(i) + } + + for i := 0; ; i++ { + fmt.Println(i, i) + if i == 11 { + break + } + } + +} diff --git a/000_temp/63-fall-2018/020-looping/02/main.go b/000_temp/63-fall-2018/020-looping/02/main.go new file mode 100644 index 00000000..1fb0b8ee --- /dev/null +++ b/000_temp/63-fall-2018/020-looping/02/main.go @@ -0,0 +1,33 @@ +package main + +import "fmt" + +func main() { + xi := []int{2, 3, 4, 5, 7, 9, 42} + + for i, v := range xi { + fmt.Println(i, v) + } + + for idx := range xi { + fmt.Println(idx) + } + + for _, val := range xi { + fmt.Println("-",val) + } + + m := map[string]int{"James":32, "Jenny":27,} + + for k, v := range m { + fmt.Println(k, v) + } + + for key := range m { + fmt.Println(key) + } + + for _, value := range m { + fmt.Println("-", value) + } +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/021-receiver/01/main.go b/000_temp/63-fall-2018/021-receiver/01/main.go new file mode 100644 index 00000000..608fdde7 --- /dev/null +++ b/000_temp/63-fall-2018/021-receiver/01/main.go @@ -0,0 +1,42 @@ +package main + +import "fmt" + +type person struct { + first string + last string + saying string +} + +// func (receiver) identifier(parameters) (returns) {code} + +func (p person) speak() { + fmt.Println(p.first, "says", p.saying) +} + +func main() { + p1 := person{ + first: "James", + last: "Bond", + saying: "Shaken, not stirred.", + } + + p2 := person{ + first: "Jenny", + last: "Moneypenny", + saying: "Helllllllo, James.", + } + + fmt.Println(p1) + fmt.Println(p2) + + fmt.Println("---------") + + fmt.Println(p1.first, "says", p1.saying) + fmt.Println(p2.first, "says", p2.saying) + + fmt.Println("---------") + + p1.speak() + p2.speak() +} diff --git a/000_temp/63-fall-2018/022-interfaces/01/main.go b/000_temp/63-fall-2018/022-interfaces/01/main.go new file mode 100644 index 00000000..e194fb3a --- /dev/null +++ b/000_temp/63-fall-2018/022-interfaces/01/main.go @@ -0,0 +1,71 @@ +package main + +import "fmt" + +type person struct { + first string + last string + saying string +} + +func (p person) speak() { + fmt.Println(p.first, "says", p.saying) +} + +func (sa secretAgent) speak() { + fmt.Println(sa.first, "says wackabacka haha", sa.saying) +} + +type secretAgent struct { + person + ltk bool +} +type human interface { + speak() +} + +func foo(h human) { + h.speak() +} + +func main() { + p1 := person{ + first: "James", + last: "Bond", + saying: "Shaken, not stirred.", + } + + p2 := person{ + first: "Jenny", + last: "Moneypenny", + saying: "Helllllllo, James.", + } + + sa1 := secretAgent{ + person: person{ + first: "Ian", + last: "Fleming", + saying: "The books were based on real stories", + }, + ltk: true, + } + + fmt.Println(p1) + fmt.Println(p2) + + fmt.Println("---------") + + fmt.Println(p1.first, "says", p1.saying) + fmt.Println(p2.first, "says", p2.saying) + + fmt.Println("---------") + + p1.speak() + p2.speak() + + fmt.Println("--------- interface") + + foo(p1) + foo(p2) + foo(sa1) +} diff --git a/000_temp/63-fall-2018/022-interfaces/02/main.go b/000_temp/63-fall-2018/022-interfaces/02/main.go new file mode 100644 index 00000000..e194fb3a --- /dev/null +++ b/000_temp/63-fall-2018/022-interfaces/02/main.go @@ -0,0 +1,71 @@ +package main + +import "fmt" + +type person struct { + first string + last string + saying string +} + +func (p person) speak() { + fmt.Println(p.first, "says", p.saying) +} + +func (sa secretAgent) speak() { + fmt.Println(sa.first, "says wackabacka haha", sa.saying) +} + +type secretAgent struct { + person + ltk bool +} +type human interface { + speak() +} + +func foo(h human) { + h.speak() +} + +func main() { + p1 := person{ + first: "James", + last: "Bond", + saying: "Shaken, not stirred.", + } + + p2 := person{ + first: "Jenny", + last: "Moneypenny", + saying: "Helllllllo, James.", + } + + sa1 := secretAgent{ + person: person{ + first: "Ian", + last: "Fleming", + saying: "The books were based on real stories", + }, + ltk: true, + } + + fmt.Println(p1) + fmt.Println(p2) + + fmt.Println("---------") + + fmt.Println(p1.first, "says", p1.saying) + fmt.Println(p2.first, "says", p2.saying) + + fmt.Println("---------") + + p1.speak() + p2.speak() + + fmt.Println("--------- interface") + + foo(p1) + foo(p2) + foo(sa1) +} diff --git a/000_temp/63-fall-2018/023-review/main.go b/000_temp/63-fall-2018/023-review/main.go new file mode 100644 index 00000000..9f33dc01 --- /dev/null +++ b/000_temp/63-fall-2018/023-review/main.go @@ -0,0 +1,124 @@ +package main + +import "fmt" + +var c int +var d = 43 + +const z = 142 + +type person struct { + first string + age int + saying string +} + +// func receiver identifier(params) returns {code} + +func (p person) speak() { + fmt.Println(p.first, "says", p.saying) +} + +type secretagent struct { + person + ltk bool +} + +func (sa secretagent) speak() { + fmt.Println(sa.first, "says even more", sa.saying) +} + +type human interface { + speak() +} + +func foo(h human) { + h.speak() +} + +func main() { + a := "James" + fmt.Println(a) + fmt.Printf("%T\n", a) + + b := fmt.Sprint("Hello", a) + fmt.Println(b) + + c = 42 + fmt.Println("c:", c) + + d = 43 + fmt.Println("d:", d) + fmt.Printf("d type: %T\n", d) + + // slice AGGREGATE or COMPOSITE data structure + + ee := []int{2,3,4,7,9,} + fmt.Println(ee) + + // it was going SEQUENCE + // now it's going ITERATIVE + + for i, v := range ee { + fmt.Println(i, v) + // conditional logic + if i == 3 { + fmt.Println("HEY, i is EQUAL TO", i) + } + } + + + // map AGGREGATE or COMPOSITE data structure + f := map[string]int{"James":32, "Jenny":27,} + fmt.Println(f) + + for k, v := range f { + fmt.Println(k, v) + } + + // struct AGGREGATE or COMPOSITE data structure + p1 := person{ + first: "James", + age: 32, + saying: "shaken, not stirred", + } + + p2 := person { + first: "Jenny", + age: 27, + saying: "nobody does it better", + } + + xp := []person{p1, p2} + fmt.Println(xp) + for i2, v2 := range xp { + fmt.Println(i2, v2) + } + + // loop init, cond, post + for j := 0; j < 10; j++ { + fmt.Println(j) + } + + sa1 := secretagent{ + person: person{ + first: "Jack", + age: 29, + saying: "Blahb blahblabhalbhablhab", + }, + ltk: true, + } + fmt.Println(sa1) + fmt.Println(sa1.first) + fmt.Println(sa1.person.first) + + p1.speak() + p2.speak() + sa1.speak() + fmt.Println("--") + foo(p1) + foo(p2) + foo(sa1) + + fmt.Println(z) +} diff --git a/000_temp/63-fall-2018/024-unfurling-slice/main.go b/000_temp/63-fall-2018/024-unfurling-slice/main.go new file mode 100644 index 00000000..5cbce4f9 --- /dev/null +++ b/000_temp/63-fall-2018/024-unfurling-slice/main.go @@ -0,0 +1,13 @@ +package main + +import "fmt" + +func main() { + xi := []int{1,2,4,5,7,8,9,} + foo(xi...) +} + +func foo(i ...int) { + fmt.Println(i) + fmt.Printf("%T\n", i) +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/025-defer/main.go b/000_temp/63-fall-2018/025-defer/main.go new file mode 100644 index 00000000..26cd71ca --- /dev/null +++ b/000_temp/63-fall-2018/025-defer/main.go @@ -0,0 +1,26 @@ +package main + +import "fmt" + +func main() { + defer foo() + bar() +} + +func foo() { + fmt.Println("foooooooo") +} + +func bar() { + fmt.Println("barrrrrrrrr") + defer one() + two() +} + +func one() { + fmt.Println("oneeeeeee") +} + +func two() { + fmt.Println("twoooooooooo") +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/026-anonymous-func/main.go b/000_temp/63-fall-2018/026-anonymous-func/main.go new file mode 100644 index 00000000..6f1cd19d --- /dev/null +++ b/000_temp/63-fall-2018/026-anonymous-func/main.go @@ -0,0 +1,15 @@ +package main + +import "fmt" + +func main() { + foo() + + // anonymous func + + func(x int){ + fmt.Println(x) + }(4) +} + +func foo() {fmt.Println("this is foo")} \ No newline at end of file diff --git a/000_temp/63-fall-2018/027-func-expression/main.go b/000_temp/63-fall-2018/027-func-expression/main.go new file mode 100644 index 00000000..f536aab4 --- /dev/null +++ b/000_temp/63-fall-2018/027-func-expression/main.go @@ -0,0 +1,27 @@ +package main + +import "fmt" + +func main() { + a := foo("something") + fmt.Println(a) + + d := 14 + b := func(z string){ + fmt.Println(z) + } + + fmt.Printf("%T\n", d) + fmt.Printf("%T\n", b) + + b("james") + b("jenny") + x := foo("cat") + y := foo("bird") + fmt.Println(x,y) + fmt.Println(d) +} + +func foo(s string) string { + return s + "dogggggggg" +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/028-returning-a-func/main.go b/000_temp/63-fall-2018/028-returning-a-func/main.go new file mode 100644 index 00000000..9fc52167 --- /dev/null +++ b/000_temp/63-fall-2018/028-returning-a-func/main.go @@ -0,0 +1,23 @@ +package main + +import "fmt" + +func main() { + x := foo() + y := foo() + fmt.Printf("%T\t %T\n", x,y) + + func(z string){ + fmt.Println(z) + }("james") + + x("jenny") + y("dogggggggggy") + +} + +func foo() func(string) { + return func(z string){ + fmt.Println(z) + } +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/029-pointers/main.go b/000_temp/63-fall-2018/029-pointers/main.go new file mode 100644 index 00000000..e53221a7 --- /dev/null +++ b/000_temp/63-fall-2018/029-pointers/main.go @@ -0,0 +1,19 @@ +package main + +import "fmt" + +func main() { + x := 42 + fmt.Println(x) + fmt.Printf("%T\n", x) + fmt.Println(&x) + + y := &x + fmt.Println(y) + fmt.Printf("%T\n", y) + fmt.Println(*y) + + *y = 43 + + fmt.Println(x) +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/030-os-args/main.go b/000_temp/63-fall-2018/030-os-args/main.go new file mode 100644 index 00000000..2babcccd --- /dev/null +++ b/000_temp/63-fall-2018/030-os-args/main.go @@ -0,0 +1,13 @@ +package main + +import ( + "os" + "fmt" +) + +func main() { + fmt.Println(os.Args[0]) + fmt.Println(os.Args[1]) + fmt.Println(os.Args[2]) + fmt.Println(os.Args[3]) +} diff --git a/000_temp/63-fall-2018/031-string-template/main.go b/000_temp/63-fall-2018/031-string-template/main.go new file mode 100644 index 00000000..7d1d6803 --- /dev/null +++ b/000_temp/63-fall-2018/031-string-template/main.go @@ -0,0 +1,45 @@ +package main + +import ( + "fmt" + "os" + "log" + "strings" + "io" +) + +func main() { + // CREATE STRING + // assign to variable + name := "James" + str := `html here` + name + `more html` + fmt.Println(str) + + // CREATE STRING + // string print + s := fmt.Sprint(`mas ` + name + `menos`) + fmt.Println(s) + + // CREATE FILE + // io.Copy to the file + nf, err := os.Create("newfile.txt") + if err != nil { + log.Fatal("whoops", err) + } + + io.Copy(nf, strings.NewReader(s)) + + // CREATE FILE + // writestring to file + nf2, err := os.Create("newfile2.txt") + if err != nil { + log.Fatal("whoops", err) + } + + n, err := nf2.WriteString(str) + if err != nil { + log.Fatal("whoops2", err) + } + + fmt.Println("bytes written", n) +} diff --git a/000_temp/63-fall-2018/032-text-template/main.go b/000_temp/63-fall-2018/032-text-template/main.go new file mode 100644 index 00000000..6285de4a --- /dev/null +++ b/000_temp/63-fall-2018/032-text-template/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "text/template" + "log" + "os" + "fmt" +) + +func main() { + tpl, err := template.ParseFiles("one.txt", "two.txt") + if err != nil { + log.Fatal("whoops", err) + } + + fmt.Println("\n-----") + tpl.ExecuteTemplate(os.Stdout, "one.txt", nil) + + fmt.Println("\n\n-----") + tpl.ExecuteTemplate(os.Stdout, "two.txt", "James") + fmt.Println("\n\n") +} diff --git a/000_temp/63-fall-2018/032-text-template/one.txt b/000_temp/63-fall-2018/032-text-template/one.txt new file mode 100644 index 00000000..045061a0 --- /dev/null +++ b/000_temp/63-fall-2018/032-text-template/one.txt @@ -0,0 +1 @@ +Hello, this is file one. \ No newline at end of file diff --git a/000_temp/63-fall-2018/032-text-template/two.txt b/000_temp/63-fall-2018/032-text-template/two.txt new file mode 100644 index 00000000..c93bf5b8 --- /dev/null +++ b/000_temp/63-fall-2018/032-text-template/two.txt @@ -0,0 +1 @@ +Hello, this is file two and my name is {{.}} \ No newline at end of file diff --git a/000_temp/63-fall-2018/033-parseglob/main.go b/000_temp/63-fall-2018/033-parseglob/main.go new file mode 100644 index 00000000..0d024b14 --- /dev/null +++ b/000_temp/63-fall-2018/033-parseglob/main.go @@ -0,0 +1,39 @@ +package main + +import ( + "text/template" + "os" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + err := tpl.ExecuteTemplate(os.Stdout, "one.gohtml", nil) + if err != nil { + panic(err) + } + + err = tpl.ExecuteTemplate(os.Stdout, "two.gohtml", nil) + if err != nil { + panic(err) + } + + err = tpl.ExecuteTemplate(os.Stdout, "lasagne.php", nil) + if err != nil { + panic(err) + } + + err = tpl.ExecuteTemplate(os.Stdout, "anaheim.dland", nil) + if err != nil { + panic(err) + } + + err = tpl.ExecuteTemplate(os.Stdout, "lets.blowitup", nil) + if err != nil { + panic(err) + } +} diff --git a/000_temp/63-fall-2018/033-parseglob/templates/anaheim.dland b/000_temp/63-fall-2018/033-parseglob/templates/anaheim.dland new file mode 100644 index 00000000..c8540638 --- /dev/null +++ b/000_temp/63-fall-2018/033-parseglob/templates/anaheim.dland @@ -0,0 +1,2 @@ +this is file anaheim +****** \ No newline at end of file diff --git a/000_temp/63-fall-2018/033-parseglob/templates/lasagne.php b/000_temp/63-fall-2018/033-parseglob/templates/lasagne.php new file mode 100644 index 00000000..0596157e --- /dev/null +++ b/000_temp/63-fall-2018/033-parseglob/templates/lasagne.php @@ -0,0 +1,2 @@ +this is file lasagne +****** \ No newline at end of file diff --git a/000_temp/63-fall-2018/033-parseglob/templates/one.gohtml b/000_temp/63-fall-2018/033-parseglob/templates/one.gohtml new file mode 100644 index 00000000..d7432a4c --- /dev/null +++ b/000_temp/63-fall-2018/033-parseglob/templates/one.gohtml @@ -0,0 +1,2 @@ +this is file one +****** \ No newline at end of file diff --git a/000_temp/63-fall-2018/033-parseglob/templates/two.gohtml b/000_temp/63-fall-2018/033-parseglob/templates/two.gohtml new file mode 100644 index 00000000..d2648063 --- /dev/null +++ b/000_temp/63-fall-2018/033-parseglob/templates/two.gohtml @@ -0,0 +1,2 @@ +this is file two +****** \ No newline at end of file diff --git a/000_temp/63-fall-2018/034-pass-in-data-aggregate/main.go b/000_temp/63-fall-2018/034-pass-in-data-aggregate/main.go new file mode 100644 index 00000000..4138fcfa --- /dev/null +++ b/000_temp/63-fall-2018/034-pass-in-data-aggregate/main.go @@ -0,0 +1,50 @@ +package main + +import ( + "text/template" + "os" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +type person struct { + First string + Last string + Age int +} + +func main() { + + p1 := person{ + First: "James", + Last: "Bond", + Age: 32, + } + + err := tpl.ExecuteTemplate(os.Stdout, "one.gohtml", p1) + if err != nil { + panic(err) + } + + p2 := person{ + First: "Jenny", + Last: "Moneypenny", + Age: 27, + } + + xp := []person{p1, p2} + err = tpl.ExecuteTemplate(os.Stdout, "two.gohtml", xp) + if err != nil { + panic(err) + } + + err = tpl.ExecuteTemplate(os.Stdout, "lasagne.php", p1) + if err != nil { + panic(err) + } + +} diff --git a/000_temp/63-fall-2018/034-pass-in-data-aggregate/templates/lasagne.php b/000_temp/63-fall-2018/034-pass-in-data-aggregate/templates/lasagne.php new file mode 100644 index 00000000..175b0a27 --- /dev/null +++ b/000_temp/63-fall-2018/034-pass-in-data-aggregate/templates/lasagne.php @@ -0,0 +1,2 @@ +this is file lasagne {{.First}} is {{.Last}} +****** \ No newline at end of file diff --git a/000_temp/63-fall-2018/034-pass-in-data-aggregate/templates/one.gohtml b/000_temp/63-fall-2018/034-pass-in-data-aggregate/templates/one.gohtml new file mode 100644 index 00000000..a7bd2240 --- /dev/null +++ b/000_temp/63-fall-2018/034-pass-in-data-aggregate/templates/one.gohtml @@ -0,0 +1,2 @@ +this is file one {{.}} +****** \ No newline at end of file diff --git a/000_temp/63-fall-2018/034-pass-in-data-aggregate/templates/two.gohtml b/000_temp/63-fall-2018/034-pass-in-data-aggregate/templates/two.gohtml new file mode 100644 index 00000000..0a8c762e --- /dev/null +++ b/000_temp/63-fall-2018/034-pass-in-data-aggregate/templates/two.gohtml @@ -0,0 +1,2 @@ +this is file two {{.}} +****** \ No newline at end of file diff --git a/000_temp/63-fall-2018/035-hash-bucket/main.go b/000_temp/63-fall-2018/035-hash-bucket/main.go new file mode 100644 index 00000000..abc30424 --- /dev/null +++ b/000_temp/63-fall-2018/035-hash-bucket/main.go @@ -0,0 +1,41 @@ +package main + +import ( + "bufio" + "fmt" + "log" + "net/http" +) + +func main() { + // get the book moby dick + res, err := http.Get("http://www.gutenberg.org/files/2701/2701-0.txt") + if err != nil { + log.Fatal(err) + } + + defer res.Body.Close() + scanner := bufio.NewScanner(res.Body) + // scan the page + // Set the split function for the scanning operation. + scanner.Split(bufio.ScanWords) + // Create slice to hold counts + buckets := make([]int, 2000) + // Loop over the words + for scanner.Scan() { + fmt.Print(scanner.Text(), " - ") + n := hashBucket(scanner.Text()) + buckets[n]++ + } + fmt.Println(buckets[65:123]) + // fmt.Println("***************") + // for i := 28; i <= 126; i++ { + // fmt.Printf("%v - %c - %v \n", i, i, buckets[i]) + // } +} + +func hashBucket(word string) int { + fmt.Print(word[0], " ---- ") + fmt.Printf("%#U\n", word[0]) + return int(word[0]) +} \ No newline at end of file diff --git a/000_temp/63-fall-2018/036-templates-review/main.go b/000_temp/63-fall-2018/036-templates-review/main.go new file mode 100644 index 00000000..ebbb00ac --- /dev/null +++ b/000_temp/63-fall-2018/036-templates-review/main.go @@ -0,0 +1,49 @@ +package main + +import ( + "html/template" + "os" + "log" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + err := tpl.ExecuteTemplate(os.Stdout, "main.gohtml", nil) + if err != nil { + log.Fatal("there was an error", err) + } + + err = tpl.ExecuteTemplate(os.Stdout, "about.gohtml", nil) + if err != nil { + log.Fatal("there was an error", err) + } + + f, err := os.Create("main.html") + if err != nil { + log.Fatal("another error", err) + } + defer f.Close() + + f2, err := os.Create("about.html") + if err != nil { + log.Fatal("another error", err) + } + defer f2.Close() + + err = tpl.ExecuteTemplate(f, "main.gohtml", nil) + if err != nil { + log.Fatal("there was an error", err) + } + + err = tpl.ExecuteTemplate(f2, "about.gohtml", nil) + if err != nil { + log.Fatal("there was an error", err) + } + + +} \ No newline at end of file diff --git a/040_json/21_solution/zz_web/templates/expectancy.html b/000_temp/63-fall-2018/036-templates-review/templates/about.gohtml old mode 100755 new mode 100644 similarity index 61% rename from 040_json/21_solution/zz_web/templates/expectancy.html rename to 000_temp/63-fall-2018/036-templates-review/templates/about.gohtml index 566549bd..89312acc --- a/040_json/21_solution/zz_web/templates/expectancy.html +++ b/000_temp/63-fall-2018/036-templates-review/templates/about.gohtml @@ -2,9 +2,11 @@ - Title + About +

Here is my about template

+ \ No newline at end of file diff --git a/040_json/21_solution/zz_web/templates/social.html b/000_temp/63-fall-2018/036-templates-review/templates/main.gohtml old mode 100755 new mode 100644 similarity index 62% rename from 040_json/21_solution/zz_web/templates/social.html rename to 000_temp/63-fall-2018/036-templates-review/templates/main.gohtml index 566549bd..00f69d92 --- a/040_json/21_solution/zz_web/templates/social.html +++ b/000_temp/63-fall-2018/036-templates-review/templates/main.gohtml @@ -2,9 +2,11 @@ - Title + Main +

Here is my main template

+ \ No newline at end of file diff --git a/000_temp/63-fall-2018/037-data/01/about.html b/000_temp/63-fall-2018/037-data/01/about.html new file mode 100644 index 00000000..1ddf1801 --- /dev/null +++ b/000_temp/63-fall-2018/037-data/01/about.html @@ -0,0 +1,15 @@ + + + + + + + Document + + + + +

here's the data from about [7 8 9 125 345]

+ + \ No newline at end of file diff --git a/000_temp/63-fall-2018/037-data/01/default.html b/000_temp/63-fall-2018/037-data/01/default.html new file mode 100644 index 00000000..554b3e3a --- /dev/null +++ b/000_temp/63-fall-2018/037-data/01/default.html @@ -0,0 +1,15 @@ + + + + + + + Document + + + +

Here's the data 42

+ + + \ No newline at end of file diff --git a/000_temp/63-fall-2018/037-data/01/main.go b/000_temp/63-fall-2018/037-data/01/main.go new file mode 100644 index 00000000..fd858f6f --- /dev/null +++ b/000_temp/63-fall-2018/037-data/01/main.go @@ -0,0 +1,39 @@ +package main + +import ( + "html/template" + "os" + "log" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + f1, err := os.Create("default.html") + if err != nil { + log.Fatal("f1 errored", err) + } + defer f1.Close() + + f2, err := os.Create("about.html") + if err != nil { + log.Fatal("f1 errored", err) + } + defer f2.Close() + + err = tpl.ExecuteTemplate(f1, "default.gohtml", 42) + if err != nil { + panic(err) + } + + + xi := []int{7,8,9,125,345,} + err = tpl.ExecuteTemplate(f2, "about.gohtml", xi) + if err != nil { + panic(err) + } +} diff --git a/000_temp/63-fall-2018/037-data/01/templates/about.gohtml b/000_temp/63-fall-2018/037-data/01/templates/about.gohtml new file mode 100644 index 00000000..4a098421 --- /dev/null +++ b/000_temp/63-fall-2018/037-data/01/templates/about.gohtml @@ -0,0 +1,15 @@ + + + + + + + Document + + + + +

here's the data from about {{.}}

+ + \ No newline at end of file diff --git a/000_temp/63-fall-2018/037-data/01/templates/default.gohtml b/000_temp/63-fall-2018/037-data/01/templates/default.gohtml new file mode 100644 index 00000000..86c227e5 --- /dev/null +++ b/000_temp/63-fall-2018/037-data/01/templates/default.gohtml @@ -0,0 +1,15 @@ + + + + + + + Document + + + +

Here's the data {{.}}

+ + + \ No newline at end of file diff --git a/000_temp/63-fall-2018/037-data/02/about.html b/000_temp/63-fall-2018/037-data/02/about.html new file mode 100644 index 00000000..348f6c97 --- /dev/null +++ b/000_temp/63-fall-2018/037-data/02/about.html @@ -0,0 +1,23 @@ + + + + + + + Document + + + + +

ABOUT here is a raw + +string + + +literal + + +

+ + \ No newline at end of file diff --git a/000_temp/63-fall-2018/037-data/02/default.html b/000_temp/63-fall-2018/037-data/02/default.html new file mode 100644 index 00000000..1afc6b1b --- /dev/null +++ b/000_temp/63-fall-2018/037-data/02/default.html @@ -0,0 +1,16 @@ + + + + + + + Document + + + +

DEFAULT here is text with space

+ + + + \ No newline at end of file diff --git a/000_temp/63-fall-2018/037-data/02/main.go b/000_temp/63-fall-2018/037-data/02/main.go new file mode 100644 index 00000000..957a710c --- /dev/null +++ b/000_temp/63-fall-2018/037-data/02/main.go @@ -0,0 +1,48 @@ +package main + +import ( + "html/template" + "os" + "log" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + f1, err := os.Create("default.html") + if err != nil { + log.Fatal("f1 errored", err) + } + defer f1.Close() + + f2, err := os.Create("about.html") + if err != nil { + log.Fatal("f1 errored", err) + } + defer f2.Close() + + s := " here is text with space " + err = tpl.ExecuteTemplate(f1, "default.gohtml", s) + if err != nil { + panic(err) + } + + + t := ` here is a raw + +string + + +literal + + +` + err = tpl.ExecuteTemplate(f2, "about.gohtml", t) + if err != nil { + panic(err) + } +} diff --git a/000_temp/63-fall-2018/037-data/02/templates/about.gohtml b/000_temp/63-fall-2018/037-data/02/templates/about.gohtml new file mode 100644 index 00000000..ec3546a3 --- /dev/null +++ b/000_temp/63-fall-2018/037-data/02/templates/about.gohtml @@ -0,0 +1,15 @@ + + + + + + + Document + + + + +

ABOUT {{- .}}

+ + \ No newline at end of file diff --git a/000_temp/63-fall-2018/037-data/02/templates/default.gohtml b/000_temp/63-fall-2018/037-data/02/templates/default.gohtml new file mode 100644 index 00000000..fb5302a8 --- /dev/null +++ b/000_temp/63-fall-2018/037-data/02/templates/default.gohtml @@ -0,0 +1,16 @@ + + + + + + + Document + + + +

DEFAULT {{- . -}}

+ + + + \ No newline at end of file diff --git a/000_temp/63-fall-2018/037-data/03/about.html b/000_temp/63-fall-2018/037-data/03/about.html new file mode 100644 index 00000000..6d39692f --- /dev/null +++ b/000_temp/63-fall-2018/037-data/03/about.html @@ -0,0 +1,15 @@ + + + + + + + Document + + + + +

ABOUT this is the else

+ + \ No newline at end of file diff --git a/000_temp/63-fall-2018/037-data/03/default.html b/000_temp/63-fall-2018/037-data/03/default.html new file mode 100644 index 00000000..83db2f29 --- /dev/null +++ b/000_temp/63-fall-2018/037-data/03/default.html @@ -0,0 +1,16 @@ + + + + + + + Document + + + +

DEFAULT evaluated

+ + + + \ No newline at end of file diff --git a/000_temp/63-fall-2018/037-data/03/main.go b/000_temp/63-fall-2018/037-data/03/main.go new file mode 100644 index 00000000..ca00444a --- /dev/null +++ b/000_temp/63-fall-2018/037-data/03/main.go @@ -0,0 +1,40 @@ +package main + +import ( + "html/template" + "os" + "log" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + f1, err := os.Create("default.html") + if err != nil { + log.Fatal("f1 errored", err) + } + defer f1.Close() + + f2, err := os.Create("about.html") + if err != nil { + log.Fatal("f1 errored", err) + } + defer f2.Close() + + t := true + err = tpl.ExecuteTemplate(f1, "default.gohtml", t) + if err != nil { + panic(err) + } + + + f := false + err = tpl.ExecuteTemplate(f2, "about.gohtml", f) + if err != nil { + panic(err) + } +} diff --git a/000_temp/63-fall-2018/037-data/03/templates/about.gohtml b/000_temp/63-fall-2018/037-data/03/templates/about.gohtml new file mode 100644 index 00000000..79bc1eb1 --- /dev/null +++ b/000_temp/63-fall-2018/037-data/03/templates/about.gohtml @@ -0,0 +1,15 @@ + + + + + + + Document + + + + +

ABOUT {{if .}}evaluated{{else}} this is the else{{end}}

+ + \ No newline at end of file diff --git a/000_temp/63-fall-2018/037-data/03/templates/default.gohtml b/000_temp/63-fall-2018/037-data/03/templates/default.gohtml new file mode 100644 index 00000000..053254bb --- /dev/null +++ b/000_temp/63-fall-2018/037-data/03/templates/default.gohtml @@ -0,0 +1,16 @@ + + + + + + + Document + + + +

DEFAULT {{if .}}evaluated{{else}} this is the else{{end}}

+ + + + \ No newline at end of file diff --git a/000_temp/64-HANDLER/main.go b/000_temp/64-HANDLER/main.go new file mode 100644 index 00000000..b5b6687c --- /dev/null +++ b/000_temp/64-HANDLER/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "net/http" + "io" +) + + +type hotdog int + +// func receiver identifier(params) return(s) {} +func (h hotdog) ServeHTTP(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "WASSSSSUP!!!!!") +} + +func main() { + var d hotdog + http.ListenAndServe(":8080", d) +} + +/* + +type Handler +type Handler interface { + ServeHTTP(ResponseWriter, *Request) +} + +*/ \ No newline at end of file diff --git a/000_temp/65-DEFAULT-SERVE-MUX/main.go b/000_temp/65-DEFAULT-SERVE-MUX/main.go new file mode 100644 index 00000000..cce7dabe --- /dev/null +++ b/000_temp/65-DEFAULT-SERVE-MUX/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "net/http" + "log" + "fmt" + "html" + "io" +) + + +type hotdog int + +func (h hotdog) ServeHTTP(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "hello from baz") +} + +func main() { + + var bazhandler hotdog + + http.Handle("/baz", bazhandler) + + http.HandleFunc("/foo", fooHandler) + + http.HandleFunc("/bar/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path)) + }) + + + log.Fatal(http.ListenAndServe(":8080", nil)) + +} + +func fooHandler(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "hello from foo") +} + + +/* + +type Handler +type Handler interface { + ServeHTTP(ResponseWriter, *Request) +} + +*/ \ No newline at end of file diff --git a/000_temp/66-HANDLEFUNC/main.go b/000_temp/66-HANDLEFUNC/main.go new file mode 100644 index 00000000..6eb300f5 --- /dev/null +++ b/000_temp/66-HANDLEFUNC/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "net/http" + "io" + "fmt" +) + +func main() { + http.HandleFunc("/", home) + http.HandleFunc("/about", about) + http.HandleFunc("/contact", contact) + + http.ListenAndServe(":8080", nil) +} + +func home(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "hello from home") +} + +func about (w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "wassup from about") +} + +func contact (w http.ResponseWriter, r * http.Request) { + fmt.Fprint(w, "get in touch with us, yo, here at contact") +} diff --git a/000_temp/67-KABOOM-BOOOYAH/main.go b/000_temp/67-KABOOM-BOOOYAH/main.go new file mode 100644 index 00000000..efbb3464 --- /dev/null +++ b/000_temp/67-KABOOM-BOOOYAH/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "net/http" + "html/template" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", home) + http.HandleFunc("/about", about) + http.HandleFunc("/contact", contact) + + http.ListenAndServe(":8080", nil) +} + +func home(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "default.gohtml", nil) +} + +func about (w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} + +func contact (w http.ResponseWriter, r * http.Request) { + tpl.ExecuteTemplate(w, "contact.gohtml", nil) +} diff --git a/000_temp/67-KABOOM-BOOOYAH/templates/about.gohtml b/000_temp/67-KABOOM-BOOOYAH/templates/about.gohtml new file mode 100644 index 00000000..1fdab8c9 --- /dev/null +++ b/000_temp/67-KABOOM-BOOOYAH/templates/about.gohtml @@ -0,0 +1 @@ +hello from about \ No newline at end of file diff --git a/000_temp/67-KABOOM-BOOOYAH/templates/contact.gohtml b/000_temp/67-KABOOM-BOOOYAH/templates/contact.gohtml new file mode 100644 index 00000000..758bb847 --- /dev/null +++ b/000_temp/67-KABOOM-BOOOYAH/templates/contact.gohtml @@ -0,0 +1 @@ +hello from contact \ No newline at end of file diff --git a/000_temp/67-KABOOM-BOOOYAH/templates/default.gohtml b/000_temp/67-KABOOM-BOOOYAH/templates/default.gohtml new file mode 100644 index 00000000..59000559 --- /dev/null +++ b/000_temp/67-KABOOM-BOOOYAH/templates/default.gohtml @@ -0,0 +1 @@ +hello from default \ No newline at end of file diff --git a/000_temp/68-sql-group-having/having.sql b/000_temp/68-sql-group-having/having.sql new file mode 100644 index 00000000..e6c9f983 --- /dev/null +++ b/000_temp/68-sql-group-having/having.sql @@ -0,0 +1,62 @@ +CREATE DATABASE music; + +\c music + +CREATE TABLE musicians (mid INT PRIMARY KEY NOT NULL, mname TEXT NOT NULL); + +INSERT INTO musicians VALUES (1, 'Dave Mustang'), (2, 'Steven Tyler'), (3, 'Sam Smith'), (4, 'Sarah McLachlan'), (5, 'Bono'), (6, 'Steve Miller'), (7, 'Bruce Springsteen'); + +CREATE TABLE bands (bid INT PRIMARY KEY NOT NULL, bname TEXT NOT NULL); + +INSERT INTO bands VALUES (1, 'Aerosmith'), (2, 'U2'), (3, 'Ghost'), (4, 'E Street'), (5, 'Metallica'), (6, 'Megadeath'); + +CREATE TABLE bandmembers (bmid INT PRIMARY KEY NOT NULL, bid INT REFERENCES bands(bid) NOT NULL, mid INT REFERENCES musicians(mid) NOT NULL); + +INSERT INTO bandmembers VALUES (1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5), (6,5,7), (7,4,4), (8,3,3); + +CREATE TABLE styles (sid INT PRIMARY KEY NOT NULL, sname TEXT NOT NULL); + +INSERT INTO styles VALUES (1,'jazz'), (2,'metal'), (3,'rock'), (4,'country'), (5,'pop'), (6,'folk'); + +CREATE TABLE bandstyles (bsid INT PRIMARY KEY NOT NULL, bid INT REFERENCES bands(bid) NOT NULL, sid INT REFERENCES styles(sid) NOT NULL); + +INSERT INTO bandstyles VALUES (1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5), (6,4,4), (7,3,3); + +------------ queries --------------- + + +SELECT m.mname, b.bname, s.sname FROM (((musicians AS m FULL JOIN bandmembers AS bm ON m.mid = bm.mid) FULL JOIN bands AS b ON bm.bid = b.bid) FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid; + + +/* generate more band members */ +https://play.golang.org/p/uv2g4Ap21Sl + +INSERT INTO bandmembers VALUES (9,2,3),(10,3,5),(11,2,4),(12,1,1),(13,2,1),(14,5,2),(15,3,5),(16,4,5),(17,2,1),(18,3,2),(19,1,2),(20,4,4),(21,3,3),(22,3,4),(23,1,1),(24,2,4),(25,3,2),(26,5,2),(27,3,2),(28,1,2),(29,4,1),(30,5,4),(31,4,3),(32,4,5),(33,5,4),(34,3,2),(35,5,5),(36,1,1),(37,4,4),(38,4,1),(39,2,1),(40,1,2); + + +SELECT bname, sname FROM (bands AS b LEFT JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid; + +SELECT m.mname, b.bname FROM (musicians AS m LEFT JOIN bandmembers AS bm ON m.mid = bm.mid) LEFT JOIN bands AS b ON bm.bid = b.bid; + +SELECT m.mname, b.bname FROM (musicians AS m LEFT JOIN bandmembers AS bm ON m.mid = bm.mid) LEFT JOIN bands AS b ON bm.bid = b.bid GROUP BY m.mname, b.bname; + +SELECT m.mid, m.mname, b.bname FROM (musicians AS m LEFT JOIN bandmembers AS bm ON m.mid = bm.mid) LEFT JOIN bands AS b ON bm.bid = b.bid GROUP BY m.mid, m.mname, b.bname; + +/* does not work*/ +SELECT b.bname, s.sname, COUNT(*) AS members FROM (((musicians AS m JOIN bandmembers AS bm ON m.mid = bm.mid) JOIN bands AS b ON bm.bid = b.bid) JOIN bandstyles AS bs ON b.bid = bs.bid) JOIN styles AS s ON bs.sid = s.sid; + +SELECT COUNT(*) AS total FROM musicians; + +/* does not work*/ +SELECT COUNT(*) AS total FROM musicians GROUP BY mname; + +SELECT mname, COUNT(*) AS total FROM musicians GROUP BY mname; + +SELECT b.bname, s.sname, COUNT(*) AS members FROM (((musicians AS m JOIN bandmembers AS bm ON m.mid = bm.mid) JOIN bands AS b ON bm.bid = b.bid) JOIN bandstyles AS bs ON b.bid = bs.bid) JOIN styles AS s ON bs.sid = s.sid GROUP BY b.bname, s.sname; + +SELECT b.bname, s.sname, COUNT(*) AS members FROM (((musicians AS m JOIN bandmembers AS bm ON m.mid = bm.mid) JOIN bands AS b ON bm.bid = b.bid) JOIN bandstyles AS bs ON b.bid = bs.bid) JOIN styles AS s ON bs.sid = s.sid GROUP BY b.bname, s.sname HAVING COUNT(*) > 10; + +SELECT b.bname, s.sname, COUNT(bm.bmid) AS bandmembers FROM (((musicians AS m JOIN bandmembers AS bm ON m.mid = bm.mid) JOIN bands AS b ON bm.bid = b.bid) JOIN bandstyles AS bs ON b.bid = bs.bid) JOIN styles AS s ON bs.sid = s.sid GROUP BY b.bname, s.sname; + +SELECT b.bname, s.sname, COUNT(bm.bmid) AS bandmembers FROM (((musicians AS m JOIN bandmembers AS bm ON m.mid = bm.mid) JOIN bands AS b ON bm.bid = b.bid) JOIN bandstyles AS bs ON b.bid = bs.bid) JOIN styles AS s ON bs.sid = s.sid GROUP BY b.bname, s.sname HAVING COUNT(*) > 10; + diff --git a/000_temp/69-review-golang/main.go b/000_temp/69-review-golang/main.go new file mode 100644 index 00000000..79853a7c --- /dev/null +++ b/000_temp/69-review-golang/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + + http.HandleFunc("/", def) + http.HandleFunc("/about", abo) + http.Handle("/foobar", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func def(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "default.gohtml", nil) +} + +func abo(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} \ No newline at end of file diff --git a/000_temp/69-review-golang/templates/about.gohtml b/000_temp/69-review-golang/templates/about.gohtml new file mode 100644 index 00000000..6b37e571 --- /dev/null +++ b/000_temp/69-review-golang/templates/about.gohtml @@ -0,0 +1,17 @@ + + + + + + + ABOUT + + + + +

HOME

+

ABOUT

+ + + \ No newline at end of file diff --git a/000_temp/69-review-golang/templates/default.gohtml b/000_temp/69-review-golang/templates/default.gohtml new file mode 100644 index 00000000..844d9eee --- /dev/null +++ b/000_temp/69-review-golang/templates/default.gohtml @@ -0,0 +1,16 @@ + + + + + + + HOME + + + +

HOME

+

ABOUT

+ + + \ No newline at end of file diff --git a/000_temp/70-sql/having.sql b/000_temp/70-sql/having.sql new file mode 100644 index 00000000..65fe4536 --- /dev/null +++ b/000_temp/70-sql/having.sql @@ -0,0 +1,96 @@ +SELECT m.mname, b.bname, s.sname FROM (((musicians AS m FULL JOIN bandmembers AS bm ON m.mid = bm.mid) FULL JOIN bands AS b ON bm.bid = b.bid) FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid; + +SELECT s.sname, COUNT(b.bname) AS bands FROM (((musicians AS m FULL JOIN bandmembers AS bm ON m.mid = bm.mid) FULL JOIN bands AS b ON bm.bid = b.bid) FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid GROUP BY s.sname; + +SELECT s.sname, COUNT(DISTINCT(b.bname)) AS bands FROM (((musicians AS m FULL JOIN bandmembers AS bm ON m.mid = bm.mid) FULL JOIN bands AS b ON bm.bid = b.bid) FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid GROUP BY s.sname; + +SELECT DISTINCT(b.bname) AS name FROM bands AS b; + +SELECT DISTINCT(bname) FROM bands; + +SELECT * FROM bands; + +INSERT INTO bands VALUES (7, 'Madonna'); +INSERT INTO bands VALUES (8, 'Madonna'); + +SELECT b.bname, s.sname FROM (bands AS b FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid; + +INSERT INTO bandstyles VALUES (8,5,2), (9,4,1), (10,3,2), (11,2,3), (12,1,4), (13,1,5), (14,1,6); + +SELECT m.mname, b.bname, s.sname FROM (((musicians AS m FULL JOIN bandmembers AS bm ON m.mid = bm.mid) FULL JOIN bands AS b ON bm.bid = b.bid) FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid; + +SELECT s.sname, COUNT(b.bname) AS bands FROM (bands AS b FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid GROUP BY s.sname; + +SELECT s.sname, COUNT(m.mname) AS musicians FROM (((musicians AS m FULL JOIN bandmembers AS bm ON m.mid = bm.mid) FULL JOIN bands AS b ON bm.bid = b.bid) FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid GROUP BY s.sname; + +SELECT s.sname, COUNT(DISTINCT(b.bname)) AS bands FROM (bands AS b FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid GROUP BY s.sname; + +SELECT bname, sname FROM (bands AS b FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid; + +SELECT sname, bname FROM (bands AS b FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid ORDER BY bname; + +SELECT DISTINCT bname, sname AS bands FROM (bands AS b FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid ORDER BY bname; + +SELECT DISTINCT sname, bname AS bands FROM (bands AS b FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid ORDER BY bname; + +SELECT DISTINCT sname, COUNT(bname) AS bands FROM (bands AS b FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid GROUP BY sname; + +SELECT sname, COUNT(bname) AS bands FROM (bands AS b FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid GROUP BY sname; + +SELECT DISTINCT sname, bname FROM (bands AS b FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid; + +SELECT sname, bname FROM (bands AS b FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid; + +SELECT sname, COUNT(bname) as bands FROM (bands AS b FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid GROUP BY sname; + +SELECT DISTINCT sname, COUNT(bname) as bands FROM (bands AS b FULL JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid GROUP BY sname; + + + + + + + + + + + + + + + + + + +/* generate more band members */ +https://play.golang.org/p/uv2g4Ap21Sl + +INSERT INTO bandmembers VALUES (9,2,3),(10,3,5),(11,2,4),(12,1,1),(13,2,1),(14,5,2),(15,3,5),(16,4,5),(17,2,1),(18,3,2),(19,1,2),(20,4,4),(21,3,3),(22,3,4),(23,1,1),(24,2,4),(25,3,2),(26,5,2),(27,3,2),(28,1,2),(29,4,1),(30,5,4),(31,4,3),(32,4,5),(33,5,4),(34,3,2),(35,5,5),(36,1,1),(37,4,4),(38,4,1),(39,2,1),(40,1,2); + + +SELECT bname, sname FROM (bands AS b LEFT JOIN bandstyles AS bs ON b.bid = bs.bid) FULL JOIN styles AS s ON bs.sid = s.sid; + +SELECT m.mname, b.bname FROM (musicians AS m LEFT JOIN bandmembers AS bm ON m.mid = bm.mid) LEFT JOIN bands AS b ON bm.bid = b.bid; + +SELECT m.mname, b.bname FROM (musicians AS m LEFT JOIN bandmembers AS bm ON m.mid = bm.mid) LEFT JOIN bands AS b ON bm.bid = b.bid GROUP BY m.mname, b.bname; + +SELECT m.mid, m.mname, b.bname FROM (musicians AS m LEFT JOIN bandmembers AS bm ON m.mid = bm.mid) LEFT JOIN bands AS b ON bm.bid = b.bid GROUP BY m.mid, m.mname, b.bname; + +/* does not work*/ +SELECT b.bname, s.sname, COUNT(*) AS members FROM (((musicians AS m JOIN bandmembers AS bm ON m.mid = bm.mid) JOIN bands AS b ON bm.bid = b.bid) JOIN bandstyles AS bs ON b.bid = bs.bid) JOIN styles AS s ON bs.sid = s.sid; + +SELECT COUNT(*) AS total FROM musicians; + +/* does not work*/ +SELECT COUNT(*) AS total FROM musicians GROUP BY mname; + +SELECT mname, COUNT(*) AS total FROM musicians GROUP BY mname; + +SELECT b.bname, s.sname, COUNT(*) AS members FROM (((musicians AS m JOIN bandmembers AS bm ON m.mid = bm.mid) JOIN bands AS b ON bm.bid = b.bid) JOIN bandstyles AS bs ON b.bid = bs.bid) JOIN styles AS s ON bs.sid = s.sid GROUP BY b.bname, s.sname; + +SELECT b.bname, s.sname, COUNT(*) AS members FROM (((musicians AS m JOIN bandmembers AS bm ON m.mid = bm.mid) JOIN bands AS b ON bm.bid = b.bid) JOIN bandstyles AS bs ON b.bid = bs.bid) JOIN styles AS s ON bs.sid = s.sid GROUP BY b.bname, s.sname HAVING COUNT(*) > 10; + +SELECT b.bname, s.sname, COUNT(bm.bmid) AS bandmembers FROM (((musicians AS m JOIN bandmembers AS bm ON m.mid = bm.mid) JOIN bands AS b ON bm.bid = b.bid) JOIN bandstyles AS bs ON b.bid = bs.bid) JOIN styles AS s ON bs.sid = s.sid GROUP BY b.bname, s.sname; + +SELECT b.bname, s.sname, COUNT(bm.bmid) AS bandmembers FROM (((musicians AS m JOIN bandmembers AS bm ON m.mid = bm.mid) JOIN bands AS b ON bm.bid = b.bid) JOIN bandstyles AS bs ON b.bid = bs.bid) JOIN styles AS s ON bs.sid = s.sid GROUP BY b.bname, s.sname HAVING COUNT(*) > 10; + diff --git a/000_temp/71/assets/city.jpeg b/000_temp/71/assets/city.jpeg new file mode 100644 index 00000000..88934e1c Binary files /dev/null and b/000_temp/71/assets/city.jpeg differ diff --git a/000_temp/71/assets/main.css b/000_temp/71/assets/main.css new file mode 100644 index 00000000..fb78b132 --- /dev/null +++ b/000_temp/71/assets/main.css @@ -0,0 +1,38 @@ +html, body { + padding: 0; + border: 0; + margin: 0; + box-sizing: border-box; +} + +#atf { + height: 100vh; + background-color: cornflowerblue; + background-image: url("http://github.com/stuff/city.jpeg"); + background-repeat: no-repeat; + background-size: cover; + background-position: center; + display: flex; + justify-content: center; + align-items: center; + font-size: 13vw; + color: white; +} + +header { + position: fixed; + top: 0; + left: 0; + background-color: rgba(97, 115, 255, 0.44); + height: 5vh; + width: 100vw; + display: flex; + justify-content: space-between; + align-items: center; +} + +header > div { + font-size: 1.5rem; + color: white; + margin: 0 2rem; +} diff --git a/000_temp/71/assets/toby.jpg b/000_temp/71/assets/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/71/assets/toby.jpg differ diff --git a/000_temp/71/main.go b/000_temp/71/main.go new file mode 100644 index 00000000..dc7e34b2 --- /dev/null +++ b/000_temp/71/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", hom) + http.HandleFunc("/about", abo) + http.Handle("/stuff/", http.StripPrefix("/stuff", http.FileServer(http.Dir("./assets/")))) + http.ListenAndServe(":8080", nil) +} + +func hom(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "default.gohtml", nil) +} + +func abo(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} \ No newline at end of file diff --git a/000_temp/71/templates/about.gohtml b/000_temp/71/templates/about.gohtml new file mode 100644 index 00000000..510b8af5 --- /dev/null +++ b/000_temp/71/templates/about.gohtml @@ -0,0 +1,19 @@ + + + + + + + Legal Firm ABOUT Page + + + +

ABOUT

+ +HOME +ABOUT + + + + \ No newline at end of file diff --git a/000_temp/71/templates/default.gohtml b/000_temp/71/templates/default.gohtml new file mode 100644 index 00000000..9298761c --- /dev/null +++ b/000_temp/71/templates/default.gohtml @@ -0,0 +1,33 @@ + + + + + + + Legal Firm Home Page + + + + +
+
left
+
right
+
+ +
+ +CHICAGO + +
+ +

HOME

+ +HOME +ABOUT + + + + + + \ No newline at end of file diff --git a/000_temp/72/assets/toby.jpg b/000_temp/72/assets/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/72/assets/toby.jpg differ diff --git a/000_temp/72/main.go b/000_temp/72/main.go new file mode 100644 index 00000000..b3795881 --- /dev/null +++ b/000_temp/72/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", foo) + http.HandleFunc("/about", bar) + http.Handle("/resources/", http.StripPrefix("/resources", http.FileServer(http.Dir("./assets")))) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func bar(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} diff --git a/000_temp/72/templates/about.gohtml b/000_temp/72/templates/about.gohtml new file mode 100644 index 00000000..58bd92b0 --- /dev/null +++ b/000_temp/72/templates/about.gohtml @@ -0,0 +1,18 @@ + + + + + + + ABOUT + + + +

ABOUT

+ +HOME +ABOUT + + + \ No newline at end of file diff --git a/000_temp/72/templates/index.gohtml b/000_temp/72/templates/index.gohtml new file mode 100644 index 00000000..d0c02408 --- /dev/null +++ b/000_temp/72/templates/index.gohtml @@ -0,0 +1,20 @@ + + + + + + + HOME + + + +

HOME

+ +HOME +ABOUT + + + + + \ No newline at end of file diff --git a/000_temp/73/01/main.go b/000_temp/73/01/main.go new file mode 100644 index 00000000..8fd45780 --- /dev/null +++ b/000_temp/73/01/main.go @@ -0,0 +1,27 @@ +package main + +import "fmt" + + +// a VALUE of TYPE + +var x int +var s string +var b bool +var i float64 + +func main() { + x = 42 + s = "James" + b = true + i = 42.123 + fmt.Println(x, s, b, i) + + f := 43 + g := "Bond" + h := false + j := 43.342 + fmt.Println(f, g, h, j) + + fmt.Printf("%T\t %T\t %T\t %T\t \n", f, g, h, j) +} \ No newline at end of file diff --git a/000_temp/73/02/main.go b/000_temp/73/02/main.go new file mode 100644 index 00000000..f6b872e7 --- /dev/null +++ b/000_temp/73/02/main.go @@ -0,0 +1,28 @@ +package main + +import "fmt" + +// AGGREGATE or COMPOSITE +func main() { + xi := []int{4,5,6,7,42} + + fmt.Println(xi) + + for p, v := range xi { + fmt.Println(p, v) + } + + // FOR declaration; condition; post {} + n := 42 + for { + fmt.Println(n) + n++ + if n == 1000 { + break + } + } + + for i := 1000; i <= 2000; i++ { + fmt.Println(i) + } +} diff --git a/000_temp/73/03/main.go b/000_temp/73/03/main.go new file mode 100644 index 00000000..8b568604 --- /dev/null +++ b/000_temp/73/03/main.go @@ -0,0 +1,13 @@ +package main + +import "fmt" + +type hotdog int + +var hd hotdog + +func main() { + hd = 42 + fmt.Println(hd) + fmt.Printf("%T\n", hd) +} diff --git a/000_temp/73/04/main.go b/000_temp/73/04/main.go new file mode 100644 index 00000000..6b2ef70d --- /dev/null +++ b/000_temp/73/04/main.go @@ -0,0 +1,31 @@ +package main + +import "fmt" + +type person struct { + first string + age int +} + +type secretAgent struct { + person + ltk bool +} + +func main() { + p := person{ + first: "Miss Moneypenny", + age: 27, + } + + sa := secretAgent { + person: person { + first: "James", + age: 32, + }, + ltk: true, + } + + fmt.Println(p) + fmt.Println(sa) +} \ No newline at end of file diff --git a/000_temp/73/05/main.go b/000_temp/73/05/main.go new file mode 100644 index 00000000..fba21fb7 --- /dev/null +++ b/000_temp/73/05/main.go @@ -0,0 +1,19 @@ +package main + +import "fmt" + +func main() { + x := 42 + fmt.Println("x", x) + fmt.Println(&x) + + y := &x + + fmt.Printf("%v\t %T\n", x, x) + fmt.Printf("%v\t %T\n", y, y) + fmt.Println(*y) + + *y = 100 + fmt.Println("y", *y) + fmt.Println("x", x) +} diff --git a/000_temp/73/06/main.go b/000_temp/73/06/main.go new file mode 100644 index 00000000..fb9b32f5 --- /dev/null +++ b/000_temp/73/06/main.go @@ -0,0 +1,26 @@ +package main + +import "fmt" + +func main() { + a := 42 + fmt.Println("a", a) + + foo(a) + fmt.Println("a after foo", a) + + bar(&a) + fmt.Println("a after bar", a) +} + + +func foo(b int) { + b = 43 + fmt.Println("b", b) +} + +func bar(c *int) { + *c = 44 + fmt.Println("c", c) + fmt.Println("*c", *c) +} \ No newline at end of file diff --git a/000_temp/74/index.html b/000_temp/74/index.html new file mode 100644 index 00000000..bae7e1cd --- /dev/null +++ b/000_temp/74/index.html @@ -0,0 +1,43 @@ + + + + + + Document + + + + +

HELLO WORLD

+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit. A atque autem, consectetur deleniti dolor expedita fugiat + fugit harum illum iste itaque maiores maxime non obcaecati omnis quam ratione recusandae suscipit.

+ + + + + + + + + \ No newline at end of file diff --git a/000_temp/75/main.go b/000_temp/75/main.go new file mode 100644 index 00000000..d2803717 --- /dev/null +++ b/000_temp/75/main.go @@ -0,0 +1,76 @@ +package main + +import ( + "html/template" + "net/http" +) + +const s = ` + + + + + + CONTACT 4 + + + +

YOU ARE AT CONTACT 4

+ +HOME +ABOUT +CONTACT 2 +CONTACT 3 +CONTACT 4 + + + + +` + +var tpl *template.Template +var tpl2 *template.Template +var tpl3 *template.Template +var tpl4 *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) + + tpl2 = template.Must(template.New("pale").ParseFiles("templates/contact.gohtml")) + + tpl3 = template.Must(template.ParseFiles("templates/contact.gohtml")) + + tpl4 = template.Must(template.New("pale").Parse(s)) +} + +func main() { + http.HandleFunc("/", foo) + http.HandleFunc("/about", bar) + http.HandleFunc("/contact/2", con2) + http.HandleFunc("/contact/3", con3) + http.HandleFunc("/contact/4", con4) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func bar(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", nil) +} + +func con2(w http.ResponseWriter, r *http.Request) { + tpl2.ExecuteTemplate(w, "contact.gohtml", nil) +} + + +func con3(w http.ResponseWriter, r *http.Request) { + tpl3.ExecuteTemplate(w, "contact.gohtml", nil) +} + + +func con4(w http.ResponseWriter, r *http.Request) { + tpl4.ExecuteTemplate(w, "pale", nil) +} diff --git a/000_temp/75/templates/about.gohtml b/000_temp/75/templates/about.gohtml new file mode 100644 index 00000000..859035fb --- /dev/null +++ b/000_temp/75/templates/about.gohtml @@ -0,0 +1,23 @@ + + + + + + + ABOUT + + + +

YOU ARE AT ABOUT

+ +HOME +ABOUT +CONTACT 2 +CONTACT 3 +CONTACT 4 + + + + + \ No newline at end of file diff --git a/000_temp/75/templates/contact.gohtml b/000_temp/75/templates/contact.gohtml new file mode 100644 index 00000000..36b38bf8 --- /dev/null +++ b/000_temp/75/templates/contact.gohtml @@ -0,0 +1,21 @@ + + + + + + + HOME + + + +

YOU ARE AT CONTACT

+ +HOME +ABOUT +CONTACT 2 +CONTACT 3 +CONTACT 4 + + + \ No newline at end of file diff --git a/000_temp/75/templates/index.gohtml b/000_temp/75/templates/index.gohtml new file mode 100644 index 00000000..b916743e --- /dev/null +++ b/000_temp/75/templates/index.gohtml @@ -0,0 +1,22 @@ + + + + + + + HOME + + + +

YOU ARE AT HOME

+ +HOME +ABOUT +CONTACT 2 +CONTACT 3 +CONTACT 4 + + + + \ No newline at end of file diff --git a/000_temp/76 sql/sales.sql b/000_temp/76 sql/sales.sql new file mode 100644 index 00000000..18ada146 --- /dev/null +++ b/000_temp/76 sql/sales.sql @@ -0,0 +1,54 @@ +CREATE DATABASE sales; + +\l + +\c sales + +CREATE TABLE employees (eid INT PRIMARY KEY NOT NULL, ename TEXT NOT NULL); + +CREATE TABLE states (stid INT PRIMARY KEY NOT NULL, stname TEXT NOT NULL); + +CREATE TABLE cities (cid INT PRIMARY KEY NOT NULL, cname TEXT NOT NULL); + +CREATE TABLE sales (sid INT PRIMARY KEY NOT NULL, eid INT REFERENCES employees(eid) NOT NULL, cid INT REFERENCES cities(cid) NOT NULL, stid INT REFERENCES states(stid) NOT NULL, samount INT NOT NULL); + +INSERT INTO employees VALUES (1,'James'), (2,'Moneypenny'), (3,'Ian'), (4,'Fleming'), (5,'Bond'); + +INSERT INTO states VALUES (1,'AL'), (2,'AK'), (3,'AZ'), (4,'AR'), (5,'CA'); + +INSERT INTO cities VALUES (1,'Montgomery'), (2,'Anchorage'), (3,'Phoenix'), (4,'Little Rock'), (5,'Sacramento'), (6,'Fresno'), (7,'Benicia'), (8,'San Fran'), (9,'LA'), (10,'San Diego'); + +https://play.golang.org/p/knG5I2AAi79 + +INSERT INTO sales VALUES (1,3,2,2,1948), (2,2,10,5,1419), (3,1,6,5,557), (4,5,1,1,3612), (5,5,3,3,4829), (6,2,5,5,1546), (7,2,8,5,596), (8,4,7,5,1359), (9,3,8,5,3388), (10,1,9,5,3116), (11,4,2,2,2488), (12,5,2,2,457), (13,2,8,5,1586), (14,4,7,5,3191), (15,4,5,5,2534), (16,4,8,5,4425), (17,4,10,5,2058), (18,5,2,2,2300), (19,1,1,1,2989), (20,4,9,5,4456), (21,1,2,2,2706), (22,2,7,5,4929), (23,3,2,2,4884), (24,4,7,5,4477), (25,4,3,3,548), (26,3,5,5,2564), (27,1,7,5,3724), (28,3,4,4,3234), (29,5,2,2,3134), (30,2,4,4,2103), (31,2,9,5,2647), (32,1,8,5,1604), (33,4,3,3,2306), (34,1,9,5,1452), (35,3,6,5,3788), (36,1,1,1,386), (37,3,1,1,3199), (38,2,4,4,3683), (39,3,5,5,4368), (40,2,8,5,995), (41,3,7,5,4082), (42,2,10,5,1371), (43,2,4,4,4920), (44,3,2,2,2276), (45,1,6,5,1488), (46,4,10,5,2919), (47,4,5,5,1325), (48,3,8,5,1633), (49,5,7,5,641), (50,2,7,5,3177), (51,2,1,1,3945), (52,1,5,5,4284), (53,1,2,2,1703), (54,3,9,5,3332), (55,5,9,5,2923), (56,3,4,4,4309), (57,4,4,4,1267), (58,1,1,1,541), (59,3,5,5,4758), (60,2,6,5,3140), (61,4,1,1,4801), (62,1,10,5,884), (63,5,1,1,3348), (64,1,1,1,4263), (65,1,10,5,2149), (66,1,7,5,3767), (67,2,1,1,1730), (68,2,3,3,2678), (69,1,7,5,500), (70,3,3,3,393), (71,2,9,5,4204), (72,4,9,5,3857), (73,3,10,5,1258), (74,1,3,3,2282), (75,1,4,4,518), (76,1,4,4,4097), (77,3,7,5,2621), (78,3,1,1,2130), (79,1,2,2,2521), (80,5,10,5,1565), (81,2,1,1,1282), (82,2,8,5,701), (83,3,10,5,1634), (84,5,2,2,1786), (85,1,10,5,1820), (86,1,5,5,3763), (87,1,1,1,4385), (88,1,4,4,1544), (89,1,2,2,675), (90,1,10,5,1437), (91,3,9,5,1645), (92,5,6,5,1338), (93,4,5,5,1707), (94,3,9,5,2521), (95,2,3,3,1218), (96,1,2,2,3783), (97,3,10,5,230), (98,2,2,2,956), (99,4,2,2,1154), (100,5,7,5,4968); + +SELECT e.ename, c.cname, st.stname, s.samount FROM ((employees AS e JOIN sales AS s ON e.eid = s.eid) JOIN cities AS c ON s.cid = c.cid) JOIN states AS st ON s.stid = st.stid; + + + +SELECT e.ename, c.cname, st.stname, s.samount FROM ((employees AS e JOIN sales AS s ON e.eid = s.eid) JOIN cities AS c ON s.cid = c.cid) JOIN states AS st ON s.stid = st.stid WHERE e.eid = 1; + + +// does not work +SELECT e.ename, c.cname, st.stname, s.samount FROM (((employees AS e WHERE e.eid = 1) JOIN sales AS s ON e.eid = s.eid) JOIN cities AS c ON s.cid = c.cid) JOIN states AS st ON s.stid = st.stid; + +// works +SELECT e.ename FROM employees AS e WHERE e.eid = 1; + +SELECT e.ename, c.cname, st.stname, SUM(s.samount) FROM ((employees AS e JOIN sales AS s ON e.eid = s.eid) JOIN cities AS c ON s.cid = c.cid) JOIN states AS st ON s.stid = st.stid GROUP BY e.ename, c.cname, st.stname; + +SELECT e.ename, c.cname, st.stname, SUM(s.samount) FROM ((employees AS e JOIN sales AS s ON e.eid = s.eid) JOIN cities AS c ON s.cid = c.cid) JOIN states AS st ON s.stid = st.stid WHERE e.eid = 1 GROUP BY e.ename, c.cname, st.stname; + +SELECT e.ename, c.cname, st.stname, SUM(s.samount) FROM ((employees AS e JOIN sales AS s ON e.eid = s.eid) JOIN cities AS c ON s.cid = c.cid) JOIN states AS st ON s.stid = st.stid GROUP BY e.ename, c.cname, st.stname ORDER BY e.ename; + +SELECT e.ename, c.cname, st.stname, SUM(s.samount) FROM ((employees AS e JOIN sales AS s ON e.eid = s.eid) JOIN cities AS c ON s.cid = c.cid) JOIN states AS st ON s.stid = st.stid WHERE e.eid = 1 GROUP BY e.ename, c.cname, st.stname HAVING st.stname = 'CA'; + +SELECT e.ename, c.cname, st.stname, SUM(s.samount) FROM ((employees AS e JOIN sales AS s ON e.eid = s.eid) JOIN cities AS c ON s.cid = c.cid) JOIN states AS st ON s.stid = st.stid WHERE e.eid = 1 AND st.stname = 'CA' GROUP BY e.ename, c.cname, st.stname; + + +SELECT e.ename, c.cname, st.stname, SUM(s.samount) FROM ((employees AS e JOIN sales AS s ON e.eid = s.eid) JOIN cities AS c ON s.cid = c.cid) JOIN states AS st ON s.stid = st.stid GROUP BY e.ename, c.cname, st.stname HAVING e.ename = 'James' AND st.stname = 'CA'; + +// does not work +SELECT e.ename, c.cname, st.stname, SUM(s.samount) FROM ((employees AS e JOIN sales AS s ON e.eid = s.eid) JOIN cities AS c ON s.cid = c.cid) JOIN states AS st ON s.stid = st.stid GROUP BY e.ename, c.cname, st.stname HAVING e.eid = 1 AND st.stname = 'CA'; + + diff --git a/000_temp/77-web-server/assets/toby.jpg b/000_temp/77-web-server/assets/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/77-web-server/assets/toby.jpg differ diff --git a/000_temp/77-web-server/main.go b/000_temp/77-web-server/main.go new file mode 100644 index 00000000..be55885b --- /dev/null +++ b/000_temp/77-web-server/main.go @@ -0,0 +1,50 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", foo) + http.HandleFunc("/about", bar ) + http.HandleFunc("/contact", con) + http.Handle("/resources/", http.StripPrefix("/resources", http.FileServer(http.Dir("./assets")))) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", 42) +} + +func bar(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "about.gohtml", []int{1,2,3,4,5,6,7,8,9}) +} + +func con(w http.ResponseWriter, r *http.Request) { + + type person struct { + First string + Age int + } + + p1 := person{ + First: "James", + Age: 32, + } + + p2 := person { + First: "Jenny", + Age: 27, + } + + xp := []person{p1, p2} + + + tpl.ExecuteTemplate(w, "contact.gohtml", xp) +} diff --git a/000_temp/77-web-server/templates/about.gohtml b/000_temp/77-web-server/templates/about.gohtml new file mode 100644 index 00000000..57cc8dc7 --- /dev/null +++ b/000_temp/77-web-server/templates/about.gohtml @@ -0,0 +1,25 @@ + + + + + + + ABOUT + + + +

ABOUT

+ +HOME +ABOUT +CONTACT + +
+ +{{if .}} +{{.}} +{{end}} + + + \ No newline at end of file diff --git a/000_temp/77-web-server/templates/contact.gohtml b/000_temp/77-web-server/templates/contact.gohtml new file mode 100644 index 00000000..e83f1890 --- /dev/null +++ b/000_temp/77-web-server/templates/contact.gohtml @@ -0,0 +1,33 @@ + + + + + + + CONTACT + + + +

CONTACT

+ +HOME +ABOUT +CONTACT + +
+ +{{if .}} +{{.}} + +{{range .}} +

First: {{.First}}

+

Age: {{.Age}}

+{{end}} +{{end}} + + + + + + \ No newline at end of file diff --git a/000_temp/77-web-server/templates/index.gohtml b/000_temp/77-web-server/templates/index.gohtml new file mode 100644 index 00000000..1aa33933 --- /dev/null +++ b/000_temp/77-web-server/templates/index.gohtml @@ -0,0 +1,25 @@ + + + + + + + HOME + + + +

HOME

+ +HOME +ABOUT +CONTACT + +
+ +{{if .}} +{{.}} +{{end}} + + + \ No newline at end of file diff --git a/000_temp/78/assets/toby.jpg b/000_temp/78/assets/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/78/assets/toby.jpg differ diff --git a/000_temp/78/main.go b/000_temp/78/main.go new file mode 100644 index 00000000..70a2a72d --- /dev/null +++ b/000_temp/78/main.go @@ -0,0 +1,57 @@ +package main + +import ( + "net/http" + "fmt" + "html/template" + "os" + "io" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + + +func main() { + http.HandleFunc("/", foo) + http.Handle("/resources/", http.StripPrefix("/resources", http.FileServer(http.Dir("./assets")))) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + fmt.Println("Method", r.Method) + + fn := "" + + if r.Method == http.MethodPost { + // open + f, h, err := r.FormFile("q") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer f.Close() + + fn = h.Filename + + df, err := os.Create("./assets/"+fn) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer df.Close() + + _, err = io.Copy(df, f) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + } + + // w.Header().Set("Content-Type", "text/html; charset=utf-8") + + tpl.ExecuteTemplate(w, "index.gohtml", fn) +} diff --git a/000_temp/78/templates/index.gohtml b/000_temp/78/templates/index.gohtml new file mode 100644 index 00000000..28ab32a4 --- /dev/null +++ b/000_temp/78/templates/index.gohtml @@ -0,0 +1,24 @@ + + + + + + + Document + + + +
+ + +
+
+ +{{if .}} +file name: {{.}} + +{{end}} + + + \ No newline at end of file diff --git a/000_temp/79/main.go b/000_temp/79/main.go new file mode 100644 index 00000000..c35ff2ea --- /dev/null +++ b/000_temp/79/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", foo) + http.HandleFunc("/bar", bar) + http.HandleFunc("/barred", barred) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, req *http.Request) { + + var s string + + if req.Method == http.MethodPost { + s = req.FormValue("fname") + } + + fmt.Print("Your request method at foo: ", req.Method, "\n") + fmt.Print("Your FORM VALUE at foo: ", s, "\n\n") +} + +func bar(w http.ResponseWriter, req *http.Request) { + fmt.Println("Your request method at bar:", req.Method) + // process form submission here + http.Redirect(w, req, "/", http.StatusSeeOther) +} + +func barred(w http.ResponseWriter, req *http.Request) { + fmt.Println("Your request method at barred:", req.Method) + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} diff --git a/000_temp/79/templates/index.gohtml b/000_temp/79/templates/index.gohtml new file mode 100644 index 00000000..54c0bbc5 --- /dev/null +++ b/000_temp/79/templates/index.gohtml @@ -0,0 +1,15 @@ + + + + + Title + + + +
+ + +
+ + + \ No newline at end of file diff --git a/000_temp/80-renamer/80-renamer.txt b/000_temp/80-renamer/80-renamer.txt new file mode 100755 index 00000000..9ed28e74 Binary files /dev/null and b/000_temp/80-renamer/80-renamer.txt differ diff --git a/000_temp/80-renamer/main.go b/000_temp/80-renamer/main.go new file mode 100644 index 00000000..513f5ff5 --- /dev/null +++ b/000_temp/80-renamer/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "fmt" + "io/ioutil" + "os" + "strconv" +) + +func main() { + + dir := "results/" + files, _ := ioutil.ReadDir(dir) + + for i, f := range files { + fmt.Println(f.Name()) + oldfile := (dir + f.Name()) + newfile := (dir + strconv.Itoa(i) + ".txt") + fmt.Println(oldfile, "named it to", newfile, "\n") + + err := os.Rename(oldfile, newfile) + if err != nil { + fmt.Println(err) + return + } + } +} \ No newline at end of file diff --git a/000_temp/80-renamer/results/0.txt b/000_temp/80-renamer/results/0.txt new file mode 100644 index 00000000..e69de29b diff --git a/000_temp/80-renamer/results/1.txt b/000_temp/80-renamer/results/1.txt new file mode 100644 index 00000000..e69de29b diff --git a/000_temp/81-cookie-counter/main.go b/000_temp/81-cookie-counter/main.go new file mode 100644 index 00000000..e223f3cf --- /dev/null +++ b/000_temp/81-cookie-counter/main.go @@ -0,0 +1,66 @@ +package main + +import ( + "net/http" + "html/template" + "strconv" + "fmt" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", foo) + http.HandleFunc("/bar", bar) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + c, err := cookieCounter(r) + if err != nil { + http.Error(w, "bad request", http.StatusBadRequest) + return + } + http.SetCookie(w, c) + + tpl.ExecuteTemplate(w, "index.gohtml", c.Value) +} + + +func bar(w http.ResponseWriter, r *http.Request) { + c, err := cookieCounter(r) + if err != nil { + fmt.Println(err) + http.Error(w, "bad request", http.StatusBadRequest) + return + } + http.SetCookie(w, c) + + tpl.ExecuteTemplate(w, "about.gohtml", c.Value) +} + +func cookieCounter(r *http.Request) (*http.Cookie, error) { + var c *http.Cookie + + c, err := r.Cookie("wackadoodle") + if err != nil { + c = &http.Cookie{ + Name: "wackadoodle", + Value: "0", + Path: "/", + } + } + + i, err := strconv.Atoi(c.Value) + if err != nil { + return c, err + } + i++ + c.Value = strconv.Itoa(i) + + return c, nil +} diff --git a/000_temp/81-cookie-counter/templates/about.gohtml b/000_temp/81-cookie-counter/templates/about.gohtml new file mode 100644 index 00000000..d1fc872f --- /dev/null +++ b/000_temp/81-cookie-counter/templates/about.gohtml @@ -0,0 +1,16 @@ + + + + + + + ABOUT + + + +

about

+VALUE OF COOKIE {{.}} + + + \ No newline at end of file diff --git a/000_temp/81-cookie-counter/templates/index.gohtml b/000_temp/81-cookie-counter/templates/index.gohtml new file mode 100644 index 00000000..9302b5ee --- /dev/null +++ b/000_temp/81-cookie-counter/templates/index.gohtml @@ -0,0 +1,16 @@ + + + + + + + Document + + + +

home

+VALUE OF COOKIE {{.}} + + + \ No newline at end of file diff --git a/000_temp/82/main.go b/000_temp/82/main.go new file mode 100644 index 00000000..180f8828 --- /dev/null +++ b/000_temp/82/main.go @@ -0,0 +1,10 @@ +package main + +import "fmt" + +func main() { + var x uint + x = 18446744073709551615 + fmt.Println(x) + fmt.Printf("%T\n\n",x) +} diff --git a/000_temp/83_select/README.md b/000_temp/83_select/README.md new file mode 100644 index 00000000..5af6f981 --- /dev/null +++ b/000_temp/83_select/README.md @@ -0,0 +1,130 @@ +# our pathway + +We will be following the example created in [this article by Alex Edwards](http://www.alexedwards.net/blog/practical-persistence-sql) and licensed under a [MIT license](https://opensource.org/licenses/MIT) + +In order to successfully pull records from a table in a database as our user ```bond```, we will need to [ALTER](https://www.postgresql.org/docs/9.6/static/sql-alteruser.html) bond to have a different role. + +# alter bond's role +``` +alter user bond with superuser; +``` + +# switch to your bookstore database +You should already have a ```bookstore``` database: + +list databases +``` +\l +``` + +switch into that database +``` +\c bookstore +``` + +directory of tables, if any +``` +\d +``` + +# create table +``` +CREATE TABLE books ( + isbn char(14) PRIMARY KEY NOT NULL, + title varchar(255) NOT NULL, + author varchar(255) NOT NULL, + price decimal(5,2) NOT NULL +); +``` + +directory of tables +``` +\d +``` + +details of table ```books``` +``` +\d books +``` + +# insert records +``` +INSERT INTO books (isbn, title, author, price) VALUES +('978-1503261969', 'Emma', 'Jayne Austen', 9.44), +('978-1505255607', 'The Time Machine', 'H. G. Wells', 5.99), +('978-1503379640', 'The Prince', 'Niccolò Machiavelli', 6.99); +``` + +view records +``` +SELECT * FROM books; +``` + +# main.go + +## importing the driver +make sure you import the driver +``` +_ "github.com/lib/pq" +``` +"We don't use anything in the pq package directly, which means that the Go compiler will raise an error if we try to import it normally. But **we need the pq package's init() function to run so that our driver can register itself with database/sql.** We get around this by aliasing the package name to the blank identifier. This means pq.init() still gets executed, but the alias is harmlessly discarded (and our code runs error-free). This approach is standard for most of Go's SQL drivers." - Alex Edwards + +## define a book type struct +``` +type Book struct { + isbn string + title string + author string + price float32 +} +``` +"Next we define a Book type. **The struct fields and their types must align to our books table.** For completeness I should point out that we've only been able to use the string and float32 types safely because we set NOT NULL constraints on the columns in our table. If the table contained nullable fields we would need to use the sql.NullString and sql.NullFloat64 types instead – see [this Gist](https://gist.github.com/alexedwards/dc3145c8e2e6d2fd6cd9) for a working example. Generally it's easiest to avoid nullable fields altogether if you can, which is what we've done here." - Alex Edwards + +## initialize a new sql.DB +``` +db, err := sql.Open("postgres", "postgres://bond:password@localhost/bookstore?sslmode=disable") + if err != nil { + panic(err) + } + defer db.Close() +``` +"In the main() function we initialise a new sql.DB by calling sql.Open(). We pass in the name of our driver (in this case "postgres") and the connection string (you'll need to check your driver documentation for the correct format). It's worth emphasizing that **sql.DB is not a database connection – it's an abstraction representing a pool of underlying connections.** You can change the maximum number of open and idle connections in the pool with the db.SetMaxOpenConns() and db.SetMaxIdleConns() methods respectively. A final thing to note is that **sql.DB is safe for concurrent access,** which is very convenient if you're using it in a web application (like we will shortly)." - Alex Edwards + +## ping the db +``` + if err = db.Ping(); err != nil { + panic(err) + } +``` +"Because sql.Open() doesn't actually check a connection, we also call DB.Ping() to make sure that everything works OK on startup." - Alex Edwards + +## query the db +``` +rows, err := db.Query("SELECT * FROM books") + if err != nil { + panic(err) + } + defer rows.Close() +``` +"We will fetch a resultset from the books table using the DB.Query() method and assign it to a rows variable. Then we defer rows.Close() to ensure the resultset is properly closed before the parent function returns. **Closing a resultset properly is really important. As long as a resultset is open it will keep the underlying database connection open – which in turn means the connection is not available to the pool.** So if something goes wrong and the resultset isn't closed it can rapidly lead to all the connections in your pool being used up. Another gotcha (which caught me out when I first began) is that the defer statement should come after you check for an error from DB.Query. Otherwise, if DB.Query() returns an error, you'll get a panic trying to close a nil resultset." - Alex Edwards + +## iterate through results +``` + for rows.Next() { + bk := Book{} + err := rows.Scan(&bk.isbn, &bk.title, &bk.author, &bk.price) // order matters + if err != nil { + panic(err) + } + bks = append(bks, bk) + } +``` +"We then use rows.Next() to iterate through the rows in the resultset. This preps the first (and then each subsequent) row to be acted on by the rows.Scan() method. Note that if iteration over all of the rows completes then the resultset automatically closes itself and frees-up the connection. We use the rows.Scan() method to copy the values from each field in the row to a new Book object that we created. We then check for any errors that occurred during Scan, and add the new Book to a slice of books." - Alex Edwards + +## make sure everything ran well +``` + if err = rows.Err(); err != nil { + panic(err) + } +``` +"When our rows.Next() loop has finished we call rows.Err(). This returns any error that was encountered during the interation. It's important to call this – don't just assume that we completed a successful iteration over the whole resultset." - Alex Edwards Err returns the error, if any, that was encountered during iteration. Err may be called after an explicit or implicit Close. \ No newline at end of file diff --git a/000_temp/83_select/main.go b/000_temp/83_select/main.go new file mode 100644 index 00000000..0d5a29fb --- /dev/null +++ b/000_temp/83_select/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" +) + +func main() { + + connstr := "host=localhost port=5432 dbname=bookstore user=bond password=password sslmode=disable" + + // "postgres://bond:password@localhost/bookstore?sslmode=disable" + + db, err := sql.Open("postgres", connstr) + if err != nil { + panic(err) + } + defer db.Close() + + err = db.Ping() + if err != nil { + panic(err) + } + fmt.Println("You connected to your database.") +} diff --git a/000_temp/84-pg-query/main.go b/000_temp/84-pg-query/main.go new file mode 100644 index 00000000..ca56408b --- /dev/null +++ b/000_temp/84-pg-query/main.go @@ -0,0 +1,48 @@ +package main + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" +) + +type Book struct { + ISBN string + Title string + Author string + Price float32 +} + +func main() { + connStrn := "host=localhost port=5432 dbname=bookstore user=bond password=password sslmode=disable" + + db, err := sql.Open("postgres", connStrn) + if err != nil { + panic(err) + } + defer db.Close() + + err = db.Ping() + if err != nil { + panic(err) + } + + fmt.Println("Connected to database") + + rs, err := db.Query("select * from books;") + + xb := make([]Book, 0) + for rs.Next() { + b := Book{} + rs.Scan(&b.ISBN, &b.Title, &b.Author, &b.Price) + xb = append(xb, b) + + if err = rs.Err(); err != nil { + panic(err) + } + } + + for i, v := range xb { + fmt.Println(i, v) + } +} \ No newline at end of file diff --git a/000_temp/85-pg-query-web/main.go b/000_temp/85-pg-query-web/main.go new file mode 100644 index 00000000..4711d308 --- /dev/null +++ b/000_temp/85-pg-query-web/main.go @@ -0,0 +1,87 @@ +package main + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" + "html/template" + "net/http" +) + +var tpl *template.Template +var db *sql.DB + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) + + connStrn := "host=localhost port=5432 dbname=bookstore user=bond password=password sslmode=disable" + + db, err := sql.Open("postgres", connStrn) + if err != nil { + panic(err) + } + defer db.Close() + + err = db.Ping() + if err != nil { + panic(err) + } + + fmt.Println("Connected to database") +} + +type Book struct { + Isbn string + Title string + Author string + Price float32 +} + +func main() { + http.HandleFunc("/", foo) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + rs, err := db.Query("select * from books;") + + xb := make([]Book, 0) + for rs.Next() { + b := Book{} + rs.Scan(&b.Isbn, &b.Title, &b.Author, &b.Price) + xb = append(xb, b) + + if err = rs.Err(); err != nil { + panic(err) + } + } + tpl.ExecuteTemplate(w, "books.gohtml", xb) +} + + + +//rs, err := db.Query("select * from books;") +//if err != nil { +// http.Error(w, http.StatusText(500), 500) +// return +//} +//defer rs.Close() +// +//xb := make([]Book, 0) +//for rs.Next() { +// b := Book{} +// err := rs.Scan(&b.ISBN, &b.Title, &b.Author, &b.Price) +// if err != nil { +// http.Error(w, http.StatusText(500), 500) +// return +// +// } +// xb = append(xb, b) +// +// if err = rs.Err(); err != nil { +// http.Error(w, http.StatusText(500), 500) +// return +// } +//} +// +//tpl.ExecuteTemplate(w, "index.gohtml", xb) diff --git a/000_temp/85-pg-query-web/templates/index.gohtml b/000_temp/85-pg-query-web/templates/index.gohtml new file mode 100644 index 00000000..d6173f62 --- /dev/null +++ b/000_temp/85-pg-query-web/templates/index.gohtml @@ -0,0 +1,17 @@ + + + + + + + Document + + + +{{range .}} +{{.Isbn}} - {{.Title}} - {{.Author}} - {{.Price}} +{{end}} + + + \ No newline at end of file diff --git a/000_temp/86-website/main.go b/000_temp/86-website/main.go new file mode 100644 index 00000000..94b9f53e --- /dev/null +++ b/000_temp/86-website/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./resources")))) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} diff --git a/000_temp/86-website/resources/css/main.css b/000_temp/86-website/resources/css/main.css new file mode 100644 index 00000000..9960c767 --- /dev/null +++ b/000_temp/86-website/resources/css/main.css @@ -0,0 +1,23 @@ +html, body, h1 { + padding: 0; + border: 0; + margin: 0; +} + +h1 { + color: red; + font-size: 10rem; +} + +#atf { + height: 100vh; + background-image: url("http://github.com/assets/img/skyf.jpeg"); + background-position: center; + background-size: cover; + background-repeat: no-repeat; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: flex-end; + align-items: center; +} \ No newline at end of file diff --git a/000_temp/86-website/resources/img/skyf.jpeg b/000_temp/86-website/resources/img/skyf.jpeg new file mode 100644 index 00000000..620c76d5 Binary files /dev/null and b/000_temp/86-website/resources/img/skyf.jpeg differ diff --git a/000_temp/86-website/resources/img/toby.jpg b/000_temp/86-website/resources/img/toby.jpg new file mode 100644 index 00000000..16fe5330 Binary files /dev/null and b/000_temp/86-website/resources/img/toby.jpg differ diff --git a/000_temp/86-website/templates/index.gohtml b/000_temp/86-website/templates/index.gohtml new file mode 100644 index 00000000..975e7247 --- /dev/null +++ b/000_temp/86-website/templates/index.gohtml @@ -0,0 +1,21 @@ + + + + + + + Document + + + + + +
+

SKYFALL

+
+ + + + + \ No newline at end of file diff --git a/000_temp/87-website/main.go b/000_temp/87-website/main.go new file mode 100644 index 00000000..337f4776 --- /dev/null +++ b/000_temp/87-website/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", idx) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./served")))) + http.ListenAndServe(":80", nil) +} + +func idx(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} diff --git a/000_temp/87-website/served/css/main.css b/000_temp/87-website/served/css/main.css new file mode 100644 index 00000000..68ba7fe4 --- /dev/null +++ b/000_temp/87-website/served/css/main.css @@ -0,0 +1,24 @@ +html, body, div, h1 { + padding: 0; + border: 0; + margin: 0; + box-sizing: border-box; +} + +#atf { + height: 100vh; + background-image: url("http://github.com/assets/img/skyf.jpeg"); + background-repeat: no-repeat; + background-size: cover; + background-position: center; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: flex-end; + align-items: center; +} + +h1 { + color: red; + font-size: 10rem; +} \ No newline at end of file diff --git a/000_temp/87-website/served/img/skyf.jpeg b/000_temp/87-website/served/img/skyf.jpeg new file mode 100644 index 00000000..620c76d5 Binary files /dev/null and b/000_temp/87-website/served/img/skyf.jpeg differ diff --git a/000_temp/87-website/skyfall b/000_temp/87-website/skyfall new file mode 100755 index 00000000..2aad6f6c Binary files /dev/null and b/000_temp/87-website/skyfall differ diff --git a/000_temp/87-website/templates/index.gohtml b/000_temp/87-website/templates/index.gohtml new file mode 100644 index 00000000..b57b18ac --- /dev/null +++ b/000_temp/87-website/templates/index.gohtml @@ -0,0 +1,15 @@ + + + + + Title + + + + +
+

SKYFALL

+
+ + + \ No newline at end of file diff --git a/000_temp/88-whole-enchilada/main.go b/000_temp/88-whole-enchilada/main.go new file mode 100644 index 00000000..6c587e24 --- /dev/null +++ b/000_temp/88-whole-enchilada/main.go @@ -0,0 +1,63 @@ +package main + +import ( + "html/template" + "net/http" + _ "github.com/lib/pq" + "database/sql" + "log" + "fmt" +) + +type customer struct { + ID int + First string +} + +var tpl *template.Template +var db *sql.DB + +func init() { + var err error + + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) + + connStr := "dbname=thanksgiving user=turkey password=gravy host=localhost port=5432 sslmode=disable" + db, err = sql.Open("postgres", connStr) + if err != nil { + log.Fatal("**** NO OPEN ****", err) + } + + err = db.Ping() + if err != nil { + log.Fatal("**** NO PING WORKING ****", err) + } else { + fmt.Println("Ping successful") + } +} + +func main() { + defer db.Close() + + http.HandleFunc("/", index) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./resources")))) + http.ListenAndServe(":80", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + rows, err := db.Query("SELECT * FROM customers;") + if err != nil { + log.Fatal(err) + } + defer rows.Close() + + xc := []customer{} + + for rows.Next() { + c := customer{} + rows.Scan(&c.ID, &c.First) + xc = append(xc, c) + } + + tpl.ExecuteTemplate(w, "index.gohtml", xc) +} diff --git a/000_temp/88-whole-enchilada/resources/img/skyf.jpeg b/000_temp/88-whole-enchilada/resources/img/skyf.jpeg new file mode 100644 index 00000000..620c76d5 Binary files /dev/null and b/000_temp/88-whole-enchilada/resources/img/skyf.jpeg differ diff --git a/000_temp/88-whole-enchilada/templates/index.gohtml b/000_temp/88-whole-enchilada/templates/index.gohtml new file mode 100644 index 00000000..5b7b6df3 --- /dev/null +++ b/000_temp/88-whole-enchilada/templates/index.gohtml @@ -0,0 +1,21 @@ + + + + + + + HOME + + + +

HOME

+ +{{range .}} +

ID - {{.ID}} .......... FIRST - {{.First}}

+{{end}} + + + + + \ No newline at end of file diff --git a/000_temp/88-whole-enchilada/texan b/000_temp/88-whole-enchilada/texan new file mode 100755 index 00000000..c22cc5a1 Binary files /dev/null and b/000_temp/88-whole-enchilada/texan differ diff --git a/000_temp/90-div/index.html b/000_temp/90-div/index.html new file mode 100644 index 00000000..f45958a8 --- /dev/null +++ b/000_temp/90-div/index.html @@ -0,0 +1,417 @@ + + + + + Title + + + + + +
+ + + + + \ No newline at end of file diff --git a/000_temp/90-div/main.css b/000_temp/90-div/main.css new file mode 100644 index 00000000..6826090f --- /dev/null +++ b/000_temp/90-div/main.css @@ -0,0 +1,10 @@ +#dog { + /*formatting*/ + width: 150px; + height: 150px; + background-color: red; + /*layout*/ + position: fixed; + right: 0; + bottom: 0; +} \ No newline at end of file diff --git a/040_json/21_solution/zz_web/templates/stoned.html b/000_temp/91-flex/index.html old mode 100755 new mode 100644 similarity index 64% rename from 040_json/21_solution/zz_web/templates/stoned.html rename to 000_temp/91-flex/index.html index 566549bd..87342e3f --- a/040_json/21_solution/zz_web/templates/stoned.html +++ b/000_temp/91-flex/index.html @@ -3,8 +3,12 @@ Title + + +
+ \ No newline at end of file diff --git a/000_temp/91-flex/main.css b/000_temp/91-flex/main.css new file mode 100644 index 00000000..67c623d9 --- /dev/null +++ b/000_temp/91-flex/main.css @@ -0,0 +1,23 @@ +html, body, div { + padding: 0; + border: 0; + margin: 0; + box-sizing: border-box; +} + +body { + height: 100vh; + border: 4px solid red; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: center; + align-items: center; +} + +#dog { + /*formatting*/ + width: 150px; + height: 150px; + background-color: red; +} \ No newline at end of file diff --git a/000_temp/92-whole-enchilada-2/main.go b/000_temp/92-whole-enchilada-2/main.go new file mode 100644 index 00000000..9bdcdea6 --- /dev/null +++ b/000_temp/92-whole-enchilada-2/main.go @@ -0,0 +1,175 @@ +package main + +import ( + "html/template" + "net/http" + _ "github.com/lib/pq" + "database/sql" + "log" + "fmt" +) + +type customer struct { + ID int + First string +} + +var tpl *template.Template +var db *sql.DB + +func init() { + var err error + + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) + + connStr := "dbname=thanksgiving user=turkey password=gravy host=localhost port=5432 sslmode=disable" + db, err = sql.Open("postgres", connStr) + if err != nil { + log.Fatal("**** NO OPEN ****", err) + } + + err = db.Ping() + if err != nil { + log.Fatal("**** NO PING WORKING ****", err) + } else { + fmt.Println("Ping successful") + } +} + +func main() { + defer db.Close() + + http.HandleFunc("/", read) + http.HandleFunc("/process", create) + http.HandleFunc("/processtoo", ptoo) + http.HandleFunc("/update", up) + http.HandleFunc("/delete", del) + http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir("./resources")))) + http.ListenAndServe(":8080", nil) +} + +//READ +func read(w http.ResponseWriter, r *http.Request) { + rows, err := db.Query("SELECT * FROM customers;") + if err != nil { + log.Fatal(err) + } + defer rows.Close() + + xc := []customer{} + + for rows.Next() { + c := customer{} + rows.Scan(&c.ID, &c.First) + xc = append(xc, c) + } + + tpl.ExecuteTemplate(w, "index.gohtml", xc) +} + +// CREATE +func create(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Redirect(w, r, "/", http.StatusFound) + return + } + + fn := r.FormValue("fffnnnaaammmeee") + fmt.Println(fn) + + result, err := db.Exec("INSERT INTO customers (cfirst) VALUES ($1);", fn) + if err != nil { + log.Fatal(err) + } + + n, err := result.RowsAffected() + if err != nil { + log.Println(err) + http.Redirect(w, r, "/", http.StatusFound) + return + } + fmt.Println("rows affected", n) + + http.Redirect(w, r, "/", http.StatusFound) +} + + +// UPDATE +func up(w http.ResponseWriter, r *http.Request) { + + if r.Method != http.MethodGet { + http.Redirect(w, r, "/", http.StatusFound) + return + } + + customerid := r.FormValue("recordid") + + row, err := db.Query("SELECT * FROM customers WHERE cid = $1", customerid) + if err != nil { + http.Error(w, "coudn't retrieve record in up", http.StatusInternalServerError) + return + } + + c := customer{} + for row.Next() { + row.Scan(&c.ID, &c.First) + } + + tpl.ExecuteTemplate(w, "update.gohtml", c) +} + + +func ptoo(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Redirect(w, r, "/", http.StatusFound) + return + } + + id := r.FormValue("customerid") + fn := r.FormValue("fffnnnaaammmeee") + fmt.Println(id) + fmt.Println(fn) + + result, err := db.Exec("UPDATE customers SET cfirst = $2 WHERE cid = $1;", id, fn) + if err != nil { + log.Fatal(err) + } + + n, err := result.RowsAffected() + if err != nil { + log.Println(err) + http.Redirect(w, r, "/", http.StatusFound) + return + } + fmt.Println("rows affected", n) + + http.Redirect(w, r, "/", http.StatusFound) +} + + +// DELETE +func del(w http.ResponseWriter, r *http.Request) { + + if r.Method != http.MethodGet { + http.Redirect(w, r, "/", http.StatusFound) + return + } + + customerid := r.FormValue("recordid") + + + result, err := db.Exec("DELETE FROM customers WHERE cid = $1;", customerid) + if err != nil { + http.Error(w, "didn't delete", http.StatusInternalServerError) + return + } + + n, err := result.RowsAffected() + if err != nil { + http.Error(w, "didn't show rows affected", http.StatusInternalServerError) + return + } + fmt.Println("rows affected", n) + + http.Redirect(w, r, "/", http.StatusFound) +} diff --git a/000_temp/92-whole-enchilada-2/resources/img/skyf.jpeg b/000_temp/92-whole-enchilada-2/resources/img/skyf.jpeg new file mode 100644 index 00000000..620c76d5 Binary files /dev/null and b/000_temp/92-whole-enchilada-2/resources/img/skyf.jpeg differ diff --git a/000_temp/92-whole-enchilada-2/templates/index.gohtml b/000_temp/92-whole-enchilada-2/templates/index.gohtml new file mode 100644 index 00000000..4a292971 --- /dev/null +++ b/000_temp/92-whole-enchilada-2/templates/index.gohtml @@ -0,0 +1,29 @@ + + + + + + + HOME + + + +

HOME

+ +{{range .}} +

ID - {{.ID}} .......... FIRST - {{.First}} .. UPDATE .. DELETE

+{{end}} + + + + + +
+ + + +
+ + + \ No newline at end of file diff --git a/000_temp/92-whole-enchilada-2/templates/update.gohtml b/000_temp/92-whole-enchilada-2/templates/update.gohtml new file mode 100644 index 00000000..3e0261fd --- /dev/null +++ b/000_temp/92-whole-enchilada-2/templates/update.gohtml @@ -0,0 +1,24 @@ + + + + + + + HOME + + + +

UPDATING

+ +

ID - {{.ID}} .......... FIRST - {{.First}}

+ +
+ + + + +
+ + + \ No newline at end of file diff --git a/001_prereq/README.md b/001_prereq/README.md index ff239a36..1fb74b80 100644 --- a/001_prereq/README.md +++ b/001_prereq/README.md @@ -42,7 +42,8 @@ - create a value of type circle - use func info to print the area of square - use func info to print the area of circle - - [SOLUTION](https://play.golang.org/p/1enChb7Kg5) + + [SOLUTION](https://play.golang.org/p/1enChb7Kg5) ## HANDS ON 2 - create a struct that holds person fields @@ -56,19 +57,24 @@ - print a field from secret agent - run saSpeak attached to the variable of type secret agent - run pSpeak attached to the variable of type secret agent - - [SOLUTION](https://play.golang.org/p/RxrkCJw9Cd) + + [SOLUTION](https://play.golang.org/p/RxrkCJw9Cd) ## HANDS ON 3 - create an interface type that both person and secretAgent implement - declare a func with a parameter of the interface’s type - call that func in main and pass in a value of type person - call that func in main and pass in a value of type secretAgent - - [SOLUTION](https://play.golang.org/p/-Ux0gHf4SF) + + [SOLUTION](https://play.golang.org/p/dAP73m_elq) + + Thank you to @BenCarter78 for that cool solution. ## ADDITIONAL INFO - solution & optional additional info not necessary to know: assertions - - [SOLUTION](https://play.golang.org/p/0TX4o-u-_B) + + [SOLUTION](https://play.golang.org/p/0TX4o-u-_B) ## ADDITIONAL EXERCISES - - [Complete these exercises](https://docs.google.com/document/d/1AqD-5yfAw8P1aUwH6-07UTHc0FSSAnW9b44sXJEVoag/edit?usp=sharing) + [Complete these exercises](https://docs.google.com/document/d/1AqD-5yfAw8P1aUwH6-07UTHc0FSSAnW9b44sXJEVoag/edit?usp=sharing) \ No newline at end of file diff --git a/002_template/01/form-letter.txt b/002_template/01/form-letter.txt old mode 100755 new mode 100644 diff --git a/003_string-to-html/01_stdout/main.go b/003_string-to-html/01_stdout/main.go old mode 100755 new mode 100644 diff --git a/003_string-to-html/02_file/main.go b/003_string-to-html/02_file/main.go old mode 100755 new mode 100644 diff --git a/003_string-to-html/03_os-Args/index.html b/003_string-to-html/03_os-Args/index.html new file mode 100644 index 00000000..624e6494 --- /dev/null +++ b/003_string-to-html/03_os-Args/index.html @@ -0,0 +1,12 @@ + + + + + + Hello World! + + +

JAMES

+ + + \ No newline at end of file diff --git a/003_string-to-html/03_os-Args/main.go b/003_string-to-html/03_os-Args/main.go old mode 100755 new mode 100644 diff --git a/003_string-to-html/README.md b/003_string-to-html/README.md index 8587b360..d7ae7b61 100644 --- a/003_string-to-html/README.md +++ b/003_string-to-html/README.md @@ -30,8 +30,8 @@ NewReader returns a new Reader reading from s. func NewReader(s string) *Reader ``` -##[os.Args](https://godoc.org/os#pkg-variables) +## [os.Args](https://godoc.org/os#pkg-variables) Args is a variable from package os. Args hold the command-line arguments, starting with the program name. ``` Go var Args []string -``` \ No newline at end of file +``` diff --git a/004_parse_execute/01_stdout/main.go b/004_parse_execute/01_stdout/main.go old mode 100755 new mode 100644 diff --git a/004_parse_execute/01_stdout/tpl.gohtml b/004_parse_execute/01_stdout/tpl.gohtml old mode 100755 new mode 100644 diff --git a/004_parse_execute/02_file/main.go b/004_parse_execute/02_file/main.go old mode 100755 new mode 100644 diff --git a/004_parse_execute/02_file/tpl.gohtml b/004_parse_execute/02_file/tpl.gohtml old mode 100755 new mode 100644 diff --git a/004_parse_execute/03_ParseFiles/main.go b/004_parse_execute/03_ParseFiles/main.go old mode 100755 new mode 100644 diff --git a/004_parse_execute/03_ParseFiles/one.gmao b/004_parse_execute/03_ParseFiles/one.gmao old mode 100755 new mode 100644 diff --git a/004_parse_execute/03_ParseFiles/two.gmao b/004_parse_execute/03_ParseFiles/two.gmao old mode 100755 new mode 100644 diff --git a/004_parse_execute/03_ParseFiles/vespa.gmao b/004_parse_execute/03_ParseFiles/vespa.gmao old mode 100755 new mode 100644 diff --git a/004_parse_execute/04_ParseGlob/main.go b/004_parse_execute/04_ParseGlob/main.go old mode 100755 new mode 100644 diff --git a/004_parse_execute/05_performant-parsing_func-init/main.go b/004_parse_execute/05_performant-parsing_func-init/main.go old mode 100755 new mode 100644 diff --git a/005_data/01/main.go b/005_data/01/main.go old mode 100755 new mode 100644 diff --git a/005_data/01/tpl.gohtml b/005_data/01/tpl.gohtml old mode 100755 new mode 100644 diff --git a/006_variable/01/main.go b/006_variable/01/main.go old mode 100755 new mode 100644 diff --git a/006_variable/01/tpl.gohtml b/006_variable/01/tpl.gohtml old mode 100755 new mode 100644 diff --git a/007_data-structures/01_slice/01/main.go b/007_data-structures/01_slice/01/main.go old mode 100755 new mode 100644 diff --git a/007_data-structures/01_slice/01/tpl.gohtml b/007_data-structures/01_slice/01/tpl.gohtml old mode 100755 new mode 100644 diff --git a/007_data-structures/01_slice/02_variable/main.go b/007_data-structures/01_slice/02_variable/main.go old mode 100755 new mode 100644 diff --git a/007_data-structures/01_slice/02_variable/tpl.gohtml b/007_data-structures/01_slice/02_variable/tpl.gohtml old mode 100755 new mode 100644 diff --git a/007_data-structures/02_map/01/main.go b/007_data-structures/02_map/01/main.go old mode 100755 new mode 100644 diff --git a/007_data-structures/02_map/01/tpl.gohtml b/007_data-structures/02_map/01/tpl.gohtml old mode 100755 new mode 100644 diff --git a/007_data-structures/02_map/02_variable/main.go b/007_data-structures/02_map/02_variable/main.go old mode 100755 new mode 100644 diff --git a/007_data-structures/02_map/02_variable/no-order/main.go b/007_data-structures/02_map/02_variable/no-order/main.go old mode 100755 new mode 100644 diff --git a/007_data-structures/02_map/02_variable/tpl.gohtml b/007_data-structures/02_map/02_variable/tpl.gohtml old mode 100755 new mode 100644 diff --git a/007_data-structures/03_struct/01/main.go b/007_data-structures/03_struct/01/main.go old mode 100755 new mode 100644 diff --git a/007_data-structures/03_struct/01/tpl.gohtml b/007_data-structures/03_struct/01/tpl.gohtml old mode 100755 new mode 100644 diff --git a/007_data-structures/03_struct/02_variable/main.go b/007_data-structures/03_struct/02_variable/main.go old mode 100755 new mode 100644 diff --git a/007_data-structures/03_struct/02_variable/tpl.gohtml b/007_data-structures/03_struct/02_variable/tpl.gohtml old mode 100755 new mode 100644 diff --git a/007_data-structures/04_slice-struct/main.go b/007_data-structures/04_slice-struct/main.go old mode 100755 new mode 100644 diff --git a/007_data-structures/04_slice-struct/tpl.gohtml b/007_data-structures/04_slice-struct/tpl.gohtml old mode 100755 new mode 100644 diff --git a/007_data-structures/05_struct-slice-struct/01/main.go b/007_data-structures/05_struct-slice-struct/01/main.go old mode 100755 new mode 100644 diff --git a/007_data-structures/05_struct-slice-struct/01/tpl.gohtml b/007_data-structures/05_struct-slice-struct/01/tpl.gohtml old mode 100755 new mode 100644 diff --git a/007_data-structures/05_struct-slice-struct/02_refactored/main.go b/007_data-structures/05_struct-slice-struct/02_refactored/main.go old mode 100755 new mode 100644 diff --git a/007_data-structures/05_struct-slice-struct/02_refactored/tpl.gohtml b/007_data-structures/05_struct-slice-struct/02_refactored/tpl.gohtml old mode 100755 new mode 100644 diff --git a/008_func/01/main.go b/008_func/01/main.go index 995b2da8..41830345 100644 --- a/008_func/01/main.go +++ b/008_func/01/main.go @@ -36,7 +36,9 @@ func init() { func firstThree(s string) string { s = strings.TrimSpace(s) - s = s[:3] + if len(s) >= 3 { + s = s[:3] + } return s } diff --git a/009_predefined-global-functions/03_comparison/main.go b/009_predefined-global-functions/03_comparison/main.go old mode 100755 new mode 100644 diff --git a/009_predefined-global-functions/03_comparison/tpl.gohtml b/009_predefined-global-functions/03_comparison/tpl.gohtml old mode 100755 new mode 100644 diff --git a/010_nested-templates/01_nested-templates/main.go b/010_nested-templates/01_nested-templates/main.go old mode 100755 new mode 100644 diff --git a/010_nested-templates/01_nested-templates/templates/index.gohtml b/010_nested-templates/01_nested-templates/templates/index.gohtml old mode 100755 new mode 100644 index 29296d88..8a809ac1 --- a/010_nested-templates/01_nested-templates/templates/index.gohtml +++ b/010_nested-templates/01_nested-templates/templates/index.gohtml @@ -5,7 +5,10 @@ Hello World! +

The meaning of life: {{.}}

+

{{template "polarbear"}}

+ \ No newline at end of file diff --git a/010_nested-templates/02_data-to-template/main.go b/010_nested-templates/02_data-to-template/main.go old mode 100755 new mode 100644 diff --git a/010_nested-templates/02_data-to-template/templates/index.gohtml b/010_nested-templates/02_data-to-template/templates/index.gohtml old mode 100755 new mode 100644 diff --git a/010_nested-templates/03_define-template/main.go b/010_nested-templates/03_define-template/main.go old mode 100755 new mode 100644 diff --git a/010_nested-templates/04_preview/main.go b/010_nested-templates/04_preview/main.go old mode 100755 new mode 100644 diff --git a/011_composition-and-methods/01/main.go b/011_composition-and-methods/01/main.go old mode 100755 new mode 100644 diff --git a/011_composition-and-methods/01/tpl.gohtml b/011_composition-and-methods/01/tpl.gohtml old mode 100755 new mode 100644 diff --git a/011_composition-and-methods/02/main.go b/011_composition-and-methods/02/main.go old mode 100755 new mode 100644 diff --git a/011_composition-and-methods/02/tpl.gohtml b/011_composition-and-methods/02/tpl.gohtml old mode 100755 new mode 100644 diff --git a/011_composition-and-methods/03/main.go b/011_composition-and-methods/03/main.go old mode 100755 new mode 100644 diff --git a/011_composition-and-methods/03/notes.txt b/011_composition-and-methods/03/notes.txt old mode 100755 new mode 100644 diff --git a/011_composition-and-methods/03/tpl.gohtml b/011_composition-and-methods/03/tpl.gohtml old mode 100755 new mode 100644 diff --git a/011_composition-and-methods/04_method/main.go b/011_composition-and-methods/04_method/main.go old mode 100755 new mode 100644 diff --git a/011_composition-and-methods/04_method/tpl.gohtml b/011_composition-and-methods/04_method/tpl.gohtml old mode 100755 new mode 100644 index 8cbaaab8..341d3db9 --- a/011_composition-and-methods/04_method/tpl.gohtml +++ b/011_composition-and-methods/04_method/tpl.gohtml @@ -10,6 +10,7 @@

{{.Age}}

{{.SomeProcessing}}

{{.AgeDbl}}

+

{{.Age | .TakesArg}}

{{.AgeDbl | .TakesArg}}

\ No newline at end of file diff --git a/012_hands-on/01_hands-on/README.md b/012_hands-on/01_hands-on/README.md old mode 100755 new mode 100644 diff --git a/012_hands-on/01_hands-on/starting-code/main.go b/012_hands-on/01_hands-on/starting-code/main.go old mode 100755 new mode 100644 diff --git a/012_hands-on/01_hands-on/starting-code/tpl.gohtml b/012_hands-on/01_hands-on/starting-code/tpl.gohtml old mode 100755 new mode 100644 diff --git a/012_hands-on/02_solution/main.go b/012_hands-on/02_solution/main.go old mode 100755 new mode 100644 diff --git a/012_hands-on/02_solution/tpl.gohtml b/012_hands-on/02_solution/tpl.gohtml old mode 100755 new mode 100644 diff --git a/012_hands-on/03_hands-on/README.md b/012_hands-on/03_hands-on/README.md old mode 100755 new mode 100644 diff --git a/012_hands-on/04_solution/01/main.go b/012_hands-on/04_solution/01/main.go old mode 100755 new mode 100644 diff --git a/012_hands-on/04_solution/01/tpl.gohtml b/012_hands-on/04_solution/01/tpl.gohtml old mode 100755 new mode 100644 diff --git a/012_hands-on/04_solution/02/main.go b/012_hands-on/04_solution/02/main.go old mode 100755 new mode 100644 diff --git a/012_hands-on/04_solution/02/tpl.gohtml b/012_hands-on/04_solution/02/tpl.gohtml old mode 100755 new mode 100644 diff --git a/012_hands-on/04_solution/03/main.go b/012_hands-on/04_solution/03/main.go old mode 100755 new mode 100644 diff --git a/012_hands-on/04_solution/03/tpl.gohtml b/012_hands-on/04_solution/03/tpl.gohtml old mode 100755 new mode 100644 diff --git a/012_hands-on/05_hands-on/README.md b/012_hands-on/05_hands-on/README.md old mode 100755 new mode 100644 diff --git a/012_hands-on/06_solution/01/main.go b/012_hands-on/06_solution/01/main.go old mode 100755 new mode 100644 diff --git a/012_hands-on/06_solution/01/tpl.gohtml b/012_hands-on/06_solution/01/tpl.gohtml old mode 100755 new mode 100644 diff --git a/012_hands-on/06_solution/02/main.go b/012_hands-on/06_solution/02/main.go old mode 100755 new mode 100644 diff --git a/012_hands-on/06_solution/02/tpl.gohtml b/012_hands-on/06_solution/02/tpl.gohtml old mode 100755 new mode 100644 diff --git a/012_hands-on/07_hands-on/README.md b/012_hands-on/07_hands-on/README.md old mode 100755 new mode 100644 diff --git a/012_hands-on/08_solution/01/main.go b/012_hands-on/08_solution/01/main.go old mode 100755 new mode 100644 diff --git a/012_hands-on/08_solution/01/tpl.gohtml b/012_hands-on/08_solution/01/tpl.gohtml old mode 100755 new mode 100644 diff --git a/012_hands-on/09_hands-on/README.md b/012_hands-on/09_hands-on/README.md old mode 100755 new mode 100644 diff --git a/012_hands-on/09_hands-on/table.csv b/012_hands-on/09_hands-on/table.csv old mode 100755 new mode 100644 diff --git a/012_hands-on/10_solution/hw.gohtml b/012_hands-on/10_solution/hw.gohtml old mode 100755 new mode 100644 diff --git a/012_hands-on/10_solution/main.go b/012_hands-on/10_solution/main.go old mode 100755 new mode 100644 diff --git a/012_hands-on/10_solution/table.csv b/012_hands-on/10_solution/table.csv old mode 100755 new mode 100644 diff --git a/013_xss/01_text-template_no-escaping/main.go b/013_xss/01_text-template_no-escaping/main.go old mode 100755 new mode 100644 diff --git a/013_xss/01_text-template_no-escaping/tpl.gohtml b/013_xss/01_text-template_no-escaping/tpl.gohtml old mode 100755 new mode 100644 diff --git a/013_xss/02_html-template_escaping/main.go b/013_xss/02_html-template_escaping/main.go old mode 100755 new mode 100644 diff --git a/013_xss/02_html-template_escaping/tpl.gohtml b/013_xss/02_html-template_escaping/tpl.gohtml old mode 100755 new mode 100644 diff --git a/015_understanding-TCP-servers/06_dial-write/README.md b/015_understanding-TCP-servers/06_dial-write/README.md index 3d836a76..5e9cdb6f 100644 --- a/015_understanding-TCP-servers/06_dial-write/README.md +++ b/015_understanding-TCP-servers/06_dial-write/README.md @@ -1,3 +1,3 @@ run "02_read-scanner" -run "07_dial-write" \ No newline at end of file +run "06_dial-write" \ No newline at end of file diff --git a/015_understanding-TCP-servers/07_tcp-apps/02_memory-database/main.go b/015_understanding-TCP-servers/07_tcp-apps/02_memory-database/main.go index 755a8d97..0bae2ca2 100644 --- a/015_understanding-TCP-servers/07_tcp-apps/02_memory-database/main.go +++ b/015_understanding-TCP-servers/07_tcp-apps/02_memory-database/main.go @@ -30,14 +30,14 @@ func handle(conn net.Conn) { defer conn.Close() // instructions - io.WriteString(conn, "\nIN-MEMORY DATABASE\n\n"+ - "USE:\n"+ - "SET key value \n"+ - "GET key \n"+ - "DEL key \n\n"+ - "EXAMPLE:\n"+ - "SET fav chocolate \n"+ - "GET fav \n\n\n") + io.WriteString(conn, "\r\nIN-MEMORY DATABASE\r\n\r\n"+ + "USE:\r\n"+ + "\tSET key value \r\n"+ + "\tGET key \r\n"+ + "\tDEL key \r\n\r\n"+ + "EXAMPLE:\r\n"+ + "\tSET fav chocolate \r\n"+ + "\tGET fav \r\n\r\n\r\n") // read & write data := make(map[string]string) @@ -46,14 +46,17 @@ func handle(conn net.Conn) { ln := scanner.Text() fs := strings.Fields(ln) // logic + if len(fs) < 1 { + continue + } switch fs[0] { case "GET": k := fs[1] v := data[k] - fmt.Fprintf(conn, "%s\n", v) + fmt.Fprintf(conn, "%s\r\n", v) case "SET": if len(fs) != 3 { - fmt.Fprintln(conn, "EXPECTED VALUE") + fmt.Fprintln(conn, "EXPECTED VALUE\r\n") continue } k := fs[1] @@ -63,7 +66,7 @@ func handle(conn net.Conn) { k := fs[1] delete(data, k) default: - fmt.Fprintln(conn, "INVALID COMMAND "+fs[0]) + fmt.Fprintln(conn, "INVALID COMMAND "+fs[0]+"\r\n") continue } } diff --git a/016_building-a-tcp-server-for-http/01/main.go b/016_building-a-tcp-server-for-http/01/main.go index fef0ddad..84875e68 100644 --- a/016_building-a-tcp-server-for-http/01/main.go +++ b/016_building-a-tcp-server-for-http/01/main.go @@ -56,7 +56,7 @@ func request(conn net.Conn) { func respond(conn net.Conn) { - body := `Hello World` + body := `Hello World` fmt.Fprint(conn, "HTTP/1.1 200 OK\r\n") fmt.Fprintf(conn, "Content-Length: %d\r\n", len(body)) diff --git a/016_building-a-tcp-server-for-http/02_hands-on/README.md b/016_building-a-tcp-server-for-http/02_hands-on/README.md old mode 100755 new mode 100644 diff --git a/016_building-a-tcp-server-for-http/03_solution/main.go b/016_building-a-tcp-server-for-http/03_solution/main.go index 33321d54..5417c964 100644 --- a/016_building-a-tcp-server-for-http/03_solution/main.go +++ b/016_building-a-tcp-server-for-http/03_solution/main.go @@ -58,7 +58,7 @@ func request(conn net.Conn) { func respond(conn net.Conn) { - body := `Hello World` + body := `Hello World` fmt.Fprint(conn, "HTTP/1.1 200 OK\r\n") fmt.Fprintf(conn, "Content-Length: %d\r\n", len(body)) diff --git a/016_building-a-tcp-server-for-http/04_hands-on/README.md b/016_building-a-tcp-server-for-http/04_hands-on/README.md old mode 100755 new mode 100644 diff --git a/016_building-a-tcp-server-for-http/05_solution/main.go b/016_building-a-tcp-server-for-http/05_solution/main.go index 10921185..d88b77cd 100644 --- a/016_building-a-tcp-server-for-http/05_solution/main.go +++ b/016_building-a-tcp-server-for-http/05_solution/main.go @@ -122,7 +122,7 @@ func contact(conn net.Conn) { func apply(conn net.Conn) { - body := ` + body := ` APPLY
index
about
diff --git a/022_hands-on/01/01_hands-on/README.md b/022_hands-on/01/01_hands-on/README.md old mode 100755 new mode 100644 diff --git a/022_hands-on/01/02_solution/main.go b/022_hands-on/01/02_solution/main.go old mode 100755 new mode 100644 diff --git a/022_hands-on/01/03_hands-on/README.md b/022_hands-on/01/03_hands-on/README.md old mode 100755 new mode 100644 diff --git a/022_hands-on/01/05_hands-on/README.md b/022_hands-on/01/05_hands-on/README.md old mode 100755 new mode 100644 diff --git a/022_hands-on/02/04_solution/main.go b/022_hands-on/02/04_solution/main.go index 7740f10b..2fdb743c 100644 --- a/022_hands-on/02/04_solution/main.go +++ b/022_hands-on/02/04_solution/main.go @@ -34,7 +34,5 @@ func main() { // how does the above reader know when it's done? fmt.Println("Code got here.") io.WriteString(conn, "I see you connected.") - - conn.Close() } } diff --git a/022_hands-on/02/05_hands-on/README.md b/022_hands-on/02/05_hands-on/README.md index 38d0de3a..9040f3ad 100644 --- a/022_hands-on/02/05_hands-on/README.md +++ b/022_hands-on/02/05_hands-on/README.md @@ -8,11 +8,13 @@ We will now break out of the reading. Package bufio has the Scanner type. The Scanner type "provides a convenient interface for reading data". When you have a Scanner type, you can call the SCAN method on it. Successive calls to the Scan method will step through the tokens (piece of data). The default token is a line. The Scanner type also has a TEXT method. When you call this method, you will be given the text from the current token. Here is how you will use it: +``` scanner := bufio.NewScanner(conn) for scanner.Scan() { ln := scanner.Text() fmt.Println(ln) } +``` Use this code to READ from an incoming connection and print the incoming text to standard out (the terminal). @@ -20,4 +22,4 @@ When your "ln" line of text is equal to an empty string, break out of the loop. Run your code and go to localhost:8080 in **your browser.** -What do you find? \ No newline at end of file +What do you find? diff --git a/022_hands-on/02/11_hands-on/README.md b/022_hands-on/02/11_hands-on/README.md index 64aaf71c..044f91eb 100644 --- a/022_hands-on/02/11_hands-on/README.md +++ b/022_hands-on/02/11_hands-on/README.md @@ -1,6 +1,6 @@ # Building upon the code from the previous problem: -Before we WRITE our RESPONSE , let's WRITE to our RESPONSE the STATUS LINE and some REPONSE HEADERS. Remember the request line and status line: +Before we WRITE our RESPONSE, let's WRITE to our RESPONSE the STATUS LINE and some RESPONSE HEADERS. Remember the request line and status line: REQUEST LINE GET / HTTP/1.1 @@ -22,4 +22,4 @@ fmt.Fprint(c, "Content-Type: text/plain\r\n") "\r\n" -Look in your browser "developer tools" under the network tab. Compare the RESPONSE HEADERS from the previous file with the RESPONSE HEADERS in your new solution. \ No newline at end of file +Look in your browser "developer tools" under the network tab. Compare the RESPONSE HEADERS from the previous file with the RESPONSE HEADERS in your new solution. diff --git a/023_serving-files/02_serving/04_FileServer/01/main.go b/023_serving-files/02_serving/04_FileServer/01/main.go index 5ff93afd..34a0df2a 100644 --- a/023_serving-files/02_serving/04_FileServer/01/main.go +++ b/023_serving-files/02_serving/04_FileServer/01/main.go @@ -7,11 +7,11 @@ import ( func main() { http.Handle("/", http.FileServer(http.Dir("."))) - http.HandleFunc("/dog", dog) + http.HandleFunc("/dog/", dog) http.ListenAndServe(":8080", nil) } func dog(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/html; charset=utf-8") - io.WriteString(w, ``) + io.WriteString(w, ``) } diff --git a/023_serving-files/02_serving/04_FileServer/02/main.go b/023_serving-files/02_serving/04_FileServer/02/main.go index 2e190205..3a7a5ff0 100644 --- a/023_serving-files/02_serving/04_FileServer/02/main.go +++ b/023_serving-files/02_serving/04_FileServer/02/main.go @@ -15,3 +15,9 @@ func dog(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/html; charset=utf-8") io.WriteString(w, ``) } + +/* + +./assets/toby.jpg + +*/ diff --git a/024_hands-on/02_solution/dog.gohtml b/024_hands-on/02_solution/dog.gohtml old mode 100755 new mode 100644 diff --git a/024_hands-on/02_solution/main.go b/024_hands-on/02_solution/main.go old mode 100755 new mode 100644 diff --git a/024_hands-on/03_hands-on/starting-files/css/main.css b/024_hands-on/03_hands-on/starting-files/css/main.css old mode 100755 new mode 100644 diff --git a/024_hands-on/03_hands-on/starting-files/css/reset.css b/024_hands-on/03_hands-on/starting-files/css/reset.css old mode 100755 new mode 100644 diff --git a/024_hands-on/03_hands-on/starting-files/index.html b/024_hands-on/03_hands-on/starting-files/index.html old mode 100755 new mode 100644 diff --git a/024_hands-on/03_hands-on/starting-files/pic/surf.jpg b/024_hands-on/03_hands-on/starting-files/pic/surf.jpg old mode 100755 new mode 100644 diff --git a/024_hands-on/04_solution/css/main.css b/024_hands-on/04_solution/css/main.css old mode 100755 new mode 100644 diff --git a/024_hands-on/04_solution/css/reset.css b/024_hands-on/04_solution/css/reset.css old mode 100755 new mode 100644 diff --git a/024_hands-on/04_solution/index.html b/024_hands-on/04_solution/index.html old mode 100755 new mode 100644 diff --git a/024_hands-on/04_solution/main.go b/024_hands-on/04_solution/main.go old mode 100755 new mode 100644 diff --git a/024_hands-on/04_solution/pic/surf.jpg b/024_hands-on/04_solution/pic/surf.jpg old mode 100755 new mode 100644 diff --git a/024_hands-on/05_hands-on/starting-files/public/pics/dog.jpeg b/024_hands-on/05_hands-on/starting-files/public/pics/dog.jpeg old mode 100755 new mode 100644 diff --git a/024_hands-on/05_hands-on/starting-files/public/pics/dog1.jpeg b/024_hands-on/05_hands-on/starting-files/public/pics/dog1.jpeg old mode 100755 new mode 100644 diff --git a/024_hands-on/05_hands-on/starting-files/public/pics/dog2.jpeg b/024_hands-on/05_hands-on/starting-files/public/pics/dog2.jpeg old mode 100755 new mode 100644 diff --git a/024_hands-on/05_hands-on/starting-files/templates/index.gohtml b/024_hands-on/05_hands-on/starting-files/templates/index.gohtml old mode 100755 new mode 100644 diff --git a/024_hands-on/06_solution/main.go b/024_hands-on/06_solution/main.go old mode 100755 new mode 100644 diff --git a/024_hands-on/06_solution/public/pics/dog.jpeg b/024_hands-on/06_solution/public/pics/dog.jpeg old mode 100755 new mode 100644 diff --git a/024_hands-on/06_solution/public/pics/dog1.jpeg b/024_hands-on/06_solution/public/pics/dog1.jpeg old mode 100755 new mode 100644 diff --git a/024_hands-on/06_solution/public/pics/dog2.jpeg b/024_hands-on/06_solution/public/pics/dog2.jpeg old mode 100755 new mode 100644 diff --git a/024_hands-on/06_solution/templates/index.gohtml b/024_hands-on/06_solution/templates/index.gohtml old mode 100755 new mode 100644 diff --git a/024_hands-on/07_hands-on/starting-files/public/pics/dog.jpeg b/024_hands-on/07_hands-on/starting-files/public/pics/dog.jpeg old mode 100755 new mode 100644 diff --git a/024_hands-on/07_hands-on/starting-files/public/pics/dog1.jpeg b/024_hands-on/07_hands-on/starting-files/public/pics/dog1.jpeg old mode 100755 new mode 100644 diff --git a/024_hands-on/07_hands-on/starting-files/public/pics/dog2.jpeg b/024_hands-on/07_hands-on/starting-files/public/pics/dog2.jpeg old mode 100755 new mode 100644 diff --git a/024_hands-on/07_hands-on/starting-files/templates/index.gohtml b/024_hands-on/07_hands-on/starting-files/templates/index.gohtml old mode 100755 new mode 100644 diff --git a/024_hands-on/08_solution/main.go b/024_hands-on/08_solution/main.go old mode 100755 new mode 100644 diff --git a/024_hands-on/08_solution/public/pics/dog.jpeg b/024_hands-on/08_solution/public/pics/dog.jpeg old mode 100755 new mode 100644 diff --git a/024_hands-on/08_solution/public/pics/dog1.jpeg b/024_hands-on/08_solution/public/pics/dog1.jpeg old mode 100755 new mode 100644 diff --git a/024_hands-on/08_solution/public/pics/dog2.jpeg b/024_hands-on/08_solution/public/pics/dog2.jpeg old mode 100755 new mode 100644 diff --git a/024_hands-on/08_solution/templates/index.gohtml b/024_hands-on/08_solution/templates/index.gohtml old mode 100755 new mode 100644 diff --git a/024_hands-on/09_hands-on/starting-files/css/main.css b/024_hands-on/09_hands-on/starting-files/public/css/main.css old mode 100755 new mode 100644 similarity index 100% rename from 024_hands-on/09_hands-on/starting-files/css/main.css rename to 024_hands-on/09_hands-on/starting-files/public/css/main.css diff --git a/024_hands-on/09_hands-on/starting-files/css/reset.css b/024_hands-on/09_hands-on/starting-files/public/css/reset.css old mode 100755 new mode 100644 similarity index 100% rename from 024_hands-on/09_hands-on/starting-files/css/reset.css rename to 024_hands-on/09_hands-on/starting-files/public/css/reset.css diff --git a/024_hands-on/09_hands-on/starting-files/pic/surf.jpg b/024_hands-on/09_hands-on/starting-files/public/pic/surf.jpg old mode 100755 new mode 100644 similarity index 100% rename from 024_hands-on/09_hands-on/starting-files/pic/surf.jpg rename to 024_hands-on/09_hands-on/starting-files/public/pic/surf.jpg diff --git a/024_hands-on/09_hands-on/starting-files/index.html b/024_hands-on/09_hands-on/starting-files/templates/index.gohtml old mode 100755 new mode 100644 similarity index 95% rename from 024_hands-on/09_hands-on/starting-files/index.html rename to 024_hands-on/09_hands-on/starting-files/templates/index.gohtml index bcbd3c5b..cb39f57e --- a/024_hands-on/09_hands-on/starting-files/index.html +++ b/024_hands-on/09_hands-on/starting-files/templates/index.gohtml @@ -3,12 +3,12 @@ - - + + -A man surfing a wave +A man surfing a wave diff --git a/024_hands-on/10_solution/main.go b/024_hands-on/10_solution/main.go old mode 100755 new mode 100644 diff --git a/024_hands-on/10_solution/public/css/main.css b/024_hands-on/10_solution/public/css/main.css old mode 100755 new mode 100644 diff --git a/024_hands-on/10_solution/public/css/reset.css b/024_hands-on/10_solution/public/css/reset.css old mode 100755 new mode 100644 diff --git a/024_hands-on/10_solution/public/pic/surf.jpg b/024_hands-on/10_solution/public/pic/surf.jpg old mode 100755 new mode 100644 diff --git a/024_hands-on/10_solution/templates/index.gohtml b/024_hands-on/10_solution/templates/index.gohtml old mode 100755 new mode 100644 diff --git a/024_hands-on/12_solution/main.go b/024_hands-on/12_solution/main.go index 8f8bf128..7e59a3e7 100644 --- a/024_hands-on/12_solution/main.go +++ b/024_hands-on/12_solution/main.go @@ -14,8 +14,8 @@ func init() { func main() { http.HandleFunc("/", index) - http.HandleFunc("/about", about) - http.HandleFunc("/contact", contact) + http.HandleFunc("/about/", about) + http.HandleFunc("/contact/", contact) http.HandleFunc("/apply", apply) http.ListenAndServe(":8080", nil) } diff --git a/025_NotFoundHandler/main.go b/025_NotFoundHandler/01/main.go old mode 100755 new mode 100644 similarity index 100% rename from 025_NotFoundHandler/main.go rename to 025_NotFoundHandler/01/main.go diff --git a/025_NotFoundHandler/02/README.md b/025_NotFoundHandler/02/README.md new file mode 100644 index 00000000..a6ceb499 --- /dev/null +++ b/025_NotFoundHandler/02/README.md @@ -0,0 +1 @@ +This file was added after the course was recorded to show you func NotFound(w ResponseWriter, r *Request) \ No newline at end of file diff --git a/025_NotFoundHandler/02/main.go b/025_NotFoundHandler/02/main.go new file mode 100644 index 00000000..64e8e815 --- /dev/null +++ b/025_NotFoundHandler/02/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + "net/http" +) + +func main() { + http.HandleFunc("/", foo) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func foo(w http.ResponseWriter, req *http.Request) { + if req.URL.Path != "/" { + http.NotFound(w, req) + return + } + fmt.Println(req.URL.Path) + fmt.Fprintln(w, "go look at your terminal") +} diff --git a/026_appengine-deploy/01/app.yaml b/026_appengine-deploy/01/app.yaml index 1dd8f1c6..fb82ec67 100644 --- a/026_appengine-deploy/01/app.yaml +++ b/026_appengine-deploy/01/app.yaml @@ -1,8 +1,6 @@ -application: temp-145415 -version: 1 -runtime: go -api_version: go1 +runtime: go113 handlers: - url: /.* - script: _go_app \ No newline at end of file + script: auto + secure: always \ No newline at end of file diff --git a/026_appengine-deploy/01/main.go b/026_appengine-deploy/01/main.go index 68523458..671d6b1d 100644 --- a/026_appengine-deploy/01/main.go +++ b/026_appengine-deploy/01/main.go @@ -4,6 +4,7 @@ import ( "net/http" ) -func init() { +func main() { http.Handle("/", http.FileServer(http.Dir("."))) + http.ListenAndServe(":8080", nil) } diff --git a/026_appengine-deploy/02/app.yaml b/026_appengine-deploy/02/app.yaml index 1dd8f1c6..fb82ec67 100644 --- a/026_appengine-deploy/02/app.yaml +++ b/026_appengine-deploy/02/app.yaml @@ -1,8 +1,6 @@ -application: temp-145415 -version: 1 -runtime: go -api_version: go1 +runtime: go113 handlers: - url: /.* - script: _go_app \ No newline at end of file + script: auto + secure: always \ No newline at end of file diff --git a/026_appengine-deploy/02/main.go b/026_appengine-deploy/02/main.go index 68523458..671d6b1d 100644 --- a/026_appengine-deploy/02/main.go +++ b/026_appengine-deploy/02/main.go @@ -4,6 +4,7 @@ import ( "net/http" ) -func init() { +func main() { http.Handle("/", http.FileServer(http.Dir("."))) + http.ListenAndServe(":8080", nil) } diff --git a/026_appengine-deploy/README.md b/026_appengine-deploy/README.md index 247ba1be..c256d787 100644 --- a/026_appengine-deploy/README.md +++ b/026_appengine-deploy/README.md @@ -1,30 +1,27 @@ -# buying a domain + # buying a domain https://domains.google/#/ # deploying to [Google Cloud](https://cloud.google.com/) - [install google appengine](https://cloud.google.com/appengine/docs/go/download) -- [make sure python is installed VERSION 2.7.x](https://www.python.org/downloads/release/python-2712/) - - python -V - configure environment PATH variables - google cloud developer console - create a project - get the project ID -- update the app.yaml file with your project ID +- set your go version in the app.yaml file ``` -application: temp-137512 -version: 1 -runtime: go -api_version: go1 - +runtime: go113 handlers: - url: /.* - script: _go_app + script: auto + secure: always ``` -- deploy to that project +- deploy to that project. update --project with your project-id ``` -appcfg.py -A -V v1 update . +gcloud app deploy app.yaml --project= -v 1 +my example: +gcloud app deploy --project temp-137512 ``` - view your project - http://YOUR_PROJECT_ID.appspot.com/ diff --git a/027_passing-data/01_url/main.go b/027_passing-data/01_url/main.go old mode 100755 new mode 100644 diff --git a/027_passing-data/02_form-post/main.go b/027_passing-data/02_form-post/main.go old mode 100755 new mode 100644 diff --git a/027_passing-data/03_form-get/main.go b/027_passing-data/03_form-get/main.go old mode 100755 new mode 100644 diff --git a/027_passing-data/04_form/main.go b/027_passing-data/04_form/main.go old mode 100755 new mode 100644 diff --git a/027_passing-data/04_form/templates/index.gohtml b/027_passing-data/04_form/templates/index.gohtml old mode 100755 new mode 100644 diff --git a/027_passing-data/05_form-file/01_read/example.txt b/027_passing-data/05_form-file/01_read/example.txt old mode 100755 new mode 100644 diff --git a/027_passing-data/05_form-file/01_read/main.go b/027_passing-data/05_form-file/01_read/main.go old mode 100755 new mode 100644 diff --git a/027_passing-data/05_form-file/02_store/main.go b/027_passing-data/05_form-file/02_store/main.go old mode 100755 new mode 100644 index 1d5ba06f..61b709e0 --- a/027_passing-data/05_form-file/02_store/main.go +++ b/027_passing-data/05_form-file/02_store/main.go @@ -56,6 +56,7 @@ func foo(w http.ResponseWriter, req *http.Request) { _, err = dst.Write(bs) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) + return } } diff --git a/027_passing-data/05_form-file/02_store/templates/index.gohtml b/027_passing-data/05_form-file/02_store/templates/index.gohtml old mode 100755 new mode 100644 diff --git a/027_passing-data/05_form-file/02_store/user/between-father-and-son.txt b/027_passing-data/05_form-file/02_store/user/between-father-and-son.txt deleted file mode 100644 index fd8ff5d8..00000000 --- a/027_passing-data/05_form-file/02_store/user/between-father-and-son.txt +++ /dev/null @@ -1,26 +0,0 @@ -The moonlight was still there, on the dashboard, -though the driver's side window was broken -and my wife's purse was gone. - -The thief, -what else did he take? - -Perhaps the childhood of someone -who wasn't raised well, a young man -without the good fortune to receive guidance -or to be helped with his homework -or to be directed towards school. - -Perhaps the thief took the love too -that this young man was meant to receive. - -I think of Hank and Jodi -with a grandchild -who has leukemia. - -We drive home with the heat on. -The air at night in winter is cold. - -What is a purse, -what is a broken window, -when compared to these things? \ No newline at end of file diff --git a/027_passing-data/README.md b/027_passing-data/README.md index 4d54b04e..8865ff2f 100644 --- a/027_passing-data/README.md +++ b/027_passing-data/README.md @@ -4,7 +4,7 @@ We can pass values from the client to the server through the URL or through the body of the request. -When you submit a form, you can use either the "POST" or "get" method. The "POST" method sends the form submission through the body of the request. The "get" method for a form submission sends the form submission values through the url. +When you submit a form, you can use either the "POST" or "GET" method. The "POST" method sends the form submission through the body of the request. The "GET" method for a form submission sends the form submission values through the url. I remember this like this: diff --git a/028_redirect/take-a-look-at-this.html b/028_redirect/status-codes.html old mode 100755 new mode 100644 similarity index 100% rename from 028_redirect/take-a-look-at-this.html rename to 028_redirect/status-codes.html diff --git a/029_cookies/01_set_get/main.go b/029_cookies/01_set_get/main.go old mode 100755 new mode 100644 index 035b772e..69873249 --- a/029_cookies/01_set_get/main.go +++ b/029_cookies/01_set_get/main.go @@ -16,6 +16,7 @@ func set(w http.ResponseWriter, req *http.Request) { http.SetCookie(w, &http.Cookie{ Name: "my-cookie", Value: "some value", + Path: "/", }) fmt.Fprintln(w, "COOKIE WRITTEN - CHECK YOUR BROWSER") fmt.Fprintln(w, "in chrome go to: dev tools / application / cookies") @@ -25,7 +26,7 @@ func read(w http.ResponseWriter, req *http.Request) { c, err := req.Cookie("my-cookie") if err != nil { - http.Error(w, err.Error(), http.StatusNotFound) + http.Error(w, http.StatusText(400), http.StatusBadRequest) return } diff --git a/029_cookies/02_multiple/main.go b/029_cookies/02_multiple/main.go old mode 100755 new mode 100644 index e08b2fcc..379d69d2 --- a/029_cookies/02_multiple/main.go +++ b/029_cookies/02_multiple/main.go @@ -18,6 +18,7 @@ func set(w http.ResponseWriter, req *http.Request) { http.SetCookie(w, &http.Cookie{ Name: "my-cookie", Value: "some value", + Path: "/", }) fmt.Fprintln(w, "COOKIE WRITTEN - CHECK YOUR BROWSER") fmt.Fprintln(w, "in chrome go to: dev tools / application / cookies") diff --git a/029_cookies/03_hands-on/README.md b/029_cookies/03_hands-on/README.md index 7319a52d..01b97f4d 100644 --- a/029_cookies/03_hands-on/README.md +++ b/029_cookies/03_hands-on/README.md @@ -1 +1,36 @@ -Using cookies, track how many times a user has been to your website domain. \ No newline at end of file +package main + +import ( + "fmt" + "net/http" +) + +func main() { + http.HandleFunc("/", set) + http.HandleFunc("/read", read) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func set(w http.ResponseWriter, req *http.Request) { + http.SetCookie(w, &http.Cookie{ + Name: "my-cookie", + Value: "some value", + Path: "/", + }) + fmt.Fprintln(w, "COOKIE WRITTEN - CHECK YOUR BROWSER") + fmt.Fprintln(w, "in chrome go to: dev tools / application / cookies") +} + +func read(w http.ResponseWriter, req *http.Request) { + + c, err := req.Cookie("my-cookie") + if err != nil { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + fmt.Fprintln(w, "YOUR COOKIE:", c) +} + +// Using cookies, track how many times a user has been to your website domain. \ No newline at end of file diff --git a/029_cookies/04_solution/main.go b/029_cookies/04_solution/main.go index 89b03c44..653ef59b 100644 --- a/029_cookies/04_solution/main.go +++ b/029_cookies/04_solution/main.go @@ -21,6 +21,7 @@ func foo(res http.ResponseWriter, req *http.Request) { cookie = &http.Cookie{ Name: "my-cookie", Value: "0", + Path: "/", } } diff --git a/029_cookies/05_maxage/main.go b/029_cookies/05_maxage/main.go index 0b095752..2c8373c5 100644 --- a/029_cookies/05_maxage/main.go +++ b/029_cookies/05_maxage/main.go @@ -21,6 +21,7 @@ func set(w http.ResponseWriter, req *http.Request) { http.SetCookie(w, &http.Cookie{ Name: "session", Value: "some value", + Path: "/", }) fmt.Fprintln(w, `

read

`) } diff --git a/029_cookies/06_path/01/main.go b/029_cookies/06_path/01/main.go new file mode 100644 index 00000000..2c63a06f --- /dev/null +++ b/029_cookies/06_path/01/main.go @@ -0,0 +1,46 @@ +package main + +import ( + "fmt" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/users/goofy", set) + http.HandleFunc("/users/goofy/read", read) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, req *http.Request) { + c, err := req.Cookie("my-cookie") + if err != nil { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + fmt.Println(c) + fmt.Fprintln(w, "YOUR COOKIE:", c) +} + +func set(w http.ResponseWriter, req *http.Request) { + c := &http.Cookie{ + Name: "my-cookie", + Value: "some value", + } + http.SetCookie(w, c) + fmt.Println(c) + fmt.Fprintln(w, "YOUR COOKIE:", c) + fmt.Fprintln(w, "COOKIE WRITTEN - CHECK YOUR BROWSER") + fmt.Fprintln(w, "in chrome go to: dev tools / application / cookies") +} + +func read(w http.ResponseWriter, req *http.Request) { + c, err := req.Cookie("my-cookie") + if err != nil { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + fmt.Fprintln(w, "YOUR COOKIE:", c) +} diff --git a/029_cookies/06_path/02/main.go b/029_cookies/06_path/02/main.go new file mode 100644 index 00000000..efbb7027 --- /dev/null +++ b/029_cookies/06_path/02/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/users/goofy", set) + http.HandleFunc("/users/goofy/read", read) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, req *http.Request) { + c, err := req.Cookie("my-cookie") + if err != nil { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + fmt.Println(c) + fmt.Fprintln(w, "YOUR COOKIE:", c) +} + +func set(w http.ResponseWriter, req *http.Request) { + c := &http.Cookie{ + Name: "my-cookie", + Value: "some value", + Path: "/", + } + http.SetCookie(w, c) + fmt.Println(c) + fmt.Fprintln(w, "YOUR COOKIE:", c) + fmt.Fprintln(w, "COOKIE WRITTEN - CHECK YOUR BROWSER") + fmt.Fprintln(w, "in chrome go to: dev tools / application / cookies") +} + +func read(w http.ResponseWriter, req *http.Request) { + c, err := req.Cookie("my-cookie") + if err != nil { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + fmt.Fprintln(w, "YOUR COOKIE:", c) +} diff --git a/029_cookies/06_path/03_templates/01/main.go b/029_cookies/06_path/03_templates/01/main.go new file mode 100644 index 00000000..ce846b2d --- /dev/null +++ b/029_cookies/06_path/03_templates/01/main.go @@ -0,0 +1,59 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/dog/bowzer", bowzer) + http.HandleFunc("/dog/bowzer/pictures", bowzerpics) + http.HandleFunc("/cat", cat) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + var c *http.Cookie + c, err := r.Cookie("user-cookie") + if err != nil { + fmt.Println(err) + fmt.Printf("%T\n", c) + } + tpl.ExecuteTemplate(w, "index.gohtml", c) +} + +func bowzer(w http.ResponseWriter, r *http.Request) { + c := &http.Cookie{ + Name: "user-cookie", + Value: "this would be the value", + Path: "/dog/bowzer", + } + http.SetCookie(w, c) + tpl.ExecuteTemplate(w, "bowzer.gohtml", c) +} + +func bowzerpics(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("user-cookie") + if err != nil { + fmt.Println(err) + fmt.Printf("%T\n", c) + } + tpl.ExecuteTemplate(w, "bowzerpics.gohtml", c) +} + +func cat(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("user-cookie") + if err != nil { + fmt.Println(err) + fmt.Printf("%T\n", c) + } + tpl.ExecuteTemplate(w, "cat.gohtml", c) +} diff --git a/029_cookies/06_path/03_templates/01/templates/bowzer.gohtml b/029_cookies/06_path/03_templates/01/templates/bowzer.gohtml new file mode 100644 index 00000000..55eca3fc --- /dev/null +++ b/029_cookies/06_path/03_templates/01/templates/bowzer.gohtml @@ -0,0 +1,26 @@ + + + + + + + Bowzer + + + +

Bowzer

+ + +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + + \ No newline at end of file diff --git a/029_cookies/06_path/03_templates/01/templates/bowzerpics.gohtml b/029_cookies/06_path/03_templates/01/templates/bowzerpics.gohtml new file mode 100644 index 00000000..d97a5bfa --- /dev/null +++ b/029_cookies/06_path/03_templates/01/templates/bowzerpics.gohtml @@ -0,0 +1,24 @@ + + + + + + + Bowzer Pics + + + +

Bowzer Pics

+ +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + \ No newline at end of file diff --git a/029_cookies/06_path/03_templates/01/templates/cat.gohtml b/029_cookies/06_path/03_templates/01/templates/cat.gohtml new file mode 100644 index 00000000..0629e8ad --- /dev/null +++ b/029_cookies/06_path/03_templates/01/templates/cat.gohtml @@ -0,0 +1,24 @@ + + + + + + + Cat + + + +

Cat

+ +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + \ No newline at end of file diff --git a/029_cookies/06_path/03_templates/01/templates/index.gohtml b/029_cookies/06_path/03_templates/01/templates/index.gohtml new file mode 100644 index 00000000..3da06dc0 --- /dev/null +++ b/029_cookies/06_path/03_templates/01/templates/index.gohtml @@ -0,0 +1,24 @@ + + + + + + + Document + + + +

Index

+ +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + \ No newline at end of file diff --git a/029_cookies/06_path/03_templates/02/main.go b/029_cookies/06_path/03_templates/02/main.go new file mode 100644 index 00000000..b504073a --- /dev/null +++ b/029_cookies/06_path/03_templates/02/main.go @@ -0,0 +1,60 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/dog/bowzer", bowzer) + http.HandleFunc("/dog/bowzer/pictures", bowzerpics) + http.HandleFunc("/cat", cat) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + var c *http.Cookie + c, err := r.Cookie("user-cookie") + if err != nil { + fmt.Println(err) + fmt.Printf("%T\n", c) + } + tpl.ExecuteTemplate(w, "index.gohtml", c) +} + +func bowzer(w http.ResponseWriter, r *http.Request) { + c := &http.Cookie{ + Name: "user-cookie", + Value: "this would be the value", + Path: "/", + //Path: "/dog/bowzer/", + } + http.SetCookie(w, c) + tpl.ExecuteTemplate(w, "bowzer.gohtml", c) +} + +func bowzerpics(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("user-cookie") + if err != nil { + fmt.Println(err) + fmt.Printf("%T\n", c) + } + tpl.ExecuteTemplate(w, "bowzerpics.gohtml", c) +} + +func cat(w http.ResponseWriter, r *http.Request) { + c, err := r.Cookie("user-cookie") + if err != nil { + fmt.Println(err) + fmt.Printf("%T\n", c) + } + tpl.ExecuteTemplate(w, "cat.gohtml", c) +} diff --git a/029_cookies/06_path/03_templates/02/templates/bowzer.gohtml b/029_cookies/06_path/03_templates/02/templates/bowzer.gohtml new file mode 100644 index 00000000..55eca3fc --- /dev/null +++ b/029_cookies/06_path/03_templates/02/templates/bowzer.gohtml @@ -0,0 +1,26 @@ + + + + + + + Bowzer + + + +

Bowzer

+ + +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + + \ No newline at end of file diff --git a/029_cookies/06_path/03_templates/02/templates/bowzerpics.gohtml b/029_cookies/06_path/03_templates/02/templates/bowzerpics.gohtml new file mode 100644 index 00000000..d97a5bfa --- /dev/null +++ b/029_cookies/06_path/03_templates/02/templates/bowzerpics.gohtml @@ -0,0 +1,24 @@ + + + + + + + Bowzer Pics + + + +

Bowzer Pics

+ +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + \ No newline at end of file diff --git a/029_cookies/06_path/03_templates/02/templates/cat.gohtml b/029_cookies/06_path/03_templates/02/templates/cat.gohtml new file mode 100644 index 00000000..0629e8ad --- /dev/null +++ b/029_cookies/06_path/03_templates/02/templates/cat.gohtml @@ -0,0 +1,24 @@ + + + + + + + Cat + + + +

Cat

+ +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + \ No newline at end of file diff --git a/029_cookies/06_path/03_templates/02/templates/index.gohtml b/029_cookies/06_path/03_templates/02/templates/index.gohtml new file mode 100644 index 00000000..3da06dc0 --- /dev/null +++ b/029_cookies/06_path/03_templates/02/templates/index.gohtml @@ -0,0 +1,24 @@ + + + + + + + Document + + + +

Index

+ +{{if .}} +

Here is the cookie

+

Name: {{.Name}}

+

Value: {{.Value}}

+

Path: {{.Path}}

+{{else}} +

There is no cookie

+{{end}} + + + \ No newline at end of file diff --git a/029_cookies/06_path/README.md b/029_cookies/06_path/README.md new file mode 100644 index 00000000..4f1f7784 --- /dev/null +++ b/029_cookies/06_path/README.md @@ -0,0 +1,5 @@ +I created these "06_path" files after the course was recorded. + +To see these files explained, watch this video. + +[https://www.youtube.com/watch?v=Corx3O9QZmk](https://www.youtube.com/watch?v=Corx3O9QZmk) \ No newline at end of file diff --git a/030_sessions/01_uuid/main.go b/030_sessions/01_uuid/main.go old mode 100755 new mode 100644 index 011f28e9..ad36b1f6 --- a/030_sessions/01_uuid/main.go +++ b/030_sessions/01_uuid/main.go @@ -24,6 +24,7 @@ func index(w http.ResponseWriter, req *http.Request) { Value: id.String(), // Secure: true, HttpOnly: true, + Path: "/", } http.SetCookie(w, cookie) } diff --git a/030_sessions/02_session/main.go b/030_sessions/02_session/main.go index 8a47f068..bda843e9 100644 --- a/030_sessions/02_session/main.go +++ b/030_sessions/02_session/main.go @@ -32,7 +32,7 @@ func index(w http.ResponseWriter, req *http.Request) { // get cookie c, err := req.Cookie("session") if err != nil { - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c = &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/030_sessions/03_signup/main.go b/030_sessions/03_signup/main.go index d086bdfd..48f0d58c 100644 --- a/030_sessions/03_signup/main.go +++ b/030_sessions/03_signup/main.go @@ -1,9 +1,10 @@ package main import ( - "github.com/satori/go.uuid" "html/template" "net/http" + + uuid "github.com/satori/go.uuid" ) type user struct { @@ -30,12 +31,12 @@ func main() { } func index(w http.ResponseWriter, req *http.Request) { - u := getUser(w, req) + u := getUser(req) tpl.ExecuteTemplate(w, "index.gohtml", u) } func bar(w http.ResponseWriter, req *http.Request) { - u := getUser(w, req) + u := getUser(req) if !alreadyLoggedIn(req) { http.Redirect(w, req, "/", http.StatusSeeOther) return @@ -65,7 +66,7 @@ func signup(w http.ResponseWriter, req *http.Request) { } // create session - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c := &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/030_sessions/03_signup/session.go b/030_sessions/03_signup/session.go index d524baac..bda111e9 100644 --- a/030_sessions/03_signup/session.go +++ b/030_sessions/03_signup/session.go @@ -1,25 +1,19 @@ package main import ( - "github.com/satori/go.uuid" "net/http" ) -func getUser(w http.ResponseWriter, req *http.Request) user { +func getUser(req *http.Request) user { + var u user + // get cookie c, err := req.Cookie("session") if err != nil { - sID := uuid.NewV4() - c = &http.Cookie{ - Name: "session", - Value: sID.String(), - } - + return u } - http.SetCookie(w, c) // if the user exists already, get user - var u user if un, ok := dbSessions[c.Value]; ok { u = dbUsers[un] } diff --git a/030_sessions/04_bcrypt/main.go b/030_sessions/04_bcrypt/main.go index 4a6f6dd7..f6d55904 100644 --- a/030_sessions/04_bcrypt/main.go +++ b/030_sessions/04_bcrypt/main.go @@ -68,7 +68,7 @@ func signup(w http.ResponseWriter, req *http.Request) { } // create session - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c := &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/030_sessions/04_bcrypt/session.go b/030_sessions/04_bcrypt/session.go index d524baac..81c2e627 100644 --- a/030_sessions/04_bcrypt/session.go +++ b/030_sessions/04_bcrypt/session.go @@ -9,7 +9,7 @@ func getUser(w http.ResponseWriter, req *http.Request) user { // get cookie c, err := req.Cookie("session") if err != nil { - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c = &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/030_sessions/05_login/main.go b/030_sessions/05_login/main.go index 20928181..9f3b6c56 100644 --- a/030_sessions/05_login/main.go +++ b/030_sessions/05_login/main.go @@ -66,7 +66,7 @@ func signup(w http.ResponseWriter, req *http.Request) { return } // create session - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c := &http.Cookie{ Name: "session", Value: sID.String(), @@ -111,7 +111,7 @@ func login(w http.ResponseWriter, req *http.Request) { return } // create session - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c := &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/030_sessions/05_login/session.go b/030_sessions/05_login/session.go index d524baac..81c2e627 100644 --- a/030_sessions/05_login/session.go +++ b/030_sessions/05_login/session.go @@ -9,7 +9,7 @@ func getUser(w http.ResponseWriter, req *http.Request) user { // get cookie c, err := req.Cookie("session") if err != nil { - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c = &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/030_sessions/06_logout/main.go b/030_sessions/06_logout/main.go index 223db65a..a6cfbd2b 100644 --- a/030_sessions/06_logout/main.go +++ b/030_sessions/06_logout/main.go @@ -67,7 +67,7 @@ func signup(w http.ResponseWriter, req *http.Request) { return } // create session - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c := &http.Cookie{ Name: "session", Value: sID.String(), @@ -112,7 +112,7 @@ func login(w http.ResponseWriter, req *http.Request) { return } // create session - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c := &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/030_sessions/06_logout/session.go b/030_sessions/06_logout/session.go index d524baac..81c2e627 100644 --- a/030_sessions/06_logout/session.go +++ b/030_sessions/06_logout/session.go @@ -9,7 +9,7 @@ func getUser(w http.ResponseWriter, req *http.Request) user { // get cookie c, err := req.Cookie("session") if err != nil { - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c = &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/030_sessions/07_permissions/main.go b/030_sessions/07_permissions/main.go index 24a1d297..6cb1eb32 100644 --- a/030_sessions/07_permissions/main.go +++ b/030_sessions/07_permissions/main.go @@ -71,7 +71,7 @@ func signup(w http.ResponseWriter, req *http.Request) { return } // create session - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c := &http.Cookie{ Name: "session", Value: sID.String(), @@ -116,7 +116,7 @@ func login(w http.ResponseWriter, req *http.Request) { return } // create session - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c := &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/030_sessions/07_permissions/session.go b/030_sessions/07_permissions/session.go index d524baac..81c2e627 100644 --- a/030_sessions/07_permissions/session.go +++ b/030_sessions/07_permissions/session.go @@ -9,7 +9,7 @@ func getUser(w http.ResponseWriter, req *http.Request) user { // get cookie c, err := req.Cookie("session") if err != nil { - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c = &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/030_sessions/08_expire-session/README.md b/030_sessions/08_expire-session/README.md new file mode 100644 index 00000000..1ea4b86a --- /dev/null +++ b/030_sessions/08_expire-session/README.md @@ -0,0 +1,69 @@ +# Concurrency & Race Conditions + +## Could this code cause a race condition? + +``` +go cleanSessions() +``` + +``` +func cleanSessions() { + for k, v := range dbSessions { + if time.Now().Sub(v.lastActivity) > (time.Second * 30) { + delete(dbSessions, k) + } + } + dbSessionsCleaned = time.Now() +} + +``` + +https://golang.org/doc/go1.6 says: + +"The runtime has added lightweight, best-effort detection of concurrent misuse of maps. As always, if one goroutine is writing to a map, no other goroutine should be reading or writing the map concurrently. If the runtime detects this condition, it prints a diagnosis and crashes the program. The best way to find out more about the problem is to run the program under the race detector, which will more reliably identify the race and give more detail." + +When you + +``` +go build -race +``` + +you do not get a race condition reported. + + +![no race condition](norace.png) + +So if you're not writing to a map, you can use the map concurrently without a problem. + +RE: time.Time + +"A Time value can be used by multiple goroutines simultaneously." + +https://godoc.org/time#Time + +## Expanding on maps & goroutines + +Maps are funky. + +Check this out: + +![maps are funky](maps.png) + + +https://play.golang.org/p/62DF4xvPeQ + +**So you can delete something that doesn't exist, and that is not a problem.** + +**And you can ask for something that isn't there, and that is not a problem (gives you the zero value for the map's value).** + +Deleting IS DIFFERENT from writing. + +**If more than 1 goroutine tried to delete that same entry in the map: no problem.** + +**And if you're reading from the map and a value isn't there: no problem.** + +So why is WRITING a problem with concurrency? + +The classic race condition example is two routines READING, pulling the same value, each incrementing the value, and then each WRITING the incremented value back, and the value is incremented only 1, instead of 2. + +Just remember: WRITE TO MAP = concurrency considerations. \ No newline at end of file diff --git a/030_sessions/08_expire-session/main.go b/030_sessions/08_expire-session/main.go index 0e4972b3..690231d9 100644 --- a/030_sessions/08_expire-session/main.go +++ b/030_sessions/08_expire-session/main.go @@ -83,7 +83,7 @@ func signup(w http.ResponseWriter, req *http.Request) { return } // create session - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c := &http.Cookie{ Name: "session", Value: sID.String(), @@ -130,7 +130,7 @@ func login(w http.ResponseWriter, req *http.Request) { return } // create session - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c := &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/030_sessions/08_expire-session/maps.png b/030_sessions/08_expire-session/maps.png new file mode 100644 index 00000000..6544facc Binary files /dev/null and b/030_sessions/08_expire-session/maps.png differ diff --git a/030_sessions/08_expire-session/norace.png b/030_sessions/08_expire-session/norace.png new file mode 100644 index 00000000..e3f6f33e Binary files /dev/null and b/030_sessions/08_expire-session/norace.png differ diff --git a/030_sessions/08_expire-session/session.go b/030_sessions/08_expire-session/session.go index 45f272d6..94488c1b 100644 --- a/030_sessions/08_expire-session/session.go +++ b/030_sessions/08_expire-session/session.go @@ -11,7 +11,7 @@ func getUser(w http.ResponseWriter, req *http.Request) user { // get cookie c, err := req.Cookie("session") if err != nil { - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c = &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/030_sessions/09_middleware/README.md b/030_sessions/09_middleware/README.md new file mode 100644 index 00000000..1ea4b86a --- /dev/null +++ b/030_sessions/09_middleware/README.md @@ -0,0 +1,69 @@ +# Concurrency & Race Conditions + +## Could this code cause a race condition? + +``` +go cleanSessions() +``` + +``` +func cleanSessions() { + for k, v := range dbSessions { + if time.Now().Sub(v.lastActivity) > (time.Second * 30) { + delete(dbSessions, k) + } + } + dbSessionsCleaned = time.Now() +} + +``` + +https://golang.org/doc/go1.6 says: + +"The runtime has added lightweight, best-effort detection of concurrent misuse of maps. As always, if one goroutine is writing to a map, no other goroutine should be reading or writing the map concurrently. If the runtime detects this condition, it prints a diagnosis and crashes the program. The best way to find out more about the problem is to run the program under the race detector, which will more reliably identify the race and give more detail." + +When you + +``` +go build -race +``` + +you do not get a race condition reported. + + +![no race condition](norace.png) + +So if you're not writing to a map, you can use the map concurrently without a problem. + +RE: time.Time + +"A Time value can be used by multiple goroutines simultaneously." + +https://godoc.org/time#Time + +## Expanding on maps & goroutines + +Maps are funky. + +Check this out: + +![maps are funky](maps.png) + + +https://play.golang.org/p/62DF4xvPeQ + +**So you can delete something that doesn't exist, and that is not a problem.** + +**And you can ask for something that isn't there, and that is not a problem (gives you the zero value for the map's value).** + +Deleting IS DIFFERENT from writing. + +**If more than 1 goroutine tried to delete that same entry in the map: no problem.** + +**And if you're reading from the map and a value isn't there: no problem.** + +So why is WRITING a problem with concurrency? + +The classic race condition example is two routines READING, pulling the same value, each incrementing the value, and then each WRITING the incremented value back, and the value is incremented only 1, instead of 2. + +Just remember: WRITE TO MAP = concurrency considerations. \ No newline at end of file diff --git a/030_sessions/09_middleware/main.go b/030_sessions/09_middleware/main.go new file mode 100644 index 00000000..21cfaedd --- /dev/null +++ b/030_sessions/09_middleware/main.go @@ -0,0 +1,177 @@ +package main + +import ( + "github.com/satori/go.uuid" + "golang.org/x/crypto/bcrypt" + "html/template" + "net/http" + "time" +) + +type user struct { + UserName string + Password []byte + First string + Last string + Role string +} + +type session struct { + un string + lastActivity time.Time +} + +var tpl *template.Template +var dbUsers = map[string]user{} // user ID, user +var dbSessions = map[string]session{} // session ID, session +var dbSessionsCleaned time.Time + +const sessionLength int = 30 + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) + dbSessionsCleaned = time.Now() +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/bar", bar) + http.HandleFunc("/signup", signup) + http.HandleFunc("/login", login) + http.HandleFunc("/logout", authorized(logout)) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, req *http.Request) { + u := getUser(w, req) + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "index.gohtml", u) +} + +func bar(w http.ResponseWriter, req *http.Request) { + u := getUser(w, req) + if !alreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + if u.Role != "007" { + http.Error(w, "You must be 007 to enter the bar", http.StatusForbidden) + return + } + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "bar.gohtml", u) +} + +func signup(w http.ResponseWriter, req *http.Request) { + if alreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + var u user + // process form submission + if req.Method == http.MethodPost { + // get form values + un := req.FormValue("username") + p := req.FormValue("password") + f := req.FormValue("firstname") + l := req.FormValue("lastname") + r := req.FormValue("role") + // username taken? + if _, ok := dbUsers[un]; ok { + http.Error(w, "Username already taken", http.StatusForbidden) + return + } + // create session + sID, _ := uuid.NewV4() + c := &http.Cookie{ + Name: "session", + Value: sID.String(), + } + c.MaxAge = sessionLength + http.SetCookie(w, c) + dbSessions[c.Value] = session{un, time.Now()} + // store user in dbUsers + bs, err := bcrypt.GenerateFromPassword([]byte(p), bcrypt.MinCost) + if err != nil { + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } + u = user{un, bs, f, l, r} + dbUsers[un] = u + // redirect + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "signup.gohtml", u) +} + +func login(w http.ResponseWriter, req *http.Request) { + if alreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + var u user + // process form submission + if req.Method == http.MethodPost { + un := req.FormValue("username") + p := req.FormValue("password") + // is there a username? + u, ok := dbUsers[un] + if !ok { + http.Error(w, "Username and/or password do not match", http.StatusForbidden) + return + } + // does the entered password match the stored password? + err := bcrypt.CompareHashAndPassword(u.Password, []byte(p)) + if err != nil { + http.Error(w, "Username and/or password do not match", http.StatusForbidden) + return + } + // create session + sID, _ := uuid.NewV4() + c := &http.Cookie{ + Name: "session", + Value: sID.String(), + } + c.MaxAge = sessionLength + http.SetCookie(w, c) + dbSessions[c.Value] = session{un, time.Now()} + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "login.gohtml", u) +} + +func logout(w http.ResponseWriter, req *http.Request) { + c, _ := req.Cookie("session") + // delete the session + delete(dbSessions, c.Value) + // remove the cookie + c = &http.Cookie{ + Name: "session", + Value: "", + MaxAge: -1, + } + http.SetCookie(w, c) + + // clean up dbSessions + if time.Now().Sub(dbSessionsCleaned) > (time.Second * 30) { + go cleanSessions() + } + + http.Redirect(w, req, "/login", http.StatusSeeOther) +} + +func authorized(h http.HandlerFunc) http.HandlerFunc { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if !alreadyLoggedIn(w, r) { + //http.Error(w, "not logged in", http.StatusUnauthorized) + http.Redirect(w, r, "/", http.StatusSeeOther) + return // don't call original handler + } + h.ServeHTTP(w, r) + }) +} diff --git a/030_sessions/09_middleware/notes.md b/030_sessions/09_middleware/notes.md new file mode 100644 index 00000000..60f20260 --- /dev/null +++ b/030_sessions/09_middleware/notes.md @@ -0,0 +1,26 @@ +# Step 1: +Created type session which is a struct with a lastActivity field. This will allow us to know the last time a session was used. + +# Step 2: +Updated dbSessions to be of type map[string]session + +# Step 3: +Updated all reads/writes to dbSessions + +# Step 4: +Apply the MaxAge field to cookie + +# Step 5: +Updated func alreadyLoggedIn to be able to set a cookie, adding the ResponseWriter to its parameters + +``` +func alreadyLoggedIn(w http.ResponseWriter, req *http.Request) bool { +``` + +# Step 6: +Added dbSessionsCleaned time.Time to keep track of the last time we cleaned out our sessions. + +# Step 7: +Added func cleanSessions to remove unused sessions from dbSessions. Set it to run whenever someone logs out and a certain amount of time has elapsed (in production you'd set this to run during a time when the server wasn't busy). + + diff --git a/030_sessions/09_middleware/session.go b/030_sessions/09_middleware/session.go new file mode 100644 index 00000000..94488c1b --- /dev/null +++ b/030_sessions/09_middleware/session.go @@ -0,0 +1,71 @@ +package main + +import ( + "fmt" + "github.com/satori/go.uuid" + "net/http" + "time" +) + +func getUser(w http.ResponseWriter, req *http.Request) user { + // get cookie + c, err := req.Cookie("session") + if err != nil { + sID, _ := uuid.NewV4() + c = &http.Cookie{ + Name: "session", + Value: sID.String(), + } + + } + c.MaxAge = sessionLength + http.SetCookie(w, c) + + // if the user exists already, get user + var u user + if s, ok := dbSessions[c.Value]; ok { + s.lastActivity = time.Now() + dbSessions[c.Value] = s + u = dbUsers[s.un] + } + return u +} + +func alreadyLoggedIn(w http.ResponseWriter, req *http.Request) bool { + c, err := req.Cookie("session") + if err != nil { + return false + } + s, ok := dbSessions[c.Value] + if ok { + s.lastActivity = time.Now() + dbSessions[c.Value] = s + } + _, ok = dbUsers[s.un] + // refresh session + c.MaxAge = sessionLength + http.SetCookie(w, c) + return ok +} + +func cleanSessions() { + fmt.Println("BEFORE CLEAN") // for demonstration purposes + showSessions() // for demonstration purposes + for k, v := range dbSessions { + if time.Now().Sub(v.lastActivity) > (time.Second * 30) { + delete(dbSessions, k) + } + } + dbSessionsCleaned = time.Now() + fmt.Println("AFTER CLEAN") // for demonstration purposes + showSessions() // for demonstration purposes +} + +// for demonstration purposes +func showSessions() { + fmt.Println("********") + for k, v := range dbSessions { + fmt.Println(k, v.un) + } + fmt.Println("") +} diff --git a/030_sessions/09_middleware/templates/bar.gohtml b/030_sessions/09_middleware/templates/bar.gohtml new file mode 100644 index 00000000..ddd56835 --- /dev/null +++ b/030_sessions/09_middleware/templates/bar.gohtml @@ -0,0 +1,20 @@ + + + + + BAR + + + +

Welcome to the bar. What can I get you to drink?

+ +{{if .First}} +USER NAME {{.UserName}}
+PASSWORD {{.Password}}
+FIRST {{.First}}
+LAST {{.Last}}
+

log out

+{{end}} + + + \ No newline at end of file diff --git a/030_sessions/09_middleware/templates/index.gohtml b/030_sessions/09_middleware/templates/index.gohtml new file mode 100644 index 00000000..3bc10844 --- /dev/null +++ b/030_sessions/09_middleware/templates/index.gohtml @@ -0,0 +1,24 @@ + + + + + Document + + + +{{if .First}} +USER NAME {{.UserName}}
+PASSWORD {{.Password}}
+FIRST {{.First}}
+LAST {{.Last}}
+

log out

+{{else}} +

sign up

+

log in

+{{end}} + +
+

Go to the bar

+ + + \ No newline at end of file diff --git a/030_sessions/09_middleware/templates/login.gohtml b/030_sessions/09_middleware/templates/login.gohtml new file mode 100644 index 00000000..eb155256 --- /dev/null +++ b/030_sessions/09_middleware/templates/login.gohtml @@ -0,0 +1,18 @@ + + + + + Document + + + +

LOGIN

+
+ + + +
+

signup

+ + + \ No newline at end of file diff --git a/030_sessions/09_middleware/templates/signup.gohtml b/030_sessions/09_middleware/templates/signup.gohtml new file mode 100644 index 00000000..e9188a11 --- /dev/null +++ b/030_sessions/09_middleware/templates/signup.gohtml @@ -0,0 +1,26 @@ + + + + + Document + + + +
+ +
+
+
+
+ + + + +
+ + + \ No newline at end of file diff --git a/030_sessions/10_temp/README.md b/030_sessions/10_temp/README.md new file mode 100644 index 00000000..1ea4b86a --- /dev/null +++ b/030_sessions/10_temp/README.md @@ -0,0 +1,69 @@ +# Concurrency & Race Conditions + +## Could this code cause a race condition? + +``` +go cleanSessions() +``` + +``` +func cleanSessions() { + for k, v := range dbSessions { + if time.Now().Sub(v.lastActivity) > (time.Second * 30) { + delete(dbSessions, k) + } + } + dbSessionsCleaned = time.Now() +} + +``` + +https://golang.org/doc/go1.6 says: + +"The runtime has added lightweight, best-effort detection of concurrent misuse of maps. As always, if one goroutine is writing to a map, no other goroutine should be reading or writing the map concurrently. If the runtime detects this condition, it prints a diagnosis and crashes the program. The best way to find out more about the problem is to run the program under the race detector, which will more reliably identify the race and give more detail." + +When you + +``` +go build -race +``` + +you do not get a race condition reported. + + +![no race condition](norace.png) + +So if you're not writing to a map, you can use the map concurrently without a problem. + +RE: time.Time + +"A Time value can be used by multiple goroutines simultaneously." + +https://godoc.org/time#Time + +## Expanding on maps & goroutines + +Maps are funky. + +Check this out: + +![maps are funky](maps.png) + + +https://play.golang.org/p/62DF4xvPeQ + +**So you can delete something that doesn't exist, and that is not a problem.** + +**And you can ask for something that isn't there, and that is not a problem (gives you the zero value for the map's value).** + +Deleting IS DIFFERENT from writing. + +**If more than 1 goroutine tried to delete that same entry in the map: no problem.** + +**And if you're reading from the map and a value isn't there: no problem.** + +So why is WRITING a problem with concurrency? + +The classic race condition example is two routines READING, pulling the same value, each incrementing the value, and then each WRITING the incremented value back, and the value is incremented only 1, instead of 2. + +Just remember: WRITE TO MAP = concurrency considerations. \ No newline at end of file diff --git a/030_sessions/10_temp/main.go b/030_sessions/10_temp/main.go new file mode 100644 index 00000000..38998347 --- /dev/null +++ b/030_sessions/10_temp/main.go @@ -0,0 +1,178 @@ +package main + +import ( + "github.com/satori/go.uuid" + "golang.org/x/crypto/bcrypt" + "html/template" + "net/http" + "time" +) + +type user struct { + UserName string + Password []byte + First string + Last string + Role string +} + +type session struct { + un string + lastActivity time.Time +} + +var tpl *template.Template +var dbUsers = map[string]user{} // user ID, user +var dbSessions = map[string]session{} // session ID, session +var dbSessionsCleaned time.Time + +const sessionLength int = 30 + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) + dbSessionsCleaned = time.Now() +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/bar", bar) + http.HandleFunc("/signup", signup) + http.HandleFunc("/login", login) + http.HandleFunc("/logout", authorized(logout)) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, req *http.Request) { + u := getUser(w, req) + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "index.gohtml", u) +} + +func bar(w http.ResponseWriter, req *http.Request) { + u := getUser(w, req) + if !alreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + if u.Role != "007" { + http.Error(w, "You must be 007 to enter the bar", http.StatusForbidden) + return + } + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "bar.gohtml", u) +} + +func signup(w http.ResponseWriter, req *http.Request) { + if alreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + var u user + // process form submission + if req.Method == http.MethodPost { + // get form values + un := req.FormValue("username") + p := req.FormValue("password") + f := req.FormValue("firstname") + l := req.FormValue("lastname") + r := req.FormValue("role") + // username taken? + if _, ok := dbUsers[un]; ok { + http.Error(w, "Username already taken", http.StatusForbidden) + return + } + // create session + sID, _ := uuid.NewV4() + c := &http.Cookie{ + Name: "session", + Value: sID.String(), + } + c.MaxAge = sessionLength + http.SetCookie(w, c) + dbSessions[c.Value] = session{un, time.Now()} + // store user in dbUsers + bs, err := bcrypt.GenerateFromPassword([]byte(p), bcrypt.MinCost) + if err != nil { + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } + u = user{un, bs, f, l, r} + dbUsers[un] = u + // redirect + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "signup.gohtml", u) +} + +func login(w http.ResponseWriter, req *http.Request) { + if alreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + var u user + // process form submission + if req.Method == http.MethodPost { + un := req.FormValue("username") + p := req.FormValue("password") + // is there a username? + u, ok := dbUsers[un] + if !ok { + http.Error(w, "Username and/or password do not match", http.StatusForbidden) + return + } + // does the entered password match the stored password? + err := bcrypt.CompareHashAndPassword(u.Password, []byte(p)) + if err != nil { + http.Error(w, "Username and/or password do not match", http.StatusForbidden) + return + } + // create session + sID, _ := uuid.NewV4() + c := &http.Cookie{ + Name: "session", + Value: sID.String(), + } + c.MaxAge = sessionLength + http.SetCookie(w, c) + dbSessions[c.Value] = session{un, time.Now()} + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "login.gohtml", u) +} + +func logout(w http.ResponseWriter, req *http.Request) { + c, _ := req.Cookie("session") + // delete the session + delete(dbSessions, c.Value) + // remove the cookie + c = &http.Cookie{ + Name: "session", + Value: "", + MaxAge: -1, + } + http.SetCookie(w, c) + + // clean up dbSessions + if time.Now().Sub(dbSessionsCleaned) > (time.Second * 30) { + go cleanSessions() + } + + http.Redirect(w, req, "/login", http.StatusSeeOther) +} + +func authorized(h http.HandlerFunc) http.HandlerFunc { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // code before + if !alreadyLoggedIn(w, r) { + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + h.ServeHTTP(w, r) + // code after + }) +} diff --git a/030_sessions/10_temp/maps.png b/030_sessions/10_temp/maps.png new file mode 100644 index 00000000..6544facc Binary files /dev/null and b/030_sessions/10_temp/maps.png differ diff --git a/030_sessions/10_temp/norace.png b/030_sessions/10_temp/norace.png new file mode 100644 index 00000000..e3f6f33e Binary files /dev/null and b/030_sessions/10_temp/norace.png differ diff --git a/030_sessions/10_temp/notes.md b/030_sessions/10_temp/notes.md new file mode 100644 index 00000000..60f20260 --- /dev/null +++ b/030_sessions/10_temp/notes.md @@ -0,0 +1,26 @@ +# Step 1: +Created type session which is a struct with a lastActivity field. This will allow us to know the last time a session was used. + +# Step 2: +Updated dbSessions to be of type map[string]session + +# Step 3: +Updated all reads/writes to dbSessions + +# Step 4: +Apply the MaxAge field to cookie + +# Step 5: +Updated func alreadyLoggedIn to be able to set a cookie, adding the ResponseWriter to its parameters + +``` +func alreadyLoggedIn(w http.ResponseWriter, req *http.Request) bool { +``` + +# Step 6: +Added dbSessionsCleaned time.Time to keep track of the last time we cleaned out our sessions. + +# Step 7: +Added func cleanSessions to remove unused sessions from dbSessions. Set it to run whenever someone logs out and a certain amount of time has elapsed (in production you'd set this to run during a time when the server wasn't busy). + + diff --git a/030_sessions/10_temp/session.go b/030_sessions/10_temp/session.go new file mode 100644 index 00000000..94488c1b --- /dev/null +++ b/030_sessions/10_temp/session.go @@ -0,0 +1,71 @@ +package main + +import ( + "fmt" + "github.com/satori/go.uuid" + "net/http" + "time" +) + +func getUser(w http.ResponseWriter, req *http.Request) user { + // get cookie + c, err := req.Cookie("session") + if err != nil { + sID, _ := uuid.NewV4() + c = &http.Cookie{ + Name: "session", + Value: sID.String(), + } + + } + c.MaxAge = sessionLength + http.SetCookie(w, c) + + // if the user exists already, get user + var u user + if s, ok := dbSessions[c.Value]; ok { + s.lastActivity = time.Now() + dbSessions[c.Value] = s + u = dbUsers[s.un] + } + return u +} + +func alreadyLoggedIn(w http.ResponseWriter, req *http.Request) bool { + c, err := req.Cookie("session") + if err != nil { + return false + } + s, ok := dbSessions[c.Value] + if ok { + s.lastActivity = time.Now() + dbSessions[c.Value] = s + } + _, ok = dbUsers[s.un] + // refresh session + c.MaxAge = sessionLength + http.SetCookie(w, c) + return ok +} + +func cleanSessions() { + fmt.Println("BEFORE CLEAN") // for demonstration purposes + showSessions() // for demonstration purposes + for k, v := range dbSessions { + if time.Now().Sub(v.lastActivity) > (time.Second * 30) { + delete(dbSessions, k) + } + } + dbSessionsCleaned = time.Now() + fmt.Println("AFTER CLEAN") // for demonstration purposes + showSessions() // for demonstration purposes +} + +// for demonstration purposes +func showSessions() { + fmt.Println("********") + for k, v := range dbSessions { + fmt.Println(k, v.un) + } + fmt.Println("") +} diff --git a/030_sessions/10_temp/templates/bar.gohtml b/030_sessions/10_temp/templates/bar.gohtml new file mode 100644 index 00000000..ddd56835 --- /dev/null +++ b/030_sessions/10_temp/templates/bar.gohtml @@ -0,0 +1,20 @@ + + + + + BAR + + + +

Welcome to the bar. What can I get you to drink?

+ +{{if .First}} +USER NAME {{.UserName}}
+PASSWORD {{.Password}}
+FIRST {{.First}}
+LAST {{.Last}}
+

log out

+{{end}} + + + \ No newline at end of file diff --git a/030_sessions/10_temp/templates/index.gohtml b/030_sessions/10_temp/templates/index.gohtml new file mode 100644 index 00000000..3bc10844 --- /dev/null +++ b/030_sessions/10_temp/templates/index.gohtml @@ -0,0 +1,24 @@ + + + + + Document + + + +{{if .First}} +USER NAME {{.UserName}}
+PASSWORD {{.Password}}
+FIRST {{.First}}
+LAST {{.Last}}
+

log out

+{{else}} +

sign up

+

log in

+{{end}} + +
+

Go to the bar

+ + + \ No newline at end of file diff --git a/030_sessions/10_temp/templates/login.gohtml b/030_sessions/10_temp/templates/login.gohtml new file mode 100644 index 00000000..eb155256 --- /dev/null +++ b/030_sessions/10_temp/templates/login.gohtml @@ -0,0 +1,18 @@ + + + + + Document + + + +

LOGIN

+
+ + + +
+

signup

+ + + \ No newline at end of file diff --git a/030_sessions/10_temp/templates/signup.gohtml b/030_sessions/10_temp/templates/signup.gohtml new file mode 100644 index 00000000..e9188a11 --- /dev/null +++ b/030_sessions/10_temp/templates/signup.gohtml @@ -0,0 +1,26 @@ + + + + + Document + + + +
+ +
+
+
+
+ + + + +
+ + + \ No newline at end of file diff --git a/030_sessions/README.md b/030_sessions/README.md old mode 100755 new mode 100644 diff --git a/031_aws/01_hello/01_hello b/031_aws/01_hello/01_hello deleted file mode 100644 index 14523717..00000000 Binary files a/031_aws/01_hello/01_hello and /dev/null differ diff --git a/031_aws/01_hello/main.go b/031_aws/01_hello/main.go old mode 100755 new mode 100644 diff --git a/031_aws/01_hello/mybinary b/031_aws/01_hello/mybinary new file mode 100755 index 00000000..19367514 Binary files /dev/null and b/031_aws/01_hello/mybinary differ diff --git a/031_aws/02_hands-on/02_solution/README.md b/031_aws/02_hands-on/02_solution/README.md index 71487cb3..009c7466 100644 --- a/031_aws/02_hands-on/02_solution/README.md +++ b/031_aws/02_hands-on/02_solution/README.md @@ -13,7 +13,7 @@ 1. copy binary to the server -1. copy you "templates" to the server +1. copy your "templates" to the server - scp -i /path/to/[your].pem templates/* ubuntu@[public-DNS]:/home/ubuntu/templates 1. chmod permissions on your binary diff --git a/031_aws/02_hands-on/02_solution/main.go b/031_aws/02_hands-on/02_solution/main.go index 5ee06052..e6e9a4cb 100644 --- a/031_aws/02_hands-on/02_solution/main.go +++ b/031_aws/02_hands-on/02_solution/main.go @@ -83,7 +83,7 @@ func signup(w http.ResponseWriter, req *http.Request) { return } // create session - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c := &http.Cookie{ Name: "session", Value: sID.String(), @@ -130,7 +130,7 @@ func login(w http.ResponseWriter, req *http.Request) { return } // create session - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c := &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/031_aws/02_hands-on/02_solution/session.go b/031_aws/02_hands-on/02_solution/session.go index 45f272d6..94488c1b 100644 --- a/031_aws/02_hands-on/02_solution/session.go +++ b/031_aws/02_hands-on/02_solution/session.go @@ -11,7 +11,7 @@ func getUser(w http.ResponseWriter, req *http.Request) user { // get cookie c, err := req.Cookie("session") if err != nil { - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c = &http.Cookie{ Name: "session", Value: sID.String(), diff --git a/032_rdbms/02_SQL/main.go b/032_rdbms/02_SQL/main.go index 9793da37..d4722b24 100644 --- a/032_rdbms/02_SQL/main.go +++ b/032_rdbms/02_SQL/main.go @@ -40,6 +40,7 @@ func index(w http.ResponseWriter, req *http.Request) { func amigos(w http.ResponseWriter, req *http.Request) { rows, err := db.Query(`SELECT aName FROM amigos;`) check(err) + defer rows.Close() // data to be used in query var s, name string @@ -58,6 +59,7 @@ func create(w http.ResponseWriter, req *http.Request) { stmt, err := db.Prepare(`CREATE TABLE customer (name VARCHAR(20));`) check(err) + defer stmt.Close() r, err := stmt.Exec() check(err) @@ -72,6 +74,7 @@ func insert(w http.ResponseWriter, req *http.Request) { stmt, err := db.Prepare(`INSERT INTO customer VALUES ("James");`) check(err) + defer stmt.Close() r, err := stmt.Exec() check(err) @@ -85,18 +88,20 @@ func insert(w http.ResponseWriter, req *http.Request) { func read(w http.ResponseWriter, req *http.Request) { rows, err := db.Query(`SELECT * FROM customer;`) check(err) + defer rows.Close() var name string for rows.Next() { err = rows.Scan(&name) check(err) - fmt.Fprintln(w, "RETREIVED RECORD:", name) + fmt.Fprintln(w, "RETRIEVED RECORD:", name) } } func update(w http.ResponseWriter, req *http.Request) { stmt, err := db.Prepare(`UPDATE customer SET name="Jimmy" WHERE name="James";`) check(err) + defer stmt.Close() r, err := stmt.Exec() check(err) @@ -110,6 +115,7 @@ func update(w http.ResponseWriter, req *http.Request) { func del(w http.ResponseWriter, req *http.Request) { stmt, err := db.Prepare(`DELETE FROM customer WHERE name="Jimmy";`) check(err) + defer stmt.Close() r, err := stmt.Exec() check(err) @@ -123,6 +129,7 @@ func del(w http.ResponseWriter, req *http.Request) { func drop(w http.ResponseWriter, req *http.Request) { stmt, err := db.Prepare(`DROP TABLE customer;`) check(err) + defer stmt.Close() _, err = stmt.Exec() check(err) diff --git a/034_photo-blog/01_starting/main.go b/034_photo-blog/01_starting/main.go index cef8d82a..6faf3df0 100644 --- a/034_photo-blog/01_starting/main.go +++ b/034_photo-blog/01_starting/main.go @@ -19,4 +19,4 @@ func main() { func index(w http.ResponseWriter, req *http.Request) { tpl.ExecuteTemplate(w, "index.gohtml", nil) -} \ No newline at end of file +} diff --git a/034_photo-blog/02_cookie/main.go b/034_photo-blog/02_cookie/main.go index e2f6833a..283e0e1d 100644 --- a/034_photo-blog/02_cookie/main.go +++ b/034_photo-blog/02_cookie/main.go @@ -1,9 +1,9 @@ package main import ( + "github.com/satori/go.uuid" "html/template" "net/http" - "github.com/satori/go.uuid" ) var tpl *template.Template @@ -27,7 +27,7 @@ func index(w http.ResponseWriter, req *http.Request) { func getCookie(w http.ResponseWriter, req *http.Request) *http.Cookie { c, err := req.Cookie("session") if err != nil { - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c = &http.Cookie{ Name: "session", Value: sID.String(), @@ -35,4 +35,4 @@ func getCookie(w http.ResponseWriter, req *http.Request) *http.Cookie { http.SetCookie(w, c) } return c -} \ No newline at end of file +} diff --git a/034_photo-blog/03_store-values/main.go b/034_photo-blog/03_store-values/main.go index b813c01d..3397de56 100644 --- a/034_photo-blog/03_store-values/main.go +++ b/034_photo-blog/03_store-values/main.go @@ -1,9 +1,9 @@ package main import ( + "github.com/satori/go.uuid" "html/template" "net/http" - "github.com/satori/go.uuid" "strings" ) @@ -29,7 +29,7 @@ func index(w http.ResponseWriter, req *http.Request) { func getCookie(w http.ResponseWriter, req *http.Request) *http.Cookie { c, err := req.Cookie("session") if err != nil { - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c = &http.Cookie{ Name: "session", Value: sID.String(), @@ -58,4 +58,4 @@ func appendValue(w http.ResponseWriter, c *http.Cookie) *http.Cookie { c.Value = s http.SetCookie(w, c) return c -} \ No newline at end of file +} diff --git a/034_photo-blog/04_upload-pictures/main.go b/034_photo-blog/04_upload-pictures/main.go index 26476737..e950302c 100644 --- a/034_photo-blog/04_upload-pictures/main.go +++ b/034_photo-blog/04_upload-pictures/main.go @@ -1,15 +1,15 @@ package main import ( - "html/template" - "net/http" - "github.com/satori/go.uuid" - "strings" + "crypto/sha1" "fmt" + "github.com/satori/go.uuid" + "html/template" "io" - "crypto/sha1" + "net/http" "os" "path/filepath" + "strings" ) var tpl *template.Template @@ -62,7 +62,7 @@ func index(w http.ResponseWriter, req *http.Request) { func getCookie(w http.ResponseWriter, req *http.Request) *http.Cookie { c, err := req.Cookie("session") if err != nil { - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c = &http.Cookie{ Name: "session", Value: sID.String(), @@ -75,10 +75,10 @@ func getCookie(w http.ResponseWriter, req *http.Request) *http.Cookie { // takes in a file name now also func appendValue(w http.ResponseWriter, c *http.Cookie, fname string) *http.Cookie { s := c.Value - if !strings.Contains(s , fname) { + if !strings.Contains(s, fname) { s += "|" + fname } c.Value = s http.SetCookie(w, c) return c -} \ No newline at end of file +} diff --git a/034_photo-blog/05_display-pictures/main.go b/034_photo-blog/05_display-pictures/main.go index 0c97dcb1..cc8344c4 100644 --- a/034_photo-blog/05_display-pictures/main.go +++ b/034_photo-blog/05_display-pictures/main.go @@ -1,15 +1,15 @@ package main import ( - "html/template" - "net/http" - "github.com/satori/go.uuid" - "strings" + "crypto/sha1" "fmt" + "github.com/satori/go.uuid" + "html/template" "io" - "crypto/sha1" + "net/http" "os" "path/filepath" + "strings" ) var tpl *template.Template @@ -64,7 +64,7 @@ func index(w http.ResponseWriter, req *http.Request) { func getCookie(w http.ResponseWriter, req *http.Request) *http.Cookie { c, err := req.Cookie("session") if err != nil { - sID := uuid.NewV4() + sID, _ := uuid.NewV4() c = &http.Cookie{ Name: "session", Value: sID.String(), @@ -76,10 +76,10 @@ func getCookie(w http.ResponseWriter, req *http.Request) *http.Cookie { func appendValue(w http.ResponseWriter, c *http.Cookie, fname string) *http.Cookie { s := c.Value - if !strings.Contains(s , fname) { + if !strings.Contains(s, fname) { s += "|" + fname } c.Value = s http.SetCookie(w, c) return c -} \ No newline at end of file +} diff --git a/035_hmac/01/main.go b/035_hmac/01/main.go old mode 100755 new mode 100644 index ecd0e5cb..d348bcb2 --- a/035_hmac/01/main.go +++ b/035_hmac/01/main.go @@ -18,4 +18,4 @@ func getCode(s string) string { h := hmac.New(sha256.New, []byte("ourkey")) io.WriteString(h, s) return fmt.Sprintf("%x", h.Sum(nil)) -} \ No newline at end of file +} diff --git a/035_hmac/02/main.go b/035_hmac/02/main.go old mode 100755 new mode 100644 index 6e6d7fad..316fffd0 --- a/035_hmac/02/main.go +++ b/035_hmac/02/main.go @@ -61,7 +61,7 @@ func auth(w http.ResponseWriter, req *http.Request) { xs := strings.Split(c.Value, "|") email := xs[0] codeRcvd := xs[1] - codeCheck := getCode(email) + codeCheck := getCode(email + "s") if codeRcvd != codeCheck { fmt.Println("HMAC codes didn't match") @@ -84,4 +84,4 @@ func getCode(data string) string { h := hmac.New(sha256.New, []byte("ourkey")) io.WriteString(h, data) return fmt.Sprintf("%x", h.Sum(nil)) -} \ No newline at end of file +} diff --git a/036_base64/01/main.go b/036_base64/01/main.go old mode 100755 new mode 100644 diff --git a/036_base64/02/main.go b/036_base64/02/main.go old mode 100755 new mode 100644 diff --git a/036_base64/03/main.go b/036_base64/03/main.go old mode 100755 new mode 100644 diff --git a/038_context/01/main.go b/038_context/01/main.go old mode 100755 new mode 100644 diff --git a/038_context/02/main.go b/038_context/02/main.go old mode 100755 new mode 100644 diff --git a/038_context/03/main.go b/038_context/03/main.go old mode 100755 new mode 100644 diff --git a/038_context/04/README.md b/038_context/04/README.md index f01071e4..ce43b8b4 100644 --- a/038_context/04/README.md +++ b/038_context/04/README.md @@ -1,3 +1,3 @@ Context makes it possible to manage a chain of calls within the same call path by signaling context’s Done channel. -source: http://golang.rakyll.org/leakingctx/ \ No newline at end of file +source: https://rakyll.org/leakingctx/ \ No newline at end of file diff --git a/039_https/01/main.go b/039_https/01/main.go old mode 100755 new mode 100644 diff --git a/040_json/01/main.go b/040_json/01/main.go index d52c6ee1..4e76ac7b 100644 --- a/040_json/01/main.go +++ b/040_json/01/main.go @@ -31,30 +31,30 @@ func foo(w http.ResponseWriter, req *http.Request) { ` w.Write([]byte(s)) - } func mshl(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "application/json") p1 := person{ - "James", - "Bond", - []string{"Suit", "Gun", "Wry sense of humor"}, + Fname: "James", + Lname: "Bond", + Items: []string{"Suit", "Gun", "Wry sense of humor"}, } - json, err := json.Marshal(&p1) + j, err := json.Marshal(p1) if err != nil { log.Println(err) } - w.Write(json) + w.Write(j) } func encd(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "application/json") p1 := person{ - "James", - "Bond", - []string{"Suit", "Gun", "Wry sense of humor"}, + Fname: "James", + Lname: "Bond", + Items: []string{"Suit", "Gun", "Wry sense of humor"}, } - err := json.NewEncoder(w).Encode(&p1) + err := json.NewEncoder(w).Encode(p1) if err != nil { log.Println(err) } diff --git a/040_json/02_object/index.html b/040_json/02_object/index.html old mode 100755 new mode 100644 diff --git a/040_json/03_array/index.html b/040_json/03_array/index.html old mode 100755 new mode 100644 diff --git a/040_json/04_stringify_object/index.html b/040_json/04_stringify/index.html old mode 100755 new mode 100644 similarity index 100% rename from 040_json/04_stringify_object/index.html rename to 040_json/04_stringify/index.html diff --git a/040_json/05_stringify_array/index.html b/040_json/05_stringify/index.html old mode 100755 new mode 100644 similarity index 100% rename from 040_json/05_stringify_array/index.html rename to 040_json/05_stringify/index.html diff --git a/040_json/06_unmarshal_object/index.html b/040_json/06_unmarshal/index.html old mode 100755 new mode 100644 similarity index 100% rename from 040_json/06_unmarshal_object/index.html rename to 040_json/06_unmarshal/index.html diff --git a/040_json/06_unmarshal_object/main.go b/040_json/06_unmarshal/main.go old mode 100755 new mode 100644 similarity index 100% rename from 040_json/06_unmarshal_object/main.go rename to 040_json/06_unmarshal/main.go diff --git a/040_json/07_unmarshal_array/index.html b/040_json/07_unmarshal/index.html old mode 100755 new mode 100644 similarity index 100% rename from 040_json/07_unmarshal_array/index.html rename to 040_json/07_unmarshal/index.html diff --git a/040_json/08_unmarshal_array_partial/main.go b/040_json/07_unmarshal/main.go old mode 100755 new mode 100644 similarity index 100% rename from 040_json/08_unmarshal_array_partial/main.go rename to 040_json/07_unmarshal/main.go diff --git a/040_json/07_unmarshal_array/main.go b/040_json/07_unmarshal_array/main.go deleted file mode 100755 index d4d84363..00000000 --- a/040_json/07_unmarshal_array/main.go +++ /dev/null @@ -1,35 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "log" -) - -type city struct { - Precision string `json:"precision,omitempty"` - Latitude, Longitude float64 - Address, City, State, Zip, Country string -} - -/* -// precision doesn't receive value -type city struct { - precision string - Latitude, Longitude float64 - Address, City, State, Zip, Country string -} -*/ - -type cities []city - -func main() { - var data cities - rcvd := `[{"precision":"zip","Latitude":37.7668,"Longitude":-122.3959,"Address":"","City":"SAN FRANCISCO","State":"CA","Zip":"94107","Country":"US"},{"precision":"zip","Latitude":37.371991,"Longitude":-122.02602,"Address":"","City":"SUNNYVALE","State":"CA","Zip":"94085","Country":"US"}]` - err := json.Unmarshal([]byte(rcvd), &data) - if err != nil { - log.Fatalln(err) - } - - fmt.Println(data) -} diff --git a/040_json/08_unmarshal_array_partial/index.html b/040_json/08_unmarshal_tags/index.html old mode 100755 new mode 100644 similarity index 92% rename from 040_json/08_unmarshal_array_partial/index.html rename to 040_json/08_unmarshal_tags/index.html index e0bdc691..f808ccd8 --- a/040_json/08_unmarshal_array_partial/index.html +++ b/040_json/08_unmarshal_tags/index.html @@ -11,7 +11,7 @@ + + \ No newline at end of file diff --git a/999_old-code/054_ajax/01/test.html b/041_ajax/01/test.html old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/01/test.html rename to 041_ajax/01/test.html diff --git a/041_ajax/02/01/main.go b/041_ajax/02/01/main.go new file mode 100644 index 00000000..0244f70d --- /dev/null +++ b/041_ajax/02/01/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/foo", foo) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + s := `Here is some text from foo` + fmt.Fprintln(w, s) +} diff --git a/041_ajax/02/01/templates/index.gohtml b/041_ajax/02/01/templates/index.gohtml new file mode 100644 index 00000000..26ac2907 --- /dev/null +++ b/041_ajax/02/01/templates/index.gohtml @@ -0,0 +1,43 @@ + + + + + Index + + + + + +

Make Something Happen

+ + + + \ No newline at end of file diff --git a/041_ajax/02/02/main.go b/041_ajax/02/02/main.go new file mode 100644 index 00000000..0244f70d --- /dev/null +++ b/041_ajax/02/02/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/foo", foo) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "index.gohtml", nil) +} + +func foo(w http.ResponseWriter, r *http.Request) { + s := `Here is some text from foo` + fmt.Fprintln(w, s) +} diff --git a/041_ajax/02/02/templates/index.gohtml b/041_ajax/02/02/templates/index.gohtml new file mode 100644 index 00000000..61bef53e --- /dev/null +++ b/041_ajax/02/02/templates/index.gohtml @@ -0,0 +1,47 @@ + + + + + Index + + + + + +

Make Something Happen

+ + + + \ No newline at end of file diff --git a/041_ajax/03/main.go b/041_ajax/03/main.go new file mode 100644 index 00000000..c230c8f6 --- /dev/null +++ b/041_ajax/03/main.go @@ -0,0 +1,192 @@ +package main + +import ( + "fmt" + "github.com/satori/go.uuid" + "golang.org/x/crypto/bcrypt" + "html/template" + "io/ioutil" + "net/http" + "time" +) + +type user struct { + UserName string + Password []byte + First string + Last string + Role string +} + +type session struct { + un string + lastActivity time.Time +} + +var tpl *template.Template +var dbUsers = map[string]user{} // user ID, user +var dbSessions = map[string]session{} // session ID, session +var dbSessionsCleaned time.Time + +const sessionLength int = 30 + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) + dbSessionsCleaned = time.Now() +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/bar", bar) + http.HandleFunc("/signup", signup) + http.HandleFunc("/login", login) + http.HandleFunc("/logout", logout) + // added new route + http.HandleFunc("/checkUserName", checkUserName) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, req *http.Request) { + u := getUser(w, req) + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "index.gohtml", u) +} + +func bar(w http.ResponseWriter, req *http.Request) { + u := getUser(w, req) + if !alreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + if u.Role != "007" { + http.Error(w, "You must be 007 to enter the bar", http.StatusForbidden) + return + } + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "bar.gohtml", u) +} + +func signup(w http.ResponseWriter, req *http.Request) { + if alreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + var u user + // process form submission + if req.Method == http.MethodPost { + // get form values + un := req.FormValue("username") + p := req.FormValue("password") + f := req.FormValue("firstname") + l := req.FormValue("lastname") + r := req.FormValue("role") + // username taken? + if _, ok := dbUsers[un]; ok { + http.Error(w, "Username already taken", http.StatusForbidden) + return + } + // create session + sID, _ := uuid.NewV4() + c := &http.Cookie{ + Name: "session", + Value: sID.String(), + } + c.MaxAge = sessionLength + http.SetCookie(w, c) + dbSessions[c.Value] = session{un, time.Now()} + // store user in dbUsers + bs, err := bcrypt.GenerateFromPassword([]byte(p), bcrypt.MinCost) + if err != nil { + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } + u = user{un, bs, f, l, r} + dbUsers[un] = u + // redirect + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "signup.gohtml", u) +} + +func login(w http.ResponseWriter, req *http.Request) { + if alreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + var u user + // process form submission + if req.Method == http.MethodPost { + un := req.FormValue("username") + p := req.FormValue("password") + // is there a username? + u, ok := dbUsers[un] + if !ok { + http.Error(w, "Username and/or password do not match", http.StatusForbidden) + return + } + // does the entered password match the stored password? + err := bcrypt.CompareHashAndPassword(u.Password, []byte(p)) + if err != nil { + http.Error(w, "Username and/or password do not match", http.StatusForbidden) + return + } + // create session + sID, _ := uuid.NewV4() + c := &http.Cookie{ + Name: "session", + Value: sID.String(), + } + c.MaxAge = sessionLength + http.SetCookie(w, c) + dbSessions[c.Value] = session{un, time.Now()} + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "login.gohtml", u) +} + +func logout(w http.ResponseWriter, req *http.Request) { + if !alreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + c, _ := req.Cookie("session") + // delete the session + delete(dbSessions, c.Value) + // remove the cookie + c = &http.Cookie{ + Name: "session", + Value: "", + MaxAge: -1, + } + http.SetCookie(w, c) + + // clean up dbSessions + if time.Now().Sub(dbSessionsCleaned) > (time.Second * 30) { + go cleanSessions() + } + + http.Redirect(w, req, "/login", http.StatusSeeOther) +} + +func checkUserName(w http.ResponseWriter, req *http.Request) { + sampleUsers := map[string]bool{ + "test@example.com": true, + "jame@bond.com": true, + "moneyp@uk.gov": true, + } + + bs, err := ioutil.ReadAll(req.Body) + if err != nil { + fmt.Println(err) + } + + sbs := string(bs) + fmt.Println("USERNAME: ", sbs) + + fmt.Fprint(w, sampleUsers[sbs]) +} diff --git a/041_ajax/03/notes.md b/041_ajax/03/notes.md new file mode 100644 index 00000000..60f20260 --- /dev/null +++ b/041_ajax/03/notes.md @@ -0,0 +1,26 @@ +# Step 1: +Created type session which is a struct with a lastActivity field. This will allow us to know the last time a session was used. + +# Step 2: +Updated dbSessions to be of type map[string]session + +# Step 3: +Updated all reads/writes to dbSessions + +# Step 4: +Apply the MaxAge field to cookie + +# Step 5: +Updated func alreadyLoggedIn to be able to set a cookie, adding the ResponseWriter to its parameters + +``` +func alreadyLoggedIn(w http.ResponseWriter, req *http.Request) bool { +``` + +# Step 6: +Added dbSessionsCleaned time.Time to keep track of the last time we cleaned out our sessions. + +# Step 7: +Added func cleanSessions to remove unused sessions from dbSessions. Set it to run whenever someone logs out and a certain amount of time has elapsed (in production you'd set this to run during a time when the server wasn't busy). + + diff --git a/041_ajax/03/session.go b/041_ajax/03/session.go new file mode 100644 index 00000000..94488c1b --- /dev/null +++ b/041_ajax/03/session.go @@ -0,0 +1,71 @@ +package main + +import ( + "fmt" + "github.com/satori/go.uuid" + "net/http" + "time" +) + +func getUser(w http.ResponseWriter, req *http.Request) user { + // get cookie + c, err := req.Cookie("session") + if err != nil { + sID, _ := uuid.NewV4() + c = &http.Cookie{ + Name: "session", + Value: sID.String(), + } + + } + c.MaxAge = sessionLength + http.SetCookie(w, c) + + // if the user exists already, get user + var u user + if s, ok := dbSessions[c.Value]; ok { + s.lastActivity = time.Now() + dbSessions[c.Value] = s + u = dbUsers[s.un] + } + return u +} + +func alreadyLoggedIn(w http.ResponseWriter, req *http.Request) bool { + c, err := req.Cookie("session") + if err != nil { + return false + } + s, ok := dbSessions[c.Value] + if ok { + s.lastActivity = time.Now() + dbSessions[c.Value] = s + } + _, ok = dbUsers[s.un] + // refresh session + c.MaxAge = sessionLength + http.SetCookie(w, c) + return ok +} + +func cleanSessions() { + fmt.Println("BEFORE CLEAN") // for demonstration purposes + showSessions() // for demonstration purposes + for k, v := range dbSessions { + if time.Now().Sub(v.lastActivity) > (time.Second * 30) { + delete(dbSessions, k) + } + } + dbSessionsCleaned = time.Now() + fmt.Println("AFTER CLEAN") // for demonstration purposes + showSessions() // for demonstration purposes +} + +// for demonstration purposes +func showSessions() { + fmt.Println("********") + for k, v := range dbSessions { + fmt.Println(k, v.un) + } + fmt.Println("") +} diff --git a/041_ajax/03/surfergirl b/041_ajax/03/surfergirl new file mode 100644 index 00000000..50aa7c10 Binary files /dev/null and b/041_ajax/03/surfergirl differ diff --git a/041_ajax/03/templates/bar.gohtml b/041_ajax/03/templates/bar.gohtml new file mode 100644 index 00000000..ddd56835 --- /dev/null +++ b/041_ajax/03/templates/bar.gohtml @@ -0,0 +1,20 @@ + + + + + BAR + + + +

Welcome to the bar. What can I get you to drink?

+ +{{if .First}} +USER NAME {{.UserName}}
+PASSWORD {{.Password}}
+FIRST {{.First}}
+LAST {{.Last}}
+

log out

+{{end}} + + + \ No newline at end of file diff --git a/041_ajax/03/templates/index.gohtml b/041_ajax/03/templates/index.gohtml new file mode 100644 index 00000000..3bc10844 --- /dev/null +++ b/041_ajax/03/templates/index.gohtml @@ -0,0 +1,24 @@ + + + + + Document + + + +{{if .First}} +USER NAME {{.UserName}}
+PASSWORD {{.Password}}
+FIRST {{.First}}
+LAST {{.Last}}
+

log out

+{{else}} +

sign up

+

log in

+{{end}} + +
+

Go to the bar

+ + + \ No newline at end of file diff --git a/041_ajax/03/templates/login.gohtml b/041_ajax/03/templates/login.gohtml new file mode 100644 index 00000000..eb155256 --- /dev/null +++ b/041_ajax/03/templates/login.gohtml @@ -0,0 +1,18 @@ + + + + + Document + + + +

LOGIN

+
+ + + +
+

signup

+ + + \ No newline at end of file diff --git a/041_ajax/03/templates/signup.gohtml b/041_ajax/03/templates/signup.gohtml new file mode 100644 index 00000000..bd8be341 --- /dev/null +++ b/041_ajax/03/templates/signup.gohtml @@ -0,0 +1,83 @@ + + + + + Document + + + +
+
+

+
+
+

+
+
+ + + + +
+ + + + \ No newline at end of file diff --git a/042_mongodb/01_julienschmidt-router/README.md b/042_mongodb/01_julienschmidt-router/README.md new file mode 100644 index 00000000..920815f8 --- /dev/null +++ b/042_mongodb/01_julienschmidt-router/README.md @@ -0,0 +1,37 @@ +# Using Curl + +1. Start your server +``` +go run main.go +``` + +1. Enter this at the terminal +``` +curl http://localhost:8080 +``` + +This code forked from Steven White and his excellent articles: +https://stevenwhite.com/building-a-rest-service-with-golang-1/ +https://stevenwhite.com/building-a-rest-service-with-golang-2/ +https://stevenwhite.com/building-a-rest-service-with-golang-3/ + +# License + +MIT LICENSE + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/042_mongodb/01_julienschmidt-router/main.go b/042_mongodb/01_julienschmidt-router/main.go new file mode 100644 index 00000000..39734816 --- /dev/null +++ b/042_mongodb/01_julienschmidt-router/main.go @@ -0,0 +1,18 @@ +package main + +import ( + "fmt" + "github.com/julienschmidt/httprouter" + "net/http" +) + +func main() { + r := httprouter.New() + r.GET("/", index) + http.ListenAndServe("localhost:8080", r) +} + +// note: using 'r' instead of 'req' +func index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + fmt.Fprint(w, "Welcome!\n") +} diff --git a/042_mongodb/02_json/README.md b/042_mongodb/02_json/README.md new file mode 100644 index 00000000..eed53b9b --- /dev/null +++ b/042_mongodb/02_json/README.md @@ -0,0 +1,9 @@ +# Using Curl + +1. Start your server + +1. Enter this at the terminal +``` +curl http://localhost:8080/user/1 +``` + diff --git a/042_mongodb/02_json/main.go b/042_mongodb/02_json/main.go new file mode 100644 index 00000000..b64a1f0b --- /dev/null +++ b/042_mongodb/02_json/main.go @@ -0,0 +1,55 @@ +package main + +import ( + "encoding/json" + "fmt" + "github.com/GoesToEleven/golang-web-dev/042_mongodb/02_json/models" + "github.com/julienschmidt/httprouter" + "net/http" +) + +func main() { + r := httprouter.New() + r.GET("/", index) + // added route plus parameter + r.GET("/user/:id", getUser) + http.ListenAndServe("localhost:8080", r) +} + +func index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + s := ` + + + +Index + + +GO TO: http://localhost:8080/user/9872309847 + + + ` + w.Header().Set("Content-Type", "text/html; charset=UTF-8") + w.WriteHeader(http.StatusOK) + w.Write([]byte(s)) +} + +// changed func name +func getUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + u := models.User{ + Name: "James Bond", + Gender: "male", + Age: 32, + Id: p.ByName("id"), + } + + // Marshal into JSON + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + // Write content-type, statuscode, payload + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprintf(w, "%s\n", uj) +} diff --git a/042_mongodb/02_json/models/user.go b/042_mongodb/02_json/models/user.go new file mode 100644 index 00000000..63a12406 --- /dev/null +++ b/042_mongodb/02_json/models/user.go @@ -0,0 +1,8 @@ +package models + +type User struct { + Name string `json:"name"` + Gender string `json:"gender"` + Age int `json:"age"` + Id string `json:"id"` +} diff --git a/042_mongodb/03_post-delete/README.md b/042_mongodb/03_post-delete/README.md new file mode 100644 index 00000000..a83975e8 --- /dev/null +++ b/042_mongodb/03_post-delete/README.md @@ -0,0 +1,29 @@ +# Using Curl + +1. Start your server + +1. Enter this at the terminal + +``` +curl http://localhost:8080/user/1 +``` + +``` +curl -X POST -H "Content-Type: application/json" -d '{"Name":"James Bond","Gender":"male","Age":32,"Id":"777"}' http://localhost:8080/user +``` + +-X is short for --request +Specifies a custom request method to use when communicating with the HTTP server. + +-H is short for --header + +-d is short for --data + + +``` +curl -X DELETE -H "Content-Type: application/json" http://localhost:8080/user/777 +``` + +IMPORTANT: +Make sure you update your import statements to import packages from the correct location! + diff --git a/042_mongodb/03_post-delete/main.go b/042_mongodb/03_post-delete/main.go new file mode 100644 index 00000000..abc773ac --- /dev/null +++ b/042_mongodb/03_post-delete/main.go @@ -0,0 +1,82 @@ +package main + +import ( + "encoding/json" + "fmt" + "github.com/GoesToEleven/golang-web-dev/042_mongodb/03_post-delete/models" + "github.com/julienschmidt/httprouter" + "net/http" +) + +func main() { + r := httprouter.New() + r.GET("/", index) + r.GET("/user/:id", getUser) + // added route + r.POST("/user", createUser) + // added route plus parameter + r.DELETE("/user/:id", deleteUser) + http.ListenAndServe("localhost:8080", r) +} + +func index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + s := ` + + + +Index + + +GO TO: http://localhost:8080/user/9872309847 + + + ` + w.Header().Set("Content-Type", "text/html; charset=UTF-8") + w.WriteHeader(http.StatusOK) + w.Write([]byte(s)) +} + +func getUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + u := models.User{ + Name: "James Bond", + Gender: "male", + Age: 32, + Id: p.ByName("id"), + } + + // Marshal into JSON + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + // Write content-type, statuscode, payload + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprintf(w, "%s\n", uj) +} + +func createUser(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + // composite literal - type and curly braces + u := models.User{} + + // encode/decode for sending/receiving JSON to/from a stream + json.NewDecoder(r.Body).Decode(&u) + + // Change Id + u.Id = "007" + + // marshal/unmarshal for having JSON assigned to a variable + uj, _ := json.Marshal(u) + + // Write content-type, statuscode, payload + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) // 201 + fmt.Fprintf(w, "%s\n", uj) +} + +func deleteUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + // TODO: write code to delete user + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprint(w, "Write code to delete user\n") +} diff --git a/042_mongodb/03_post-delete/models/user.go b/042_mongodb/03_post-delete/models/user.go new file mode 100644 index 00000000..63a12406 --- /dev/null +++ b/042_mongodb/03_post-delete/models/user.go @@ -0,0 +1,8 @@ +package models + +type User struct { + Name string `json:"name"` + Gender string `json:"gender"` + Age int `json:"age"` + Id string `json:"id"` +} diff --git a/042_mongodb/04_controllers/README.md b/042_mongodb/04_controllers/README.md new file mode 100644 index 00000000..92b732b8 --- /dev/null +++ b/042_mongodb/04_controllers/README.md @@ -0,0 +1,20 @@ +# Using Curl + +1. Start your server + +1. Enter this at the terminal + +``` +curl http://localhost:8080/user/1 +``` + +``` +curl -X POST -H "Content-Type: application/json" -d '{"Name":"James Bond","Gender":"male","Age":32,"Id":"777"}' http://localhost:8080/user +``` + +``` +curl -X DELETE -H "Content-Type: application/json" http://localhost:8080/user/777 +``` + +IMPORTANT: +Make sure you update your import statements to import packages from the correct location! diff --git a/042_mongodb/04_controllers/controllers/user.go b/042_mongodb/04_controllers/controllers/user.go new file mode 100644 index 00000000..6721c792 --- /dev/null +++ b/042_mongodb/04_controllers/controllers/user.go @@ -0,0 +1,57 @@ +package controllers + +import ( + "encoding/json" + "fmt" + "github.com/GoesToEleven/golang-web-dev/042_mongodb/04_controllers/models" + "github.com/julienschmidt/httprouter" + "net/http" +) + +type UserController struct{} + +func NewUserController() *UserController { + return &UserController{} +} + +// Methods have to be capitalized to be exported, eg, GetUser and not getUser +func (uc UserController) GetUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + u := models.User{ + Name: "James Bond", + Gender: "male", + Age: 32, + Id: p.ByName("id"), + } + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) CreateUser(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + u := models.User{} + + json.NewDecoder(r.Body).Decode(&u) + + u.Id = "007" + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) // 201 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) DeleteUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + // TODO: only write code to delete user + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprint(w, "Write code to delete user\n") +} diff --git a/042_mongodb/04_controllers/main.go b/042_mongodb/04_controllers/main.go new file mode 100644 index 00000000..2d701eaa --- /dev/null +++ b/042_mongodb/04_controllers/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "github.com/GoesToEleven/golang-web-dev/042_mongodb/04_controllers/controllers" + "github.com/julienschmidt/httprouter" + "net/http" +) + +func main() { + r := httprouter.New() + uc := controllers.NewUserController() + r.GET("/user/:id", uc.GetUser) + r.POST("/user", uc.CreateUser) + r.DELETE("/user/:id", uc.DeleteUser) + http.ListenAndServe("localhost:8080", r) +} diff --git a/042_mongodb/04_controllers/models/user.go b/042_mongodb/04_controllers/models/user.go new file mode 100644 index 00000000..63a12406 --- /dev/null +++ b/042_mongodb/04_controllers/models/user.go @@ -0,0 +1,8 @@ +package models + +type User struct { + Name string `json:"name"` + Gender string `json:"gender"` + Age int `json:"age"` + Id string `json:"id"` +} diff --git a/042_mongodb/05_mongodb/01_update-user-controller/README.md b/042_mongodb/05_mongodb/01_update-user-controller/README.md new file mode 100644 index 00000000..ba3f6333 --- /dev/null +++ b/042_mongodb/05_mongodb/01_update-user-controller/README.md @@ -0,0 +1,61 @@ +# Install Mongo + +# Go get driver for mongo + +``` +go get gopkg.in/mgo.v2 +go get gopkg.in/mgo.v2/bson +``` + +# In this step: + +Don't run this code + +Just making updates - a several step process. + +We will need a mongo session to use in the CRUD methods. + +We need our UserController to have access to a mongo session. + +Let's add this to controllers/user.go + +``` +UserController struct { + session *mgo.Session +} +``` + +And now add this to controllers/user.go + +``` +func NewUserController(s *mgo.Session) *UserController { + return &UserController{s} +} +``` + +And now add this to main.go + +``` +func getSession() *mgo.Session { + // Connect to our local mongo + s, err := mgo.Dial("mongodb://localhost") + + // Check if connection error, is mongo running? + if err != nil { + panic(err) + } + return s +} +``` + +and this + +``` +uc := controllers.NewUserController(getSession()) +``` + +1. Enter this at the terminal + +``` +curl http://localhost:8080/user/1 +``` \ No newline at end of file diff --git a/042_mongodb/05_mongodb/01_update-user-controller/controllers/user.go b/042_mongodb/05_mongodb/01_update-user-controller/controllers/user.go new file mode 100644 index 00000000..ec99de83 --- /dev/null +++ b/042_mongodb/05_mongodb/01_update-user-controller/controllers/user.go @@ -0,0 +1,60 @@ +package controllers + +import ( + "encoding/json" + "fmt" + "github.com/GoesToEleven/golang-web-dev/042_mongodb/05_mongodb/01_update-user-controller/models" + "github.com/julienschmidt/httprouter" + "gopkg.in/mgo.v2" + "net/http" +) + +// added session to our userController +type UserController struct { + session *mgo.Session +} + +// added session to our userController +func NewUserController(s *mgo.Session) *UserController { + return &UserController{s} +} + +func (uc UserController) GetUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + u := models.User{ + Name: "James Bond", + Gender: "male", + Age: 32, + Id: p.ByName("id"), + } + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) CreateUser(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + u := models.User{} + + json.NewDecoder(r.Body).Decode(&u) + + u.Id = "007" + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) // 201 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) DeleteUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + // TODO: only write code to delete user + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprint(w, "Write code to delete user\n") +} diff --git a/042_mongodb/05_mongodb/01_update-user-controller/main.go b/042_mongodb/05_mongodb/01_update-user-controller/main.go new file mode 100644 index 00000000..f3fdcfef --- /dev/null +++ b/042_mongodb/05_mongodb/01_update-user-controller/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "github.com/GoesToEleven/golang-web-dev/042_mongodb/05_mongodb/01_update-user-controller/controllers" + "github.com/julienschmidt/httprouter" + "gopkg.in/mgo.v2" + "net/http" +) + +func main() { + r := httprouter.New() + // Get a UserController instance + uc := controllers.NewUserController(getSession()) + r.GET("/user/:id", uc.GetUser) + r.POST("/user", uc.CreateUser) + r.DELETE("/user/:id", uc.DeleteUser) + http.ListenAndServe("localhost:8080", r) +} + +func getSession() *mgo.Session { + // Connect to our local mongo + s, err := mgo.Dial("mongodb://localhost") + + // Check if connection error, is mongo running? + if err != nil { + panic(err) + } + return s +} diff --git a/042_mongodb/05_mongodb/01_update-user-controller/models/user.go b/042_mongodb/05_mongodb/01_update-user-controller/models/user.go new file mode 100644 index 00000000..63a12406 --- /dev/null +++ b/042_mongodb/05_mongodb/01_update-user-controller/models/user.go @@ -0,0 +1,8 @@ +package models + +type User struct { + Name string `json:"name"` + Gender string `json:"gender"` + Age int `json:"age"` + Id string `json:"id"` +} diff --git a/042_mongodb/05_mongodb/02_update-user-model/README.md b/042_mongodb/05_mongodb/02_update-user-model/README.md new file mode 100644 index 00000000..bea06dbe --- /dev/null +++ b/042_mongodb/05_mongodb/02_update-user-model/README.md @@ -0,0 +1,24 @@ +Don't run this code + +Just making updates - a several step process. + +IMPORTANT: +Make sure you update your import statements to import packages from the correct location! + +In this step: + +MongoDB represents JSON documents in binary-encoded format called BSON behind the scenes. BSON extends the JSON model to provide additional data types and to be efficient for encoding and decoding within different languages. + +We will update our user model to change the type of our Id field to be a bson.ObjectId + +Add this to models/user.go + +``` +type User struct { + Name string `json:"name" bson:"name"` + Gender string `json:"gender" bson:"gender"` + Age int `json:"age" bson:"age"` + Id bson.ObjectId `json:"id" bson:"_id"` +} + +``` \ No newline at end of file diff --git a/042_mongodb/05_mongodb/02_update-user-model/controllers/user.go b/042_mongodb/05_mongodb/02_update-user-model/controllers/user.go new file mode 100644 index 00000000..347fcbf4 --- /dev/null +++ b/042_mongodb/05_mongodb/02_update-user-model/controllers/user.go @@ -0,0 +1,59 @@ +package controllers + +import ( + "encoding/json" + "fmt" + "github.com/GoesToEleven/golang-web-dev/042_mongodb/05_mongodb/02_update-user-model/models" + "github.com/julienschmidt/httprouter" + "gopkg.in/mgo.v2" + "net/http" +) + +type UserController struct { + session *mgo.Session +} + +func NewUserController(s *mgo.Session) *UserController { + return &UserController{s} +} + +func (uc UserController) GetUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + u := models.User{ + Name: "James Bond", + Gender: "male", + Age: 32, + Id: p.ByName("id"), + } + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) CreateUser(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + u := models.User{} + + json.NewDecoder(r.Body).Decode(&u) + + u.Id = "007" + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) // 201 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) DeleteUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + // TODO: only write code to delete user + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprint(w, "Write code to delete user\n") +} diff --git a/042_mongodb/05_mongodb/02_update-user-model/main.go b/042_mongodb/05_mongodb/02_update-user-model/main.go new file mode 100644 index 00000000..bb869598 --- /dev/null +++ b/042_mongodb/05_mongodb/02_update-user-model/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "github.com/GoesToEleven/golang-web-dev/042_mongodb/05_mongodb/02_update-user-model/controllers" + "github.com/julienschmidt/httprouter" + "gopkg.in/mgo.v2" + "net/http" +) + +func main() { + r := httprouter.New() + uc := controllers.NewUserController(getSession()) + r.GET("/user/:id", uc.GetUser) + r.POST("/user", uc.CreateUser) + r.DELETE("/user/:id", uc.DeleteUser) + http.ListenAndServe("localhost:8080", r) +} + +func getSession() *mgo.Session { + s, err := mgo.Dial("mongodb://localhost") + + if err != nil { + panic(err) + } + return s +} diff --git a/042_mongodb/05_mongodb/02_update-user-model/models/user.go b/042_mongodb/05_mongodb/02_update-user-model/models/user.go new file mode 100644 index 00000000..2cc8f12a --- /dev/null +++ b/042_mongodb/05_mongodb/02_update-user-model/models/user.go @@ -0,0 +1,12 @@ +package models + +import "gopkg.in/mgo.v2/bson" + +type User struct { + Name string `json:"name" bson:"name"` + Gender string `json:"gender" bson:"gender"` + Age int `json:"age" bson:"age"` + Id bson.ObjectId `json:"id" bson:"_id"` +} + +// Id was of type string before diff --git a/042_mongodb/05_mongodb/03_update-user-controllers-post/README.md b/042_mongodb/05_mongodb/03_update-user-controllers-post/README.md new file mode 100644 index 00000000..81aaac05 --- /dev/null +++ b/042_mongodb/05_mongodb/03_update-user-controllers-post/README.md @@ -0,0 +1,19 @@ +# Don't run this code yet + +We create an ObjectId using the bson package. + +We do this in controllers/user.go in func CreateUser + +``` + // create bson ID + u.Id = bson.NewObjectId() + +``` + +Second, we store the user in mongodb. + +We do this in controllers/user.go in func CreateUser + +``` +uc.session.DB("go-web-dev-db").C("users").Insert(u) +``` \ No newline at end of file diff --git a/042_mongodb/05_mongodb/03_update-user-controllers-post/controllers/user.go b/042_mongodb/05_mongodb/03_update-user-controllers-post/controllers/user.go new file mode 100644 index 00000000..ab4b90d4 --- /dev/null +++ b/042_mongodb/05_mongodb/03_update-user-controllers-post/controllers/user.go @@ -0,0 +1,64 @@ +package controllers + +import ( + "encoding/json" + "fmt" + "github.com/GoesToEleven/golang-web-dev/042_mongodb/05_mongodb/03_update-user-controllers-post/models" + "github.com/julienschmidt/httprouter" + "gopkg.in/mgo.v2" + "gopkg.in/mgo.v2/bson" + "net/http" +) + +type UserController struct { + session *mgo.Session +} + +func NewUserController(s *mgo.Session) *UserController { + return &UserController{s} +} + +func (uc UserController) GetUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + u := models.User{ + Name: "James Bond", + Gender: "male", + Age: 32, + Id: p.ByName("id"), + } + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) CreateUser(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + u := models.User{} + + json.NewDecoder(r.Body).Decode(&u) + + // create bson ID + u.Id = bson.NewObjectId() + + // store the user in mongodb + uc.session.DB("go-web-dev-db").C("users").Insert(u) + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) // 201 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) DeleteUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + // TODO: only write code to delete user + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprint(w, "Write code to delete user\n") +} diff --git a/042_mongodb/05_mongodb/03_update-user-controllers-post/main.go b/042_mongodb/05_mongodb/03_update-user-controllers-post/main.go new file mode 100644 index 00000000..d7ce9016 --- /dev/null +++ b/042_mongodb/05_mongodb/03_update-user-controllers-post/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "github.com/GoesToEleven/golang-web-dev/042_mongodb/05_mongodb/03_update-user-controllers-post/controllers" + "github.com/julienschmidt/httprouter" + "gopkg.in/mgo.v2" + "net/http" +) + +func main() { + r := httprouter.New() + uc := controllers.NewUserController(getSession()) + r.GET("/user/:id", uc.GetUser) + r.POST("/user", uc.CreateUser) + r.DELETE("/user/:id", uc.DeleteUser) + http.ListenAndServe("localhost:8080", r) +} + +func getSession() *mgo.Session { + s, err := mgo.Dial("mongodb://localhost") + + if err != nil { + panic(err) + } + return s +} diff --git a/042_mongodb/05_mongodb/03_update-user-controllers-post/models/user.go b/042_mongodb/05_mongodb/03_update-user-controllers-post/models/user.go new file mode 100644 index 00000000..9ae0fb52 --- /dev/null +++ b/042_mongodb/05_mongodb/03_update-user-controllers-post/models/user.go @@ -0,0 +1,10 @@ +package models + +import "gopkg.in/mgo.v2/bson" + +type User struct { + Name string `json:"name" bson:"name"` + Gender string `json:"gender" bson:"gender"` + Age int `json:"age" bson:"age"` + Id bson.ObjectId `json:"id" bson:"_id"` +} diff --git a/042_mongodb/05_mongodb/04_update-user-controllers-get/README.md b/042_mongodb/05_mongodb/04_update-user-controllers-get/README.md new file mode 100644 index 00000000..23e218cf --- /dev/null +++ b/042_mongodb/05_mongodb/04_update-user-controllers-get/README.md @@ -0,0 +1,68 @@ +# In this step: + +We will get a user from mongodb + +First we will get the user id from the URL + +``` +id := p.ByName("id") +``` + +Next we will Verify that the id is an ObjectId + +``` +if !bson.IsObjectIdHex(id) { + w.WriteHeader(http.StatusNotFound) // 404 + return +} +``` + +ObjectIdHex returns an ObjectId from the provided hex representation. + +``` + oid := bson.ObjectIdHex(id) +``` + +Now we will create an empty user to store the results in + +``` + u := models.User{} +``` + +And then we will get the user information + +``` +if err := uc.session.DB("go-web-dev-db").C("users").FindId(oid).One(&u); err != nil { + w.WriteHeader(404) + return +} +``` + + +# Run this code + +1. Start your server + +## POST a user to mongodb + +Enter this at the terminal + +``` +curl -X POST -H "Content-Type: application/json" -d '{"name":"James Bond","gender":"male","age":32}' http://localhost:8080/user +``` + +-X is short for --request +Specifies a custom request method to use when communicating with the HTTP server. + +-H is short for --header + +-d is short for --data + +## GET a user from mongodb + +Enter this at the terminal + +``` +curl http://localhost:8080/user/ + +``` \ No newline at end of file diff --git a/042_mongodb/05_mongodb/04_update-user-controllers-get/controllers/user.go b/042_mongodb/05_mongodb/04_update-user-controllers-get/controllers/user.go new file mode 100644 index 00000000..cbbc6e75 --- /dev/null +++ b/042_mongodb/05_mongodb/04_update-user-controllers-get/controllers/user.go @@ -0,0 +1,76 @@ +package controllers + +import ( + "encoding/json" + "fmt" + "github.com/GoesToEleven/golang-web-dev/042_mongodb/05_mongodb/04_update-user-controllers-get/models" + "github.com/julienschmidt/httprouter" + "gopkg.in/mgo.v2" + "gopkg.in/mgo.v2/bson" + "net/http" +) + +type UserController struct { + session *mgo.Session +} + +func NewUserController(s *mgo.Session) *UserController { + return &UserController{s} +} + +func (uc UserController) GetUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + // Grab id + id := p.ByName("id") + + // Verify id is ObjectId hex representation, otherwise return status not found + if !bson.IsObjectIdHex(id) { + w.WriteHeader(http.StatusNotFound) // 404 + return + } + + // ObjectIdHex returns an ObjectId from the provided hex representation. + oid := bson.ObjectIdHex(id) + + // composite literal + u := models.User{} + + // Fetch user + if err := uc.session.DB("go-web-dev-db").C("users").FindId(oid).One(&u); err != nil { + w.WriteHeader(404) + return + } + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) CreateUser(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + u := models.User{} + + json.NewDecoder(r.Body).Decode(&u) + + u.Id = bson.NewObjectId() + + uc.session.DB("go-web-dev-db").C("users").Insert(u) + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) // 201 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) DeleteUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + // TODO: only write code to delete user + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprint(w, "Write code to delete user\n") +} diff --git a/042_mongodb/05_mongodb/04_update-user-controllers-get/main.go b/042_mongodb/05_mongodb/04_update-user-controllers-get/main.go new file mode 100644 index 00000000..336cdf50 --- /dev/null +++ b/042_mongodb/05_mongodb/04_update-user-controllers-get/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "github.com/GoesToEleven/golang-web-dev/042_mongodb/05_mongodb/04_update-user-controllers-get/controllers" + "github.com/julienschmidt/httprouter" + "gopkg.in/mgo.v2" + "net/http" +) + +func main() { + r := httprouter.New() + uc := controllers.NewUserController(getSession()) + r.GET("/user/:id", uc.GetUser) + r.POST("/user", uc.CreateUser) + r.DELETE("/user/:id", uc.DeleteUser) + http.ListenAndServe("localhost:8080", r) +} + +func getSession() *mgo.Session { + s, err := mgo.Dial("mongodb://localhost") + + if err != nil { + panic(err) + } + return s +} diff --git a/042_mongodb/05_mongodb/04_update-user-controllers-get/models/user.go b/042_mongodb/05_mongodb/04_update-user-controllers-get/models/user.go new file mode 100644 index 00000000..7892c44f --- /dev/null +++ b/042_mongodb/05_mongodb/04_update-user-controllers-get/models/user.go @@ -0,0 +1,10 @@ +package models + +import "gopkg.in/mgo.v2/bson" + +type User struct { + Id bson.ObjectId `json:"id" bson:"_id"` + Name string `json:"name" bson:"name"` + Gender string `json:"gender" bson:"gender"` + Age int `json:"age" bson:"age"` +} diff --git a/042_mongodb/05_mongodb/05_update-user-controllers-delete/README.md b/042_mongodb/05_mongodb/05_update-user-controllers-delete/README.md new file mode 100644 index 00000000..f93ac03a --- /dev/null +++ b/042_mongodb/05_mongodb/05_update-user-controllers-delete/README.md @@ -0,0 +1,57 @@ +# In this step: + +We will delete a user from mongodb. + +This is identical to what we did in the last step to GET a user. + +First we will get the user id from the URL + +``` +id := p.ByName("id") +``` + +Next we will Verify that the id is an ObjectId + +``` +if !bson.IsObjectIdHex(id) { + w.WriteHeader(http.StatusNotFound) // 404 + return +} +``` + +ObjectIdHex returns an ObjectId from the provided hex representation. + +``` + oid := bson.ObjectIdHex(id) +``` + +Next, add code to delete the user + +``` +if err := uc.session.DB("go_rest_tutorial").C("users").RemoveId(oid); err != nil { + w.WriteHeader(404) + return +} +``` + +# Run this code + +1. Start your server + +## DELETE a user from mongodb + +Enter this at the terminal + +``` +curl -X POST -H "Content-Type: application/json" -d '{"name":"Miss Moneypenny","gender":"female","age":27}' http://localhost:8080/user +``` + +``` +curl http://localhost:8080/user/ + +``` + + +``` +curl -X DELETE http://localhost:8080/user/ +``` \ No newline at end of file diff --git a/042_mongodb/05_mongodb/05_update-user-controllers-delete/controllers/user.go b/042_mongodb/05_mongodb/05_update-user-controllers-delete/controllers/user.go new file mode 100644 index 00000000..a6a3fbaa --- /dev/null +++ b/042_mongodb/05_mongodb/05_update-user-controllers-delete/controllers/user.go @@ -0,0 +1,85 @@ +package controllers + +import ( + "encoding/json" + "fmt" + "github.com/GoesToEleven/golang-web-dev/042_mongodb/05_mongodb/05_update-user-controllers-delete/models" + "github.com/julienschmidt/httprouter" + "gopkg.in/mgo.v2" + "gopkg.in/mgo.v2/bson" + "net/http" +) + +type UserController struct { + session *mgo.Session +} + +func NewUserController(s *mgo.Session) *UserController { + return &UserController{s} +} + +func (uc UserController) GetUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + id := p.ByName("id") + + if !bson.IsObjectIdHex(id) { + w.WriteHeader(http.StatusNotFound) // 404 + return + } + + oid := bson.ObjectIdHex(id) + + u := models.User{} + + if err := uc.session.DB("go-web-dev-db").C("users").FindId(oid).One(&u); err != nil { + w.WriteHeader(404) + return + } + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) CreateUser(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + u := models.User{} + + json.NewDecoder(r.Body).Decode(&u) + + u.Id = bson.NewObjectId() + + uc.session.DB("go-web-dev-db").C("users").Insert(u) + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) // 201 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) DeleteUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + id := p.ByName("id") + + if !bson.IsObjectIdHex(id) { + w.WriteHeader(404) + return + } + + oid := bson.ObjectIdHex(id) + + // Delete user + if err := uc.session.DB("go-web-dev-db").C("users").RemoveId(oid); err != nil { + w.WriteHeader(404) + return + } + + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprint(w, "Deleted user", oid, "\n") +} diff --git a/042_mongodb/05_mongodb/05_update-user-controllers-delete/main.go b/042_mongodb/05_mongodb/05_update-user-controllers-delete/main.go new file mode 100644 index 00000000..ea395413 --- /dev/null +++ b/042_mongodb/05_mongodb/05_update-user-controllers-delete/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "github.com/julienschmidt/httprouter" + "gopkg.in/mgo.v2" + "net/http" + + "github.com/GoesToEleven/golang-web-dev/042_mongodb/05_mongodb/05_update-user-controllers-delete/controllers" +) + +func main() { + r := httprouter.New() + uc := controllers.NewUserController(getSession()) + r.GET("/user/:id", uc.GetUser) + r.POST("/user", uc.CreateUser) + r.DELETE("/user/:id", uc.DeleteUser) + http.ListenAndServe("localhost:8080", r) +} + +func getSession() *mgo.Session { + s, err := mgo.Dial("mongodb://localhost") + + if err != nil { + panic(err) + } + return s +} diff --git a/042_mongodb/05_mongodb/05_update-user-controllers-delete/models/user.go b/042_mongodb/05_mongodb/05_update-user-controllers-delete/models/user.go new file mode 100644 index 00000000..7892c44f --- /dev/null +++ b/042_mongodb/05_mongodb/05_update-user-controllers-delete/models/user.go @@ -0,0 +1,10 @@ +package models + +import "gopkg.in/mgo.v2/bson" + +type User struct { + Id bson.ObjectId `json:"id" bson:"_id"` + Name string `json:"name" bson:"name"` + Gender string `json:"gender" bson:"gender"` + Age int `json:"age" bson:"age"` +} diff --git a/042_mongodb/06_hands-on/README.md b/042_mongodb/06_hands-on/README.md new file mode 100644 index 00000000..a458482e --- /dev/null +++ b/042_mongodb/06_hands-on/README.md @@ -0,0 +1,10 @@ +# Use a map + +Use the code in the "starting code" folder. + +Remove mongodb from the code. + +Instead of using mongodb, store all of the data in a map. + +IMPORTANT: +Make sure you update your import statements to import packages from the correct location! \ No newline at end of file diff --git a/042_mongodb/06_hands-on/starting-code/controllers/user.go b/042_mongodb/06_hands-on/starting-code/controllers/user.go new file mode 100644 index 00000000..345fd95e --- /dev/null +++ b/042_mongodb/06_hands-on/starting-code/controllers/user.go @@ -0,0 +1,87 @@ +package controllers + +import ( + "encoding/json" + "fmt" + "github.com/GoesToEleven/golang-web-dev/040_mongodb/06_hands-on/starting-code/models" + "github.com/julienschmidt/httprouter" + "gopkg.in/mgo.v2" + "gopkg.in/mgo.v2/bson" + "net/http" +) + +type UserController struct { + session *mgo.Session +} + +func NewUserController(s *mgo.Session) *UserController { + return &UserController{s} +} + +func (uc UserController) GetUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + // Grab id + id := p.ByName("id") + + // Verify id is ObjectId hex representation, otherwise return status not found + if !bson.IsObjectIdHex(id) { + w.WriteHeader(http.StatusNotFound) // 404 + return + } + + // ObjectIdHex returns an ObjectId from the provided hex representation. + oid := bson.ObjectIdHex(id) + + // composite literal + u := models.User{} + + // Fetch user + if err := uc.session.DB("go-web-dev-db").C("users").FindId(oid).One(&u); err != nil { + w.WriteHeader(404) + return + } + + // Marshal provided interface into JSON structure + uj, _ := json.Marshal(u) + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) CreateUser(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + u := models.User{} + + json.NewDecoder(r.Body).Decode(&u) + + // create bson ID + u.Id = bson.NewObjectId() + + // store the user in mongodb + uc.session.DB("go-web-dev-db").C("users").Insert(u) + + uj, _ := json.Marshal(u) + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) // 201 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) DeleteUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + id := p.ByName("id") + + if !bson.IsObjectIdHex(id) { + w.WriteHeader(404) + return + } + + oid := bson.ObjectIdHex(id) + + // Delete user + if err := uc.session.DB("go-web-dev-db").C("users").RemoveId(oid); err != nil { + w.WriteHeader(404) + return + } + + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprint(w, "Deleted user", oid, "\n") +} diff --git a/042_mongodb/06_hands-on/starting-code/main.go b/042_mongodb/06_hands-on/starting-code/main.go new file mode 100644 index 00000000..e47ade07 --- /dev/null +++ b/042_mongodb/06_hands-on/starting-code/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "github.com/GoesToEleven/golang-web-dev/040_mongodb/06_hands-on/starting-code/controllers" + "github.com/julienschmidt/httprouter" + "gopkg.in/mgo.v2" + "net/http" +) + +func main() { + r := httprouter.New() + // Get a UserController instance + uc := controllers.NewUserController(getSession()) + r.GET("/user/:id", uc.GetUser) + r.POST("/user", uc.CreateUser) + r.DELETE("/user/:id", uc.DeleteUser) + http.ListenAndServe("localhost:8080", r) +} + +func getSession() *mgo.Session { + // Connect to our local mongo + s, err := mgo.Dial("mongodb://localhost") + + // Check if connection error, is mongo running? + if err != nil { + panic(err) + } + return s +} diff --git a/042_mongodb/06_hands-on/starting-code/models/user.go b/042_mongodb/06_hands-on/starting-code/models/user.go new file mode 100644 index 00000000..94e05c63 --- /dev/null +++ b/042_mongodb/06_hands-on/starting-code/models/user.go @@ -0,0 +1,12 @@ +package models + +import "gopkg.in/mgo.v2/bson" + +type User struct { + Id bson.ObjectId `json:"id" bson:"_id"` + Name string `json:"name" bson:"name"` + Gender string `json:"gender" bson:"gender"` + Age int `json:"age" bson:"age"` +} + +// Id was of type string before diff --git a/042_mongodb/07_solution/controllers/user.go b/042_mongodb/07_solution/controllers/user.go new file mode 100644 index 00000000..79f65b4a --- /dev/null +++ b/042_mongodb/07_solution/controllers/user.go @@ -0,0 +1,65 @@ +package controllers + +import ( + "encoding/json" + "fmt" + "github.com/GoesToEleven/golang-web-dev/042_mongodb/07_solution/models" + "github.com/julienschmidt/httprouter" + "github.com/satori/go.uuid" + "net/http" +) + +type UserController struct { + session map[string]models.User +} + +func NewUserController(m map[string]models.User) *UserController { + return &UserController{m} +} + +func (uc UserController) GetUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + // Grab id + id := p.ByName("id") + + // Retrieve user + u := uc.session[id] + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) CreateUser(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + u := models.User{} + + json.NewDecoder(r.Body).Decode(&u) + + // create ID + u.Id = uuid.NewV4().String() + + // store the user + uc.session[u.Id] = u + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) // 201 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) DeleteUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + id := p.ByName("id") + + delete(uc.session, id) + + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprint(w, "Deleted user", id, "\n") +} diff --git a/042_mongodb/07_solution/main.go b/042_mongodb/07_solution/main.go new file mode 100644 index 00000000..95e80c79 --- /dev/null +++ b/042_mongodb/07_solution/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "github.com/GoesToEleven/golang-web-dev/042_mongodb/07_solution/controllers" + "github.com/GoesToEleven/golang-web-dev/042_mongodb/07_solution/models" + "github.com/julienschmidt/httprouter" + "net/http" +) + +func main() { + r := httprouter.New() + // Get a UserController instance + uc := controllers.NewUserController(getSession()) + r.GET("/user/:id", uc.GetUser) + r.POST("/user", uc.CreateUser) + r.DELETE("/user/:id", uc.DeleteUser) + http.ListenAndServe("localhost:8080", r) +} + +func getSession() map[string]models.User { + return make(map[string]models.User) +} diff --git a/042_mongodb/07_solution/models/user.go b/042_mongodb/07_solution/models/user.go new file mode 100644 index 00000000..9e4c179d --- /dev/null +++ b/042_mongodb/07_solution/models/user.go @@ -0,0 +1,9 @@ +package models + +// changed Id type to string +type User struct { + Id string `json:"id"` + Name string `json:"name" ` + Gender string `json:"gender"` + Age int `json:"age"` +} diff --git a/042_mongodb/08_hands-on/README.md b/042_mongodb/08_hands-on/README.md new file mode 100644 index 00000000..5b28fa44 --- /dev/null +++ b/042_mongodb/08_hands-on/README.md @@ -0,0 +1,12 @@ +# Use a map + +Use the code in the previous folder "07_solution". + +There is a map that holds all of the user data. + +Every time a user is created or deleted, write this map as JSON to a file. + +Also, when your program starts, if there is a file with JSON data in it, load that data. + +IMPORTANT: +Make sure you update your import statements to import packages from the correct location! \ No newline at end of file diff --git a/042_mongodb/09_solution/README.md b/042_mongodb/09_solution/README.md new file mode 100644 index 00000000..c6639941 --- /dev/null +++ b/042_mongodb/09_solution/README.md @@ -0,0 +1,47 @@ +# Run this code + +1. Start your server +You must use "go build" as you need to build a binary that includes a dependency (models package). + +``` +go build -o cowgirl +./cowgirl +``` +## POST users + +Enter these commands at the terminal + +``` +curl -X POST -H "Content-Type: application/json" -d '{"name":"James Bond","gender":"male","age":32}' http://localhost:8080/user +``` + +``` +curl -X POST -H "Content-Type: application/json" -d '{"name":"Miss Moneypenny","gender":"female","age":27}' http://localhost:8080/user +``` + +``` +curl -X POST -H "Content-Type: application/json" -d '{"name":"Q","gender":"female","age":54}' http://localhost:8080/user +``` + +-X is short for --request +Specifies a custom request method to use when communicating with the HTTP server. + +-H is short for --header + +-d is short for --data + +## GET a user + +Enter this at the terminal + +``` +curl http://localhost:8080/user/ + + +## DELETE a user + +Enter this at the terminal + +``` +curl -X DELETE http://localhost:8080/user/ +``` \ No newline at end of file diff --git a/042_mongodb/09_solution/controllers/user.go b/042_mongodb/09_solution/controllers/user.go new file mode 100644 index 00000000..8d13d344 --- /dev/null +++ b/042_mongodb/09_solution/controllers/user.go @@ -0,0 +1,68 @@ +package controllers + +import ( + "encoding/json" + "fmt" + "github.com/GoesToEleven/golang-web-dev/042_mongodb/09_solution/models" + "github.com/julienschmidt/httprouter" + "github.com/satori/go.uuid" + "net/http" +) + +type UserController struct { + session map[string]models.User +} + +func NewUserController(m map[string]models.User) *UserController { + return &UserController{m} +} + +func (uc UserController) GetUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + // Grab id + id := p.ByName("id") + + // Retrieve user + u := uc.session[id] + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) CreateUser(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + u := models.User{} + + json.NewDecoder(r.Body).Decode(&u) + + // create ID + u.Id = uuid.NewV4().String() + + // store the user + uc.session[u.Id] = u + models.StoreUsers(uc.session) + + uj, err := json.Marshal(u) + if err != nil { + fmt.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) // 201 + fmt.Fprintf(w, "%s\n", uj) +} + +func (uc UserController) DeleteUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + id := p.ByName("id") + + delete(uc.session, id) + + models.StoreUsers(uc.session) + + w.WriteHeader(http.StatusOK) // 200 + fmt.Fprint(w, "Deleted user ", id, "\n") +} diff --git a/042_mongodb/09_solution/data b/042_mongodb/09_solution/data new file mode 100644 index 00000000..d60141ea --- /dev/null +++ b/042_mongodb/09_solution/data @@ -0,0 +1 @@ +{"ff69705b-0c6d-479d-ae12-71acf86587cf":{"id":"ff69705b-0c6d-479d-ae12-71acf86587cf","name":"Miss Moneypenny","gender":"female","age":27}} diff --git a/042_mongodb/09_solution/main.go b/042_mongodb/09_solution/main.go new file mode 100644 index 00000000..0b712be6 --- /dev/null +++ b/042_mongodb/09_solution/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "github.com/GoesToEleven/golang-web-dev/042_mongodb/09_solution/controllers" + "github.com/GoesToEleven/golang-web-dev/042_mongodb/09_solution/models" + "github.com/julienschmidt/httprouter" + "net/http" +) + +func main() { + r := httprouter.New() + // Get a UserController instance + uc := controllers.NewUserController(getSession()) + r.GET("/user/:id", uc.GetUser) + r.POST("/user", uc.CreateUser) + r.DELETE("/user/:id", uc.DeleteUser) + http.ListenAndServe("localhost:8080", r) +} + +func getSession() map[string]models.User { + return models.LoadUsers() +} diff --git a/042_mongodb/09_solution/models/user.go b/042_mongodb/09_solution/models/user.go new file mode 100644 index 00000000..8f8ac512 --- /dev/null +++ b/042_mongodb/09_solution/models/user.go @@ -0,0 +1,42 @@ +package models + +import ( + "encoding/json" + "fmt" + "os" +) + +// changed Id type to string +type User struct { + Id string `json:"id"` + Name string `json:"name" ` + Gender string `json:"gender"` + Age int `json:"age"` +} + +func StoreUsers(m map[string]User) { + f, err := os.Create("data") + if err != nil { + fmt.Println(err) + } + defer f.Close() + + json.NewEncoder(f).Encode(m) +} + +func LoadUsers() map[string]User { + m := make(map[string]User) + + f, err := os.Open("data") + if err != nil { + fmt.Println(err) + return m + } + defer f.Close() + + err = json.NewDecoder(f).Decode(&m) + if err != nil { + fmt.Println(err) + } + return m +} diff --git a/042_mongodb/10_hands-on/README.md b/042_mongodb/10_hands-on/README.md new file mode 100644 index 00000000..f4e16970 --- /dev/null +++ b/042_mongodb/10_hands-on/README.md @@ -0,0 +1,9 @@ +# Use packages + +Modify our session code in "starting-code" to use these packages: + +1. controllers +1. models +1. session + +Refactor code as necessary to put code into appropriate packages. \ No newline at end of file diff --git a/042_mongodb/10_hands-on/starting-code/main.go b/042_mongodb/10_hands-on/starting-code/main.go new file mode 100644 index 00000000..690231d9 --- /dev/null +++ b/042_mongodb/10_hands-on/starting-code/main.go @@ -0,0 +1,170 @@ +package main + +import ( + "github.com/satori/go.uuid" + "golang.org/x/crypto/bcrypt" + "html/template" + "net/http" + "time" +) + +type user struct { + UserName string + Password []byte + First string + Last string + Role string +} + +type session struct { + un string + lastActivity time.Time +} + +var tpl *template.Template +var dbUsers = map[string]user{} // user ID, user +var dbSessions = map[string]session{} // session ID, session +var dbSessionsCleaned time.Time + +const sessionLength int = 30 + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) + dbSessionsCleaned = time.Now() +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/bar", bar) + http.HandleFunc("/signup", signup) + http.HandleFunc("/login", login) + http.HandleFunc("/logout", logout) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, req *http.Request) { + u := getUser(w, req) + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "index.gohtml", u) +} + +func bar(w http.ResponseWriter, req *http.Request) { + u := getUser(w, req) + if !alreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + if u.Role != "007" { + http.Error(w, "You must be 007 to enter the bar", http.StatusForbidden) + return + } + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "bar.gohtml", u) +} + +func signup(w http.ResponseWriter, req *http.Request) { + if alreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + var u user + // process form submission + if req.Method == http.MethodPost { + // get form values + un := req.FormValue("username") + p := req.FormValue("password") + f := req.FormValue("firstname") + l := req.FormValue("lastname") + r := req.FormValue("role") + // username taken? + if _, ok := dbUsers[un]; ok { + http.Error(w, "Username already taken", http.StatusForbidden) + return + } + // create session + sID, _ := uuid.NewV4() + c := &http.Cookie{ + Name: "session", + Value: sID.String(), + } + c.MaxAge = sessionLength + http.SetCookie(w, c) + dbSessions[c.Value] = session{un, time.Now()} + // store user in dbUsers + bs, err := bcrypt.GenerateFromPassword([]byte(p), bcrypt.MinCost) + if err != nil { + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } + u = user{un, bs, f, l, r} + dbUsers[un] = u + // redirect + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "signup.gohtml", u) +} + +func login(w http.ResponseWriter, req *http.Request) { + if alreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + var u user + // process form submission + if req.Method == http.MethodPost { + un := req.FormValue("username") + p := req.FormValue("password") + // is there a username? + u, ok := dbUsers[un] + if !ok { + http.Error(w, "Username and/or password do not match", http.StatusForbidden) + return + } + // does the entered password match the stored password? + err := bcrypt.CompareHashAndPassword(u.Password, []byte(p)) + if err != nil { + http.Error(w, "Username and/or password do not match", http.StatusForbidden) + return + } + // create session + sID, _ := uuid.NewV4() + c := &http.Cookie{ + Name: "session", + Value: sID.String(), + } + c.MaxAge = sessionLength + http.SetCookie(w, c) + dbSessions[c.Value] = session{un, time.Now()} + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + showSessions() // for demonstration purposes + tpl.ExecuteTemplate(w, "login.gohtml", u) +} + +func logout(w http.ResponseWriter, req *http.Request) { + if !alreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + c, _ := req.Cookie("session") + // delete the session + delete(dbSessions, c.Value) + // remove the cookie + c = &http.Cookie{ + Name: "session", + Value: "", + MaxAge: -1, + } + http.SetCookie(w, c) + + // clean up dbSessions + if time.Now().Sub(dbSessionsCleaned) > (time.Second * 30) { + go cleanSessions() + } + + http.Redirect(w, req, "/login", http.StatusSeeOther) +} diff --git a/042_mongodb/10_hands-on/starting-code/session.go b/042_mongodb/10_hands-on/starting-code/session.go new file mode 100644 index 00000000..94488c1b --- /dev/null +++ b/042_mongodb/10_hands-on/starting-code/session.go @@ -0,0 +1,71 @@ +package main + +import ( + "fmt" + "github.com/satori/go.uuid" + "net/http" + "time" +) + +func getUser(w http.ResponseWriter, req *http.Request) user { + // get cookie + c, err := req.Cookie("session") + if err != nil { + sID, _ := uuid.NewV4() + c = &http.Cookie{ + Name: "session", + Value: sID.String(), + } + + } + c.MaxAge = sessionLength + http.SetCookie(w, c) + + // if the user exists already, get user + var u user + if s, ok := dbSessions[c.Value]; ok { + s.lastActivity = time.Now() + dbSessions[c.Value] = s + u = dbUsers[s.un] + } + return u +} + +func alreadyLoggedIn(w http.ResponseWriter, req *http.Request) bool { + c, err := req.Cookie("session") + if err != nil { + return false + } + s, ok := dbSessions[c.Value] + if ok { + s.lastActivity = time.Now() + dbSessions[c.Value] = s + } + _, ok = dbUsers[s.un] + // refresh session + c.MaxAge = sessionLength + http.SetCookie(w, c) + return ok +} + +func cleanSessions() { + fmt.Println("BEFORE CLEAN") // for demonstration purposes + showSessions() // for demonstration purposes + for k, v := range dbSessions { + if time.Now().Sub(v.lastActivity) > (time.Second * 30) { + delete(dbSessions, k) + } + } + dbSessionsCleaned = time.Now() + fmt.Println("AFTER CLEAN") // for demonstration purposes + showSessions() // for demonstration purposes +} + +// for demonstration purposes +func showSessions() { + fmt.Println("********") + for k, v := range dbSessions { + fmt.Println(k, v.un) + } + fmt.Println("") +} diff --git a/042_mongodb/10_hands-on/starting-code/templates/bar.gohtml b/042_mongodb/10_hands-on/starting-code/templates/bar.gohtml new file mode 100644 index 00000000..ddd56835 --- /dev/null +++ b/042_mongodb/10_hands-on/starting-code/templates/bar.gohtml @@ -0,0 +1,20 @@ + + + + + BAR + + + +

Welcome to the bar. What can I get you to drink?

+ +{{if .First}} +USER NAME {{.UserName}}
+PASSWORD {{.Password}}
+FIRST {{.First}}
+LAST {{.Last}}
+

log out

+{{end}} + + + \ No newline at end of file diff --git a/042_mongodb/10_hands-on/starting-code/templates/index.gohtml b/042_mongodb/10_hands-on/starting-code/templates/index.gohtml new file mode 100644 index 00000000..3bc10844 --- /dev/null +++ b/042_mongodb/10_hands-on/starting-code/templates/index.gohtml @@ -0,0 +1,24 @@ + + + + + Document + + + +{{if .First}} +USER NAME {{.UserName}}
+PASSWORD {{.Password}}
+FIRST {{.First}}
+LAST {{.Last}}
+

log out

+{{else}} +

sign up

+

log in

+{{end}} + +
+

Go to the bar

+ + + \ No newline at end of file diff --git a/042_mongodb/10_hands-on/starting-code/templates/login.gohtml b/042_mongodb/10_hands-on/starting-code/templates/login.gohtml new file mode 100644 index 00000000..eb155256 --- /dev/null +++ b/042_mongodb/10_hands-on/starting-code/templates/login.gohtml @@ -0,0 +1,18 @@ + + + + + Document + + + +

LOGIN

+
+ + + +
+

signup

+ + + \ No newline at end of file diff --git a/042_mongodb/10_hands-on/starting-code/templates/signup.gohtml b/042_mongodb/10_hands-on/starting-code/templates/signup.gohtml new file mode 100644 index 00000000..e9188a11 --- /dev/null +++ b/042_mongodb/10_hands-on/starting-code/templates/signup.gohtml @@ -0,0 +1,26 @@ + + + + + Document + + + +
+ +
+
+
+
+ + + + +
+ + + \ No newline at end of file diff --git a/042_mongodb/11_solution/README.md b/042_mongodb/11_solution/README.md new file mode 100644 index 00000000..fe919152 --- /dev/null +++ b/042_mongodb/11_solution/README.md @@ -0,0 +1,6 @@ +# Run this code + +at the terminal: + +go build -o wildwest +./wildwest \ No newline at end of file diff --git a/042_mongodb/11_solution/controllers/general.go b/042_mongodb/11_solution/controllers/general.go new file mode 100644 index 00000000..b9236ab5 --- /dev/null +++ b/042_mongodb/11_solution/controllers/general.go @@ -0,0 +1,35 @@ +package controllers + +import ( + "github.com/GoesToEleven/golang-web-dev/042_mongodb/11_solution/session" + "html/template" + "net/http" +) + +type Controller struct { + tpl *template.Template +} + +func NewController(t *template.Template) *Controller { + return &Controller{t} +} + +func (c Controller) Index(w http.ResponseWriter, req *http.Request) { + u := session.GetUser(w, req) + session.Show() // for demonstration purposes + c.tpl.ExecuteTemplate(w, "index.gohtml", u) +} + +func (c Controller) Bar(w http.ResponseWriter, req *http.Request) { + u := session.GetUser(w, req) + if !session.AlreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + if u.Role != "007" { + http.Error(w, "You must be 007 to enter the bar", http.StatusForbidden) + return + } + session.Show() // for demonstration purposes + c.tpl.ExecuteTemplate(w, "bar.gohtml", u) +} diff --git a/042_mongodb/11_solution/controllers/user.go b/042_mongodb/11_solution/controllers/user.go new file mode 100644 index 00000000..82f6dd6b --- /dev/null +++ b/042_mongodb/11_solution/controllers/user.go @@ -0,0 +1,116 @@ +package controllers + +import ( + "github.com/GoesToEleven/golang-web-dev/042_mongodb/11_solution/models" + "github.com/GoesToEleven/golang-web-dev/042_mongodb/11_solution/session" + "github.com/satori/go.uuid" + "golang.org/x/crypto/bcrypt" + "net/http" + "time" +) + +func (c Controller) SignUp(w http.ResponseWriter, req *http.Request) { + if session.AlreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + var u models.User + // process form submission + if req.Method == http.MethodPost { + // get form values + un := req.FormValue("username") + p := req.FormValue("password") + f := req.FormValue("firstname") + l := req.FormValue("lastname") + r := req.FormValue("role") + // username taken? + if _, ok := session.Users[un]; ok { + http.Error(w, "Username already taken", http.StatusForbidden) + return + } + // create session + sID, _ := uuid.NewV4() + ck := &http.Cookie{ + Name: "session", + Value: sID.String(), + } + ck.MaxAge = session.Length + http.SetCookie(w, ck) + session.Sessions[ck.Value] = models.Session{un, time.Now()} + // store user in session.Users + bs, err := bcrypt.GenerateFromPassword([]byte(p), bcrypt.MinCost) + if err != nil { + http.Error(w, "Internal server error", http.StatusInternalServerError) + return + } + u = models.User{un, bs, f, l, r} + session.Users[un] = u + // redirect + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + session.Show() // for demonstration purposes + c.tpl.ExecuteTemplate(w, "signup.gohtml", u) +} + +func (c Controller) Login(w http.ResponseWriter, req *http.Request) { + if session.AlreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + var u models.User + // process form submission + if req.Method == http.MethodPost { + un := req.FormValue("username") + p := req.FormValue("password") + // is there a username? + u, ok := session.Users[un] + if !ok { + http.Error(w, "Username and/or password do not match", http.StatusForbidden) + return + } + // does the entered password match the stored password? + err := bcrypt.CompareHashAndPassword(u.Password, []byte(p)) + if err != nil { + http.Error(w, "Username and/or password do not match", http.StatusForbidden) + return + } + // create session + sID, _ := uuid.NewV4() + ck := &http.Cookie{ + Name: "session", + Value: sID.String(), + } + ck.MaxAge = session.Length + http.SetCookie(w, ck) + session.Sessions[ck.Value] = models.Session{un, time.Now()} + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + session.Show() // for demonstration purposes + c.tpl.ExecuteTemplate(w, "login.gohtml", u) +} + +func (c Controller) Logout(w http.ResponseWriter, req *http.Request) { + if !session.AlreadyLoggedIn(w, req) { + http.Redirect(w, req, "/", http.StatusSeeOther) + return + } + ck, _ := req.Cookie("session") + // delete the session + delete(session.Sessions, ck.Value) + // remove the cookie + ck = &http.Cookie{ + Name: "session", + Value: "", + MaxAge: -1, + } + http.SetCookie(w, ck) + + // clean up session.Sessions + if time.Now().Sub(session.LastCleaned) > (time.Second * 30) { + go session.Clean() + } + + http.Redirect(w, req, "/login", http.StatusSeeOther) +} diff --git a/042_mongodb/11_solution/main.go b/042_mongodb/11_solution/main.go new file mode 100644 index 00000000..798b0bbd --- /dev/null +++ b/042_mongodb/11_solution/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "github.com/GoesToEleven/golang-web-dev/042_mongodb/11_solution/controllers" + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + c := controllers.NewController(tpl) + http.HandleFunc("/", c.Index) + http.HandleFunc("/bar", c.Bar) + http.HandleFunc("/signup", c.SignUp) + http.HandleFunc("/login", c.Login) + http.HandleFunc("/logout", c.Logout) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} diff --git a/042_mongodb/11_solution/models/user.go b/042_mongodb/11_solution/models/user.go new file mode 100644 index 00000000..cc6214a6 --- /dev/null +++ b/042_mongodb/11_solution/models/user.go @@ -0,0 +1,18 @@ +package models + +import "time" + +// capitalize to export from package +type User struct { + UserName string + Password []byte + First string + Last string + Role string +} + +// capitalize to export from package +type Session struct { + UserName string + LastActivity time.Time +} diff --git a/042_mongodb/11_solution/session/session.go b/042_mongodb/11_solution/session/session.go new file mode 100644 index 00000000..f7cae192 --- /dev/null +++ b/042_mongodb/11_solution/session/session.go @@ -0,0 +1,78 @@ +package session + +import ( + "fmt" + "github.com/GoesToEleven/golang-web-dev/042_mongodb/11_solution/models" + "github.com/satori/go.uuid" + "net/http" + "time" +) + +const Length int = 30 + +var Users = map[string]models.User{} // user ID, user +var Sessions = map[string]models.Session{} // session ID, session +var LastCleaned time.Time = time.Now() + +func GetUser(w http.ResponseWriter, req *http.Request) models.User { + // get cookie + ck, err := req.Cookie("session") + if err != nil { + sID, _ := uuid.NewV4() + ck = &http.Cookie{ + Name: "session", + Value: sID.String(), + } + + } + ck.MaxAge = Length + http.SetCookie(w, ck) + + // if the user exists already, get user + var u models.User + if s, ok := Sessions[ck.Value]; ok { + s.LastActivity = time.Now() + Sessions[ck.Value] = s + u = Users[s.UserName] + } + return u +} + +func AlreadyLoggedIn(w http.ResponseWriter, req *http.Request) bool { + ck, err := req.Cookie("session") + if err != nil { + return false + } + s, ok := Sessions[ck.Value] + if ok { + s.LastActivity = time.Now() + Sessions[ck.Value] = s + } + _, ok = Users[s.UserName] + // refresh session + ck.MaxAge = Length + http.SetCookie(w, ck) + return ok +} + +func Clean() { + fmt.Println("BEFORE CLEAN") // for demonstration purposes + Show() // for demonstration purposes + for k, v := range Sessions { + if time.Now().Sub(v.LastActivity) > (time.Second * 30) { + delete(Sessions, k) + } + } + LastCleaned = time.Now() + fmt.Println("AFTER CLEAN") // for demonstration purposes + Show() // for demonstration purposes +} + +// for demonstration purposes +func Show() { + fmt.Println("********") + for k, v := range Sessions { + fmt.Println(k, v.UserName) + } + fmt.Println("") +} diff --git a/042_mongodb/11_solution/templates/bar.gohtml b/042_mongodb/11_solution/templates/bar.gohtml new file mode 100644 index 00000000..ddd56835 --- /dev/null +++ b/042_mongodb/11_solution/templates/bar.gohtml @@ -0,0 +1,20 @@ + + + + + BAR + + + +

Welcome to the bar. What can I get you to drink?

+ +{{if .First}} +USER NAME {{.UserName}}
+PASSWORD {{.Password}}
+FIRST {{.First}}
+LAST {{.Last}}
+

log out

+{{end}} + + + \ No newline at end of file diff --git a/042_mongodb/11_solution/templates/index.gohtml b/042_mongodb/11_solution/templates/index.gohtml new file mode 100644 index 00000000..3bc10844 --- /dev/null +++ b/042_mongodb/11_solution/templates/index.gohtml @@ -0,0 +1,24 @@ + + + + + Document + + + +{{if .First}} +USER NAME {{.UserName}}
+PASSWORD {{.Password}}
+FIRST {{.First}}
+LAST {{.Last}}
+

log out

+{{else}} +

sign up

+

log in

+{{end}} + +
+

Go to the bar

+ + + \ No newline at end of file diff --git a/042_mongodb/11_solution/templates/login.gohtml b/042_mongodb/11_solution/templates/login.gohtml new file mode 100644 index 00000000..eb155256 --- /dev/null +++ b/042_mongodb/11_solution/templates/login.gohtml @@ -0,0 +1,18 @@ + + + + + Document + + + +

LOGIN

+
+ + + +
+

signup

+ + + \ No newline at end of file diff --git a/042_mongodb/11_solution/templates/signup.gohtml b/042_mongodb/11_solution/templates/signup.gohtml new file mode 100644 index 00000000..e9188a11 --- /dev/null +++ b/042_mongodb/11_solution/templates/signup.gohtml @@ -0,0 +1,26 @@ + + + + + Document + + + +
+ +
+
+
+
+ + + + +
+ + + \ No newline at end of file diff --git a/042_mongodb/11_solution/wildwest b/042_mongodb/11_solution/wildwest new file mode 100644 index 00000000..35d0d136 Binary files /dev/null and b/042_mongodb/11_solution/wildwest differ diff --git a/043_docker/01_about-containers/README.md b/043_docker/01_about-containers/README.md new file mode 100644 index 00000000..810c76d6 --- /dev/null +++ b/043_docker/01_about-containers/README.md @@ -0,0 +1,119 @@ +# Applications & machines + +Back in the day, an application would be created and run on a machine. There was a ratio of 1:1. One application, one machine. + +When wondering what type of a machine to purchase for their application, developers always purchased the most powerful machine possible. There was no certainty as to how much an application might be in demand. To cover their asses, they errored on the side of too much power instead of not enough. + +The result of this: many machines were greatly underutilized. Many machines only ran at a small fraction of their capacity. + +# Virtual machines + +There were many machines with unused capacity. + +Virtual machines found a way to use that capacity. + +One physical machine could host several virtual machines. + +Each virtual machine appeared just like a real machine to its user. + +Here is an image from [docker's website](https://www.docker.com/what-docker) that shows the architecture of virtual machines: + +![Virtual Machines](vm.png) + +There was a downside to this, though: each virtual machine had its own operating system. This created license and maintenance costs, as well as using up resources on the physical machine. + +The question arose: **Is there a way to divide up a physical machine, but only have one operating system on that machine?** + +# Containers + +Linux is built in such a way that you can create separate user spaces. + +Each user space is in a separate isolated "sandbox" area. Each user space has its own file system and processes. These user spaces are all segregated and separate from each other. + +Containers leverage this technology of the Linux operating system. + +A container is just like a virtual machine WITHOUT THE OPERATING SYSTEM. + +Each PHYSICAL MACHINE has ONE LINUX OPERATING SYSTEM. + +Containers use the Linux OS of the physical machine. + +To the user, each container appears just like a real machine. + +Here is an image from [docker's website](https://www.docker.com/what-docker) that shows a comparison between virtual machines and containers: + +![Virtual Machines vs Containers](vm-containers.png) + +Containers and virtual machines have similar resource isolation and allocation benefits -- but a different architectural approach allows containers to be more portable and efficient. + +## Virtual machines + +Virtual machines include the application, the necessary binaries and libraries, and an entire guest operating system -- all of which can amount to tens of GBs. + +## Containers + +Containers include the application and all of its dependencies --but share the kernel with other containers, running as isolated processes in user space on the host operating system. **Docker containers are not tied to any specific infrastructure: they run on any computer, on any infrastructure, and in any cloud.** + +# Docker + +Docker is the most popular container system. + +You build an **IMAGE** and then create as many **CONTAINERS** as you would like from that image. + +You can then run those containers on physical machines. + +Docker containers run on Linux, Mac OS, and Windows. + +The official description: Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production. +[source](https://docs.docker.com/engine/understanding-docker/) + +![Docker](docker.png) + +# Docker benefits + + +## Run anywhere, easily + +Docker containers wrap a piece of software in a complete filesystem that contains everything needed to run: code, runtime, system tools, system libraries – anything that can be installed on a server. This guarantees that the software will always run the same, regardless of its environment. + +Docker containers are based on open standards, enabling containers to run on all major Linux distributions and on Microsoft Windows -- and on top of any infrastructure. + +## Secure + +Containers isolate applications from one another and the underlying infrastructure + +## Lightweight + +Containers running on a single machine share the same operating system kernel; they start instantly and use less RAM than VMs. + +## Accelerate developers + +Stop wasting hours setting up developer environments, spinning up new instances, and making copies of production code to run locally. With Docker, you simply take copies of your live environment and run them on any new endpoint running a Docker engine. + +## Focus on microservices + +The isolation capabilities of Docker containers free developers from constraints: they can use the best language and tools for their application services without worrying about causing internal tooling conflicts. + +## Collaborate + +Docker creates a common framework for developers and sysadmins to work together on distributed applications + +## Docker repositories (like Docker hub) + +Store, distribute, and manage Docker images in Docker Hub with your team. Image updates, changes, and history are automatically shared across your organization. + +## SHIP 7X MORE + +On average, Docker users ship 7X more software after deploying Docker in their environment. More frequent software updates provide added value to customers. + +## Scale + +Docker containers spin up and down in seconds, making it easy to scale application services to satisfy peak customer demand, and then reduce running containers when demand ebbs. + +## Debugging + +Docker makes it easy to identify issues, isolate the problem container, quickly roll back to make the necessary changes, and then push the updated container into production. Isolation between containers makes these changes less disruptive than in traditional software models. + +## Orchestration + +Automate deployment, scaling, and management of containerized applications with **Docker Swarm** or **Kubernetes**. \ No newline at end of file diff --git a/043_docker/01_about-containers/docker.png b/043_docker/01_about-containers/docker.png new file mode 100644 index 00000000..32e2d19b Binary files /dev/null and b/043_docker/01_about-containers/docker.png differ diff --git a/043_docker/01_about-containers/vm-containers.png b/043_docker/01_about-containers/vm-containers.png new file mode 100644 index 00000000..3775f40b Binary files /dev/null and b/043_docker/01_about-containers/vm-containers.png differ diff --git a/043_docker/01_about-containers/vm.png b/043_docker/01_about-containers/vm.png new file mode 100644 index 00000000..07a13ed6 Binary files /dev/null and b/043_docker/01_about-containers/vm.png differ diff --git a/043_docker/02_install/README.md b/043_docker/02_install/README.md new file mode 100644 index 00000000..7f5084f9 --- /dev/null +++ b/043_docker/02_install/README.md @@ -0,0 +1,49 @@ +# Overview + +This is what we will do: + +1. install Docker +1. run a software image in a container +1. locate an interesting image on Docker Hub +1. run the image on your own machine +1. modify an image to create your own and run it +1. create a Docker Hub account and repository +1. push your image to Docker Hub for others to share + +# Install + +[Install docker](https://docs.docker.com/) + +Choose **Docker engine / install** + +# Verify installation + +Check the docker version +``` +docker version +``` + +Run a sample "hello world" application +``` +docker run hello-world +``` + +# Images, Repository, Containers + +You use an **image** to make a **container**. + +You can make an unlimited number of **containers** from one **image**. + +An **image** is stored in a docker image **repository**. + +**Docker hub** is one docker image repository you can use. + +See all containers (processes) on your machine +``` +docker ps -a +``` + +See all running containers on your machine +``` +docker ps +``` \ No newline at end of file diff --git a/043_docker/03_run-images/README.md b/043_docker/03_run-images/README.md new file mode 100644 index 00000000..649c5eab --- /dev/null +++ b/043_docker/03_run-images/README.md @@ -0,0 +1,49 @@ +# Preview + +We will search docker hub for an image. We will then run that image. + +When you run an image, that image is copied to your local machine. + +When you run an image in a container, Docker downloads the image to your computer. This local copy of the image saves you time. Docker only downloads the image again if the image’s source changes on the hub. You can, of course, delete the image yourself. You’ll learn more about that later. + +# Locate whalesay + +Locate the **docker/whalesay** image on [Docker Hub](https://hub.docker.com/) + +You can also do this to search docker hub: + +``` +docker search +``` + +Caveat: This is code. When you grab someone else's code to use with your code, make sure you know what's in it. + +# Run the program + +``` +docker run docker/whalesay cowsay boo +``` + +# See the images on your machine + +``` +docker images +``` + +# See all containers (processes) on your machine + +``` +docker ps -a +``` + +``` +docker ps +``` + +# Reflection + +You searched for an image on Docker Hub. + +You used your command line to run an image. Effectively you ran a piece of Linux software on whatever machine you're using (Windows, Mac, Linux). + +You learned that running an image copies it on your computer. \ No newline at end of file diff --git a/043_docker/04_build-image/README.md b/043_docker/04_build-image/README.md new file mode 100644 index 00000000..903f34de --- /dev/null +++ b/043_docker/04_build-image/README.md @@ -0,0 +1,307 @@ +# Main points + +## Dockerfile --> Docker image --> Docker containers + +A Dockerfile builds a docker image. From a docker image, you can run an unlimited number of containers. + +## Your Dockerfile must be named Dockerfile + +## Include stuff in your image + +Everything in the folder with your Dockerfile, and all subsequent folders down the directory structure, are included in your image. + +## Dockerfile always starts with "FROM" + +Specify some image unless you're creating from scratch. + +You can also have a comment on the first line. Dockerfile comments are ```#``` hash symbols + +## + +# Build an image + +1. Create a Dockerfile +1. Build an image from the Dockerfile + +# Create Dockerfile + +## Create a directory + +``` +mkdir mydockerbuild +``` + +## Enter directory + +``` +cd mydockerbuild +``` + +## Create a docker build file + +``` +nano Dockerfile +``` + +## Add these lines to your build file + +``` +FROM docker/whalesay:latest +RUN apt-get -y update && apt-get install -y fortunes +CMD /usr/games/fortune -a | cowsay +``` + +### FROM +The FROM keyword tells Docker which image your image is based on. + +### RUN +The RUN statement will install the fortunes program into the image. + +The whalesay image is based on Ubuntu, which uses apt-get to install packages. + +These two commands refresh the list of packages available to the image and install the fortunes program into it. + +The fortunes program prints out wise sayings for our whale to say. + +### CMD +The CMD statement tells the image the final command to run after its environment is set up. + +This command runs fortune -a and pipes its output to the cowsay command. + + +# Build an image from the Dockerfile + +## Docker build +Build the image using the docker build command. + +The -t parameter gives your image a tag, so you can run it more easily later. + +Don’t forget the . command, which tells the docker build command to look in the current directory for a file called Dockerfile. + +``` +docker build -t docker-whale . +``` + +The above command reads the Dockerfile in the current directory and processes its instructions one by one to build an image called **docker-whale** on your local machine. + +# Run your new docker-whale + +See what images you have on your machine: + +``` +docker images +``` + +Run your image + +``` +docker run docker-whale +``` + +Run it again, and again, and again to see different output. + +# Notes from "Docker RUN vs CMD vs ENTRYPOINT" +[Yury Pitsishin - 02 APRIL 2016](http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/) + + +Some Docker instructions look similar and cause confusion among developers who just started using Docker or do it irregularly. In this post I will explain the difference between CMD, RUN, and ENTRYPOINT on examples. + +## RUN +executes command(s) in a new layer and creates a new image. E.g., it is often used for installing software packages. + +## CMD +sets default command and/or parameters, which can be overwritten from command line when docker container runs. + +## ENTRYPOINT +configures a container that will run as an executable. + +If it doesn't make much sense or you after details, then read on. + +# Docker images and layers + +When Docker runs a container, it runs an image inside it. This image is usually built by executing Docker instructions, which add layers on top of existing image or OS distribution. OS distribution is the initial image and every added layer creates a new image. + +# Shell and Exec forms + +All three instructions (RUN, CMD and ENTRYPOINT) can be specified in shell form or exec form. Let's get familiar with these forms first, because the forms usually cause more confusion than instructions themselves. + +## Shell form +``` ``` + +Examples: + +``` +RUN apt-get install python3 +CMD echo "Hello world" +ENTRYPOINT echo "Hello world" +``` + +When instruction is executed in shell form it calls /bin/sh -c `````` under the hood and normal shell processing happens. For example, the following snippet in Dockerfile + +``` +ENV name John Dow +ENTRYPOINT echo "Hello, $name" +``` + +```docker run -it ``` + +will produce + +``` +Hello, John Dow +``` + +Note that variable name is replaced with its value. + +## Exec form + +This is the preferred form for CMD and ENTRYPOINT instructions. + +``` ["executable", "param1", "param2", ...]``` + +Examples: + +``` +RUN ["apt-get", "install", "python3"] +CMD ["/bin/echo", "Hello world"] +ENTRYPOINT ["/bin/echo", "Hello world"] +``` + +When instruction is executed in exec form it calls executable directly, and **shell processing does not happen.** For example, the following snippet in Dockerfile + +``` +ENV name John Dow +ENTRYPOINT ["/bin/echo", "Hello, $name"] +``` + +```docker run -it ``` + +will produce output + +``` +Hello, $name +``` + +Note that variable name is not substituted. + +## How to run bash? + +If you need to run bash (or any other interpreter but sh), use exec form with /bin/bash as executable. **In this case, normal shell processing will take place.** For example, the following snippet in Dockerfile + +``` +ENV name John Dow +ENTRYPOINT ["/bin/bash", "-c", "echo Hello, $name"] +``` + +``` +docker run -it +``` + +will produce output + +``` +Hello, John Dow +``` + +# RUN + +RUN allows you to install your application and packages. It executes any commands on top of the current image and creates a new layer by committing the results. Often you will find multiple RUN instructions in a Dockerfile. + +RUN has two forms: + +``` +RUN (shell form) +RUN ["executable", "param1", "param2"] (exec form) +``` + +(The forms are described in detail in Shell and Exec forms section above.) + +A good illustration of RUN instruction would be to install multiple version control systems packages: + +``` +RUN apt-get update && apt-get install -y \ + bzr \ + cvs \ + git \ + mercurial \ + subversion +``` + +**Note that apt-get update and apt-get install are executed in a single RUN instruction. This is done to make sure that the latest packages will be installed. If apt-get install were in a separate RUN instruction, then it would reuse a layer added by apt-get update, which could had been created a long time ago.** + + +# CMD +CMD instruction allows you to **set a default command, which will be executed only when you run container without specifying a command. If Docker container runs with a command, the default command will be ignored. If Dockerfile has more than one CMD instruction, all but last CMD instructions are ignored.** + +CMD has three forms: + +``` +CMD ["executable","param1","param2"] (exec form, preferred) +CMD ["param1","param2"] (sets additional default parameters for ENTRYPOINT in exec form) +CMD command param1 param2 (shell form) +``` + +Again, the first and third forms were explained in Shell and Exec forms section. The second one is used together with ENTRYPOINT instruction in exec form. It sets default parameters that will be added after ENTRYPOINT parameters if container runs without command line arguments. See ENTRYPOINT for example. + +Let's have a look how CMD instruction works. The following snippet in Dockerfile + +``` +CMD echo "Hello world" +``` + +when container runs as ```docker run -it ``` will produce output + +``` +Hello world +``` + +but when container runs with a command, e.g., ```docker run -it /bin/bash```, CMD is ignored and bash interpreter runs instead: + +``` +root@7de4bed89922:/# +``` + +# ENTRYPOINT + +ENTRYPOINT instruction allows you to **configure a container that will run as an executable.** It looks similar to CMD, because it also allows you to specify a command with parameters. The difference is **ENTRYPOINT command and parameters are not ignored when Docker container runs with command line parameters.** (There is a way to ignore ENTTRYPOINT, but it is unlikely that you will do it.) + +ENTRYPOINT has two forms: + +``` +ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred) +ENTRYPOINT command param1 param2 (shell form) +``` + +Be very careful when choosing ENTRYPOINT form, because forms behaviour differs significantly. + +## Exec form + +Exec form of ENTRYPOINT allows you to set commands and parameters and then use either form of CMD to set additional parameters that are more likely to be changed. ENTRYPOINT arguments are always used, while CMD ones can be overwritten by command line arguments provided when Docker container runs. For example, the following snippet in Dockerfile + +``` +ENTRYPOINT ["/bin/echo", "Hello"] +CMD ["world"] +``` + +when container runs as ```docker run -it ``` will produce output + +``` +Hello world +``` + +but when container runs as ```docker run -it John``` will result in + +``` +Hello John +``` + +## Shell form +Shell form of ENTRYPOINT ignores any CMD or docker run command line arguments. + +# The bottom line + +Use RUN instructions to build your image by adding layers on top of initial image. + +Prefer ENTRYPOINT to CMD when building executable Docker image and you need a command always to be executed. Additionally use CMD if you need to provide extra default arguments that could be overwritten from command line when docker container runs. + +Choose CMD if you need to provide a default command and/or arguments that can be overwritten from command line when docker container runs. \ No newline at end of file diff --git a/043_docker/04_build-image/anything/Dockerfile b/043_docker/04_build-image/anything/Dockerfile new file mode 100644 index 00000000..980902a6 --- /dev/null +++ b/043_docker/04_build-image/anything/Dockerfile @@ -0,0 +1,4 @@ +# Changes whalesay to speak a fortune +FROM docker/whalesay:latest +RUN apt-get -y update && apt-get install -y fortunes +CMD /usr/games/fortune -a | cowsay \ No newline at end of file diff --git a/043_docker/05_curl/README.md b/043_docker/05_curl/README.md new file mode 100644 index 00000000..f6fde8bc --- /dev/null +++ b/043_docker/05_curl/README.md @@ -0,0 +1,78 @@ +# Build an image + +1. Create a Dockerfile +1. Build an image from the Dockerfile + +# Create Dockerfile + +## Create a directory + +``` +mkdir mydockerbuild2 +``` + +## Enter directory + +``` +cd mydockerbuild2 +``` + +## Create a docker build file + +``` +nano Dockerfile +``` + +## Add these lines to your build file + +``` +# Creates an ubuntu image with curl installed +FROM ubuntu:latest +RUN apt-get -y update && apt-get install -y curl +``` + +# Build an image from the Dockerfile + +## Docker build +Build the image using the docker build command. + +The -t parameter gives your image a tag, so you can run it more easily later. + +Don’t forget the ```.``` command, which tells the docker build command to look in the current directory for a file called Dockerfile. + +``` +docker build -t . +``` + +The above command reads the Dockerfile in the current directory and processes its instructions one by one to build an image called on your local machine. + +# Run your new image + +See what images you have on your machine: + +``` +docker images +``` + +## Run your image + +### Mac / Linux / maybe Windows +``` +MAC / LINUX: docker run -it /bin/bash +``` + +### Windows: if you get this error ```the input device is not a TTY. If you are using mintty, try prefixing the command with "winpty" ``` use the below code + +``` +WINDOWS: winpty docker run -it bash +``` + +## run a curl command + +``` +curl --head www.google.com +``` + +# Exit + +Exit your image by typing ```exit``` diff --git a/043_docker/05_curl/cowboy/Dockerfile b/043_docker/05_curl/cowboy/Dockerfile new file mode 100644 index 00000000..068f6088 --- /dev/null +++ b/043_docker/05_curl/cowboy/Dockerfile @@ -0,0 +1,3 @@ +# This docker file builds an image that runs curl +FROM ubuntu:latest +RUN apt-get -y update && apt-get install -y curl diff --git a/043_docker/06_hello-go/.dockerignore b/043_docker/06_hello-go/.dockerignore new file mode 100644 index 00000000..dd449725 --- /dev/null +++ b/043_docker/06_hello-go/.dockerignore @@ -0,0 +1 @@ +*.md diff --git a/043_docker/06_hello-go/Dockerfile b/043_docker/06_hello-go/Dockerfile new file mode 100644 index 00000000..5858f358 --- /dev/null +++ b/043_docker/06_hello-go/Dockerfile @@ -0,0 +1,4 @@ +# A hello world example with Go +FROM golang:1.8-onbuild +MAINTAINER tuddleymc@gmail.com + diff --git a/043_docker/06_hello-go/README.md b/043_docker/06_hello-go/README.md new file mode 100644 index 00000000..3a260447 --- /dev/null +++ b/043_docker/06_hello-go/README.md @@ -0,0 +1,82 @@ +# Create Go app + +Create a directory + +Create main.go + +Create code for a "hello world" web app + +# Create .dockerignore file + +If you want to ignore any files or directories in your build, add a .dockerignore file + +# Create Dockerfile + +The Dockerfile must be named Dockerfile. + +The Dockerfile will include EVERYTHING in the current directory, and descendent directories, in the image which is built (unless told to ignore something by the .dockerignore file) + +The Dockerfile may start with a comment + +``` +# Yo, this is my Dockerfile, Yo +``` + +The Dockerfile must have FROM as the first instruction + +The FROM says what image your are building this image from. + +In most cases, you will start with an image to build your image. + +You then later new images on top of your starting FROM image, and that all finally becomes your finished image. + +Images are made out of images layered on top of images. + +You can add in a MAINTAINER instruction if you'd like and say who built this image + +We are going to build our image FROM a golang image so ... + +Go to docker hub + +Search for golang + +Find the golang image you want + +We will use: golang:1.8-onbuild + +So our Dockerfile will be + +``` +# Some comment +FROM golang:1.8-onbuild +MAINTAINER youremail@gmail.com +``` + +# Now build our image + +``` +docker build -t my-app . +``` + +-t means "tag" or "give it a name" + +The name we gave it is "my-app" + +The dot "." means the code for this image is in this current directory + +Make sure you are in the correct directory when you run this + +# Now create a container from your image and run it + +``` + docker run -d -p 80:80 my-app +``` + +-d means run this detached, as a daemon, eg, not dependent on the terminal session + +-p means map ports; mapping ```:``` + + +# Verify it's running + +Go to your browser and see if it's running \ No newline at end of file diff --git a/043_docker/06_hello-go/main.go b/043_docker/06_hello-go/main.go new file mode 100644 index 00000000..b8e2189d --- /dev/null +++ b/043_docker/06_hello-go/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "io" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":80", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "hello from a docker container") +} diff --git a/043_docker/07_push-pull/README.md b/043_docker/07_push-pull/README.md new file mode 100644 index 00000000..9123e65f --- /dev/null +++ b/043_docker/07_push-pull/README.md @@ -0,0 +1,86 @@ +# See what images you currently have + +``` +docker images +``` + +# Add a docker tag + +``` +docker tag /: +``` +![Docker tag](tag.png) + +# Give terminal your docker hub credentials + +Create a docker hub account, if necessary + +``` +docker login +``` + +# Push your image + +``` +docker push / +``` + +# Look at your docker hub account + +Your image should be there. + +# See images on your machine + +``` +docker images +``` + +# Remove all "docker-whale" images + +``` +docker rmi -f +``` + +-f is "with force" + +# See docker help + +``` +docker --help +docker --help +docker rmi --help +``` + +# Pull from your repo + +## run it this way if it's our go web app from previous step +``` +docker run -d -p 80:80 / +``` + +## for some other image you might use this +``` +docker run / +``` + +# Stop your container from running +``` +docker ps +docker stop +docker ps +docker images +``` + +# Look at what you've done + +1. gained an understanding of containers & Docker +1. gained an understanding of Docker, images, containers, image repositories +1. installed Docker +1. run a software image in a container +1. located an interesting image on Docker Hub +1. run the image on your own machine +1. modified an image to create your own and run it +1. built a docker image with a Go web app +1. run a docker container with a Go web app +1. create a Docker Hub account and repository +1. pushed your image to Docker Hub for others to share diff --git a/043_docker/07_push-pull/tag.png b/043_docker/07_push-pull/tag.png new file mode 100644 index 00000000..6a5b17bc Binary files /dev/null and b/043_docker/07_push-pull/tag.png differ diff --git a/043_docker/08_aws-docker/README.md b/043_docker/08_aws-docker/README.md new file mode 100644 index 00000000..061714c2 --- /dev/null +++ b/043_docker/08_aws-docker/README.md @@ -0,0 +1,64 @@ +# Create a new EC2 instance + +Use the Amazon Linux AMI + +[EC2 Docker Instructions](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/docker-basics.html) + +change the permissions on your pem if you created a new one +``` +sudo chmod 400 your.pem +``` + +# Connect to your machine + +ssh into your instance +``` +ssh -i /path/to/[your].pem ec2-user@[public-DNS] +``` + +# Update the installed packages and package cache on your instance. +``` +sudo yum update -y +``` + +# Install Docker. +``` +sudo yum install -y docker +``` + +# Start the Docker service. +``` +sudo service docker start +``` + +# Add the ec2-user to the docker group so you can execute Docker commands without using sudo. +``` +sudo usermod -a -G docker ec2-user +``` + +# Log out and log back in again to pick up the new docker group permissions. + +# Verify that the ec2-user can run Docker commands without sudo. +``` +docker info +``` + +In some cases, you may need to reboot your instance to provide permissions for the ec2-user to access the Docker daemon. Try rebooting your instance if you see the following error: +``` +Cannot connect to the Docker daemon. Is the docker daemon running on this host? +``` + +# Run the Go app from the previous example +``` +docker run -d -p 80:80 toddmcleod/golang-hello-world +``` + +# Check that it's running +``` +docker ps +``` + +# View the web app from a browser +``` +Use the IP address of your instance +``` \ No newline at end of file diff --git a/043_docker/README.md b/043_docker/README.md new file mode 100644 index 00000000..afaade16 --- /dev/null +++ b/043_docker/README.md @@ -0,0 +1,105 @@ +# These are the docker commands we used + +## 02_install + +``` +docker version +docker run hello-world +docker ps -a +docker ps +``` + +## 03_run-images + +``` +docker search +docker run docker/whalesay cowsay boo +docker images +docker ps -a +docker ps +``` + +## 04_build-image + +``` +mkdir mydockerbuild +cd mydockerbuild +nano Dockerfile + +FROM docker/whalesay:latest +RUN apt-get -y update && apt-get install -y fortunes +CMD /usr/games/fortune -a | cowsay + +docker build -t docker-whale . +docker images +docker run docker-whale +``` + +## 05_curl + +``` +mkdir mydockerbuild2 +cd mydockerbuild2 +nano Dockerfile + +# Creates an ubuntu image with curl installed +FROM ubuntu:latest +RUN apt-get -y update && apt-get install -y curl + +docker build -t . +docker images + +MAC / LINUX: docker run -it /bin/bash +WINDOWS: winpty docker run -it bash + +curl --head www.google.com +exit +``` + +## 06_hello-go + +``` +# Some comment +FROM golang:1.8-onbuild +MAINTAINER youremail@gmail.com + + +docker build -t my-app . +docker run -d -p 80:80 my-app +``` + +## 07_push-pull + +``` +docker images +docker tag /: +docker login +docker push / +docker images +docker rmi -f +docker --help +docker --help +docker rmi --help +docker search +## run it this way if it's our go web app from previous step +docker run -d -p 80:80 / +docker ps +docker stop +docker ps +docker images +``` + +## 08_aws-docker + +``` +sudo chmod 400 your.pem +ssh -i /path/to/[your].pem ec2-user@[public-DNS] +sudo yum update -y +sudo yum install -y docker +sudo service docker start +sudo usermod -a -G docker ec2-user +docker info +docker run -d -p 80:80 toddmcleod/golang-hello-world +docker ps +Use the IP address of your instance +``` \ No newline at end of file diff --git a/044_postgres/01_install/README.md b/044_postgres/01_install/README.md new file mode 100644 index 00000000..e655b601 --- /dev/null +++ b/044_postgres/01_install/README.md @@ -0,0 +1,31 @@ +# postgres + +[Nice tutorial](https://www.tutorialspoint.com/postgresql/postgresql_create_database.htm) +[documenation reference](https://www.postgresql.org/docs/9.4/static/app-psql.html) + +## install +[postgresql website](https://www.postgresql.org/download/) + +### mac +Postgres.app is fine. + +## log in + +``` +psql +``` + +or +``` +/Applications/Postgres.app/Contents/Versions/9.6/bin/psql -p5432 +``` + +## list databases +``` +\l +``` + +## log out +``` +\q +``` \ No newline at end of file diff --git a/044_postgres/02_create-database/README.md b/044_postgres/02_create-database/README.md new file mode 100644 index 00000000..800a745e --- /dev/null +++ b/044_postgres/02_create-database/README.md @@ -0,0 +1,34 @@ +# create database +``` +CREATE DATABASE employees; +``` + +## list databases +``` +\l +``` + +## connect to a database +``` +\c +``` + +## switch back to postgres database +``` +\c postgres +``` + +## see current user +``` +SELECT current_user; +``` + +## see current database +``` +SELECT current_database(); +``` + +## drop (remove, delete) database +``` +DROP DATABASE ; +``` \ No newline at end of file diff --git a/044_postgres/03_create-table/README.md b/044_postgres/03_create-table/README.md new file mode 100644 index 00000000..d996f413 --- /dev/null +++ b/044_postgres/03_create-table/README.md @@ -0,0 +1,39 @@ +# create table +``` +CREATE TABLE employees ( + ID INT PRIMARY KEY NOT NULL, + NAME TEXT NOT NULL, + RANK INT NOT NULL, + ADDRESS CHAR(50), + SALARY REAL DEFAULT 25500.00, + BDAY DATE DEFAULT '1900-01-01' +); +``` + +## show tables in a database (list down) +``` +\d +``` + +## show details of a table +``` +\d +``` + +## drop a table +``` +DROP TABLE
; +``` + +## schema +Schemas allow us to organize our database and database code. + +A schema is like a folder. + +Into this folder, you can put tables, views, indexes, sequences, data types, operators, and functions. + +Unlike folders, however, schemas can't be nested. + +Schemas provide namespacing. + +[Read more about schemas](https://www.tutorialspoint.com/postgresql/postgresql_schema.htm) \ No newline at end of file diff --git a/044_postgres/04_insert-record/README.md b/044_postgres/04_insert-record/README.md new file mode 100644 index 00000000..21b9d24c --- /dev/null +++ b/044_postgres/04_insert-record/README.md @@ -0,0 +1,25 @@ +# insert a record +``` +INSERT INTO employees (ID,NAME,RANK,ADDRESS,SALARY,BDAY) VALUES (1, 'Mark', 7, '1212 E. Lane, Someville, AK, 57483', 43000.00 ,'1992-01-13'); +``` + +## list records in a table +``` +SELECT * FROM
; +``` + +## insert a record - variations +omitted values will have the [default value](https://www.postgresql.org/docs/9.3/static/ddl-default.html): +``` +INSERT INTO employees (ID,NAME,RANK,ADDRESS,BDAY) VALUES (2, 'Marian', 8, '7214 Wonderlust Ave, Lost Lake, KS, 22897', '1989-11-21'); +``` + +we can use DEFAULT rather leaving a field blank or specifying a value: +``` +INSERT INTO employees (ID,NAME,RANK,ADDRESS,SALARY,BDAY) VALUES (3, 'Maxwell', 6, '7215 Jasmine Place, Corinda, CA 98743', 87500.00, DEFAULT); +``` + +we can insert multiple rows: +``` +INSERT INTO employees (ID,NAME,RANK,ADDRESS,SALARY,BDAY) VALUES (4, 'Jasmine', 5, '983 Star Ave., Brooklyn, NY, 00912 ', 55700.00, '1997-12-13' ), (5, 'Orranda', 9, '745 Hammer Lane, Hammerfield, Texas, 75839', 65350.00 , '1992-12-13'); +``` \ No newline at end of file diff --git a/044_postgres/05_auto-increment/README.md b/044_postgres/05_auto-increment/README.md new file mode 100644 index 00000000..45792dbd --- /dev/null +++ b/044_postgres/05_auto-increment/README.md @@ -0,0 +1,25 @@ +# auto increment key field +Instead of creating a unique ID number ourselves, we can have postgres automatically increment this ID field. + + To do this we use the data types smallserial, serial or bigserial (not true types but for convenience). + + This is like AUTO_INCREMENT in other databases. + +``` +CREATE TABLE phonenumbers( + ID SERIAL PRIMARY KEY, + PHONE TEXT NOT NULL +); +``` + +``` +INSERT INTO phonenumbers (PHONE) VALUES ( '234-432-5234'), ('543-534-6543'), ('312-123-5432'); +``` + +``` +\d phonenumbers +``` + +``` +SELECT * FROM phonenumbers; +``` \ No newline at end of file diff --git a/044_postgres/06_hands-on/README.md b/044_postgres/06_hands-on/README.md new file mode 100644 index 00000000..7483c534 --- /dev/null +++ b/044_postgres/06_hands-on/README.md @@ -0,0 +1,15 @@ +# hands-on exercise +1. delete all of your current tables. +1. READ ALL OF THIS: create a new table called employees with these fields ```id, name, score, salary``` AND give ```score``` a default value of 10 AND have the ```id``` field automatically increment. +1. add these records and then show all of the records +``` + id | name | score | salary +----+--------+-------+-------- + 1 | Daniel | 23 | 55000 + 2 | Arin | 25 | 65000 + 3 | Juan | 24 | 72000 + 4 | Shen | 26 | 64000 + 5 | Myke | 27 | 58000 + 6 | McLeod | 26 | 72000 + 7 | James | 32 | 35000 +``` \ No newline at end of file diff --git a/044_postgres/07_solution/README.md b/044_postgres/07_solution/README.md new file mode 100644 index 00000000..963dd62c --- /dev/null +++ b/044_postgres/07_solution/README.md @@ -0,0 +1,21 @@ +# solution +``` +DROP TABLE employees, phonenumbers; +``` + +``` +CREATE TABLE employees ( + ID SERIAL PRIMARY KEY NOT NULL, + NAME TEXT NOT NULL, + SCORE INT DEFAULT 10 NOT NULL, + SALARY REAL +); +``` + +``` +INSERT INTO employees (NAME,SCORE,SALARY) VALUES ('Daniel', 23, 55000.00), ('Arin', 25, 65000.00), ('Juan', 24, 72000.00), ('Shen', 26, 64000.00), ('Myke', 27, 58000.00), ('McLeod', 26, 72000.00), ('James', 32, 35000.00); +``` + +``` +SELECT * FROM employees; +``` \ No newline at end of file diff --git a/044_postgres/08_relational-dbs/README.md b/044_postgres/08_relational-dbs/README.md new file mode 100644 index 00000000..86187d6b --- /dev/null +++ b/044_postgres/08_relational-dbs/README.md @@ -0,0 +1,15 @@ +# relational databases + +![Understanding relational databases](db.png) + +``` +CREATE TABLE phonenumbers ( + ID SERIAL PRIMARY KEY NOT NULL, + PHONE CHAR(50) NOT NULL, + EMP_ID INT references employees(ID) +); +``` + +``` +INSERT INTO phonenumbers (PHONE,EMP_ID) VALUES ('555-777-8888', 4), ('555-222-3345', 4), ('777-543-3451', 1), ('544-756-2334', 2); +``` \ No newline at end of file diff --git a/044_postgres/08_relational-dbs/db.png b/044_postgres/08_relational-dbs/db.png new file mode 100644 index 00000000..6af1da69 Binary files /dev/null and b/044_postgres/08_relational-dbs/db.png differ diff --git a/044_postgres/09_queries_cross-join/README.md b/044_postgres/09_queries_cross-join/README.md new file mode 100644 index 00000000..91768cf3 --- /dev/null +++ b/044_postgres/09_queries_cross-join/README.md @@ -0,0 +1,46 @@ +# queries + +## querying from more than one table + +This query is an **inner join**. +``` +SELECT employees.NAME, phonenumbers.PHONE FROM employees INNER JOIN phonenumbers ON employees.ID = phonenumbers.EMP_ID; +``` + +# join queries + +Join queries allow us to select records from two or more tables. + +A join query combines columns from one or more tables - it joins a bunch of columns from different tables together. + +There are five types of joins in postgres: + +## cross join +A cross join returns the **Cartesian product** of rows from tables in the join. In other words, it will produce rows which combine each row from the first table with each row from the second table. + +``` +CREATE TABLE person ( + ID SERIAL PRIMARY KEY NOT NULL, + NAME CHAR(50) NOT NULL +); +``` + +``` +INSERT INTO person (NAME) VALUES ('Shen'), ('Daniel'), ('Juan'), ('Arin'), ('McLeod'); +``` + +``` +CREATE TABLE sport ( + ID SERIAL PRIMARY KEY NOT NULL, + NAME CHAR(50) NOT NULL, + P_ID INT references person(ID) +); +``` + +``` +INSERT INTO sport (NAME, P_ID) VALUES ('Surf',1),('Soccer',3),('Ski',3),('Sail',3),('Bike',3); +``` + +``` +SELECT person.NAME, sport.NAME FROM person CROSS JOIN sport; +``` \ No newline at end of file diff --git a/044_postgres/10_queries_inner-join/01_video-rental/README.md b/044_postgres/10_queries_inner-join/01_video-rental/README.md new file mode 100644 index 00000000..306b8ff5 --- /dev/null +++ b/044_postgres/10_queries_inner-join/01_video-rental/README.md @@ -0,0 +1,73 @@ +# create a database +``` +create database blockbuster; +``` + +# switch into the database +``` +\c blockbuster +``` + +# create three tables + +``` +create table customers (cid serial primary key not null, cfirst char(50) not null); +``` + +``` +create table movies (mid serial primary key not null, mmovie char(50) not null); +``` + +``` +create table rentals (rid serial primary key not null, cid int references customers(cid), mid int references movies(mid)); +``` + +# populate tables +``` +insert into customers (cfirst) values ('James Bond'), ('Miss Moneypenny'), ('Q'), ('M'), ('Fleming'); +``` + +``` +insert into movies (mmovie) values ('Jaws'), ('Alien'), ('Never Say Never'), ('Skyfall'), ('Highlander'); +``` + +``` +insert into rentals (cid, mid) values (1,3), (2,5), (4,1), (3,2), (5,4), (3,2), (1,3), (2,4), (5,4), (2,1), (2,3), (4,5), (5,2), (2,1), (3,2), (3,3), (2,3), (1,4), (3,2), (2,3), (3,3), (2,4), (2,3), (1,2), (3,5), (3,4), (1,5); +``` + +# inner join query +``` +select customers.cfirst, movies.mmovie from customers inner join rentals on customers.cid = rentals.cid inner join movies on rentals.mid = movies.mid; +``` + + +# How this works + +``` +select * from +tableA inner join tableB + on tableA.common = tableB.common +inner join TableC + on tableB.common = TableC.common +``` + +## you might also see alias use + +``` +select * from +tableA a inner join tableB b + on a.common = b.common +inner join TableC c + on b.common = c.common +``` + + + + + + + + + + + diff --git a/044_postgres/10_queries_inner-join/README.md b/044_postgres/10_queries_inner-join/README.md new file mode 100644 index 00000000..09b56851 --- /dev/null +++ b/044_postgres/10_queries_inner-join/README.md @@ -0,0 +1,64 @@ +# general syntax + +## select +``` +SELECT FROM
; +``` + +``` +SELECT * FROM employees; +``` + +``` +SELECT name, score FROM employees; +``` + +## cross join +``` +SELECT FROM CROSS JOIN ; +``` + +``` +SELECT person.NAME, sport.NAME FROM person CROSS JOIN sport; +``` + +## inner join +``` +SELECT FROM
INNER JOIN
+ON = ; +``` + +``` +SELECT person.NAME, sport.NAME FROM person INNER JOIN sport +ON person.ID = sport.P_ID; +``` + +# inner join + +An inner join allows us to select records from two tables. + +We used an inner join above when we asked for the phone numbers associated with an employee: + +``` +SELECT employees.NAME, phonenumbers.PHONE FROM employees INNER JOIN phonenumbers ON employees.ID = phonenumbers.EMP_ID; +``` + +We can use one with our ```people``` and ```sports``` table too, if we wanted, as these tables are connected (remember ```P_ID INT references person(ID)```). + +``` +SELECT person.NAME, sport.NAME FROM person INNER JOIN sport ON person.ID = sport.P_ID; +``` + +Here is how wikipedia explains an inner join: + +An inner join requires each row in the two joined tables to have matching rows, and is a commonly used join operation in applications but should not be assumed to be the best choice in all situations. + +Inner join creates a new result table by combining column values of two tables (A and B) based upon the join-predicate. + +The query compares each row of A with each row of B to find all pairs of rows which satisfy the join-predicate. + +When the join-predicate is satisfied by matching non-NULL values, column values for each matched pair of rows of A and B are combined into a result row. + +The result of the join can be defined as the outcome of first taking the Cartesian product (or Cross join) of all rows in the tables (combining every row in table A with every row in table B) and then returning all rows which satisfy the join predicate. Actual SQL implementations normally use other approaches, such as hash joins or sort-merge joins, since computing the Cartesian product is slower and would often require a prohibitively large amount of memory to store. + +SQL specifies two different syntactical ways to express joins: the "explicit join notation" and the "implicit join notation". The "implicit join notation" is no longer considered a best practice, although database systems still support it. The **"explicit join notation"** uses the JOIN keyword, optionally preceded by the INNER keyword, to specify the table to join, and the ON keyword to specify the predicates for the join. \ No newline at end of file diff --git a/044_postgres/11_queries_outer-join/README.md b/044_postgres/11_queries_outer-join/README.md new file mode 100644 index 00000000..60bc475a --- /dev/null +++ b/044_postgres/11_queries_outer-join/README.md @@ -0,0 +1,30 @@ +# outer join + +## left outer join + A left outer join gives you everything in one table, and also the matching records in another table. + + For tables A and B a left outer join would give you all rows of the "left" table (A), even if the join-condition does not find any matching row in the "right" table (B). + + This means that if the ON clause matches 0 (zero) rows in B (for a given row in A), the join will still return a row in the result (for that row)—but with NULL in each column from B. + + ``` + SELECT person.NAME, sport.NAME FROM person LEFT OUTER JOIN sport ON person.ID = sport.P_ID; + ``` + +## right outer join +A right outer join is like a left outer join, but for the table on the right. + +``` +INSERT INTO sport (NAME) VALUES ('Squirrel Suit Flying'); +``` + +``` + SELECT person.NAME, sport.NAME FROM person RIGHT OUTER JOIN sport ON person.ID = sport.P_ID; +``` + +## full outer join +A full outer join is like running both a left outer join and a right outer join at the same time. It gives you everything from all tables, and matches what matches. + +``` + SELECT person.NAME, sport.NAME FROM person FULL OUTER JOIN sport ON person.ID = sport.P_ID; +``` \ No newline at end of file diff --git a/044_postgres/12_clauses/README.md b/044_postgres/12_clauses/README.md new file mode 100644 index 00000000..a7d7634c --- /dev/null +++ b/044_postgres/12_clauses/README.md @@ -0,0 +1,50 @@ +## where +Adding **WHERE** to a SQL query allows you to filter results. +``` +SELECT * FROM employees WHERE salary > 60000; +``` + +## and +``` +SELECT * FROM employees WHERE salary > 60000 AND score = 26; +``` + +## in +``` +SELECT * FROM employees WHERE score IN (25,26); +``` + +## not +``` +SELECT * FROM employees WHERE score NOT IN (25,26); +``` + +## between +``` +SELECT * FROM employees WHERE score BETWEEN 23 AND 26; +``` + +## is not null +``` +SELECT * FROM employees WHERE score IS NOT NULL; +``` + +## like +``` +SELECT * FROM employees WHERE name LIKE '%an%'; +``` + +## or +``` +SELECT * FROM employees WHERE score <= 24 OR salary < 50000; +``` + +## limit +Limit the number of records returned +``` +SELECT * FROM employees LIMIT 4; +``` + +``` +SELECT * FROM employees ORDER BY id LIMIT 4; +``` \ No newline at end of file diff --git a/044_postgres/13_update/README.md b/044_postgres/13_update/README.md new file mode 100644 index 00000000..917b0259 --- /dev/null +++ b/044_postgres/13_update/README.md @@ -0,0 +1,21 @@ +# update + +syntax +``` +UPDATE table +SET col1 = val1, col2 = val2, ..., colN = valN +WHERE ; +``` + +``` +SELECT * FROM employees; +``` + +``` +UPDATE employees SET score = 99 WHERE ID = 3; +``` + +## order by +``` +SELECT * FROM employees ORDER BY id; +``` \ No newline at end of file diff --git a/044_postgres/14_delete/README.md b/044_postgres/14_delete/README.md new file mode 100644 index 00000000..01b99ba6 --- /dev/null +++ b/044_postgres/14_delete/README.md @@ -0,0 +1,20 @@ +# delete + +syntax +``` +DELETE FROM table +WHERE ; +``` + +``` +SELECT * FROM sport; +``` + +``` +DELETE FROM sport WHERE id = 6; +``` + +**WARNING: this deletes all records:** +``` +DELETE FROM sport; +``` \ No newline at end of file diff --git a/044_postgres/15_users/README.md b/044_postgres/15_users/README.md new file mode 100644 index 00000000..a944fbee --- /dev/null +++ b/044_postgres/15_users/README.md @@ -0,0 +1,41 @@ +# users & privileges + +## see current user +``` +SELECT current_user; +``` + +## details of users +``` +\du +``` + +## create user +``` +CREATE USER james WITH PASSWORD 'password'; +``` + +## grant privileges +privileges: SELECT, INSERT, UPDATE, DELETE, RULE, ALL +``` +GRANT ALL PRIVILEGES ON DATABASE company to james; +``` + +## revoke privileges +``` +REVOKE ALL PRIVILEGES ON DATABASE company from james; +``` + +## alter +``` +ALTER USER james WITH SUPERUSER; +``` + +``` +ALTER USER james WITH NOSUPERUSER; +``` + +## remove +``` +DROP USER james; +``` diff --git a/044_postgres/16_go-postgres/README.md b/044_postgres/16_go-postgres/README.md new file mode 100644 index 00000000..3a48734d --- /dev/null +++ b/044_postgres/16_go-postgres/README.md @@ -0,0 +1,22 @@ +# Go & postgres + +driver +``` +go get github.com/lib/pq +``` + +## create a db + +``` +CREATE DATABASE bookstore; +``` + +## create user +``` +CREATE USER bond WITH PASSWORD 'password'; +``` + +## grant privileges +``` +GRANT ALL PRIVILEGES ON DATABASE bookstore to bond; +``` diff --git a/044_postgres/16_go-postgres/main.go b/044_postgres/16_go-postgres/main.go new file mode 100644 index 00000000..79f9c7a2 --- /dev/null +++ b/044_postgres/16_go-postgres/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" +) + +func main() { + db, err := sql.Open("postgres", "postgres://bond:password@localhost/bookstore?sslmode=disable") + if err != nil { + panic(err) + } + defer db.Close() + + err = db.Ping() + if err != nil { + panic(err) + } + fmt.Println("You connected to your database.") +} diff --git a/044_postgres/17_select/README.md b/044_postgres/17_select/README.md new file mode 100644 index 00000000..5af6f981 --- /dev/null +++ b/044_postgres/17_select/README.md @@ -0,0 +1,130 @@ +# our pathway + +We will be following the example created in [this article by Alex Edwards](http://www.alexedwards.net/blog/practical-persistence-sql) and licensed under a [MIT license](https://opensource.org/licenses/MIT) + +In order to successfully pull records from a table in a database as our user ```bond```, we will need to [ALTER](https://www.postgresql.org/docs/9.6/static/sql-alteruser.html) bond to have a different role. + +# alter bond's role +``` +alter user bond with superuser; +``` + +# switch to your bookstore database +You should already have a ```bookstore``` database: + +list databases +``` +\l +``` + +switch into that database +``` +\c bookstore +``` + +directory of tables, if any +``` +\d +``` + +# create table +``` +CREATE TABLE books ( + isbn char(14) PRIMARY KEY NOT NULL, + title varchar(255) NOT NULL, + author varchar(255) NOT NULL, + price decimal(5,2) NOT NULL +); +``` + +directory of tables +``` +\d +``` + +details of table ```books``` +``` +\d books +``` + +# insert records +``` +INSERT INTO books (isbn, title, author, price) VALUES +('978-1503261969', 'Emma', 'Jayne Austen', 9.44), +('978-1505255607', 'The Time Machine', 'H. G. Wells', 5.99), +('978-1503379640', 'The Prince', 'Niccolò Machiavelli', 6.99); +``` + +view records +``` +SELECT * FROM books; +``` + +# main.go + +## importing the driver +make sure you import the driver +``` +_ "github.com/lib/pq" +``` +"We don't use anything in the pq package directly, which means that the Go compiler will raise an error if we try to import it normally. But **we need the pq package's init() function to run so that our driver can register itself with database/sql.** We get around this by aliasing the package name to the blank identifier. This means pq.init() still gets executed, but the alias is harmlessly discarded (and our code runs error-free). This approach is standard for most of Go's SQL drivers." - Alex Edwards + +## define a book type struct +``` +type Book struct { + isbn string + title string + author string + price float32 +} +``` +"Next we define a Book type. **The struct fields and their types must align to our books table.** For completeness I should point out that we've only been able to use the string and float32 types safely because we set NOT NULL constraints on the columns in our table. If the table contained nullable fields we would need to use the sql.NullString and sql.NullFloat64 types instead – see [this Gist](https://gist.github.com/alexedwards/dc3145c8e2e6d2fd6cd9) for a working example. Generally it's easiest to avoid nullable fields altogether if you can, which is what we've done here." - Alex Edwards + +## initialize a new sql.DB +``` +db, err := sql.Open("postgres", "postgres://bond:password@localhost/bookstore?sslmode=disable") + if err != nil { + panic(err) + } + defer db.Close() +``` +"In the main() function we initialise a new sql.DB by calling sql.Open(). We pass in the name of our driver (in this case "postgres") and the connection string (you'll need to check your driver documentation for the correct format). It's worth emphasizing that **sql.DB is not a database connection – it's an abstraction representing a pool of underlying connections.** You can change the maximum number of open and idle connections in the pool with the db.SetMaxOpenConns() and db.SetMaxIdleConns() methods respectively. A final thing to note is that **sql.DB is safe for concurrent access,** which is very convenient if you're using it in a web application (like we will shortly)." - Alex Edwards + +## ping the db +``` + if err = db.Ping(); err != nil { + panic(err) + } +``` +"Because sql.Open() doesn't actually check a connection, we also call DB.Ping() to make sure that everything works OK on startup." - Alex Edwards + +## query the db +``` +rows, err := db.Query("SELECT * FROM books") + if err != nil { + panic(err) + } + defer rows.Close() +``` +"We will fetch a resultset from the books table using the DB.Query() method and assign it to a rows variable. Then we defer rows.Close() to ensure the resultset is properly closed before the parent function returns. **Closing a resultset properly is really important. As long as a resultset is open it will keep the underlying database connection open – which in turn means the connection is not available to the pool.** So if something goes wrong and the resultset isn't closed it can rapidly lead to all the connections in your pool being used up. Another gotcha (which caught me out when I first began) is that the defer statement should come after you check for an error from DB.Query. Otherwise, if DB.Query() returns an error, you'll get a panic trying to close a nil resultset." - Alex Edwards + +## iterate through results +``` + for rows.Next() { + bk := Book{} + err := rows.Scan(&bk.isbn, &bk.title, &bk.author, &bk.price) // order matters + if err != nil { + panic(err) + } + bks = append(bks, bk) + } +``` +"We then use rows.Next() to iterate through the rows in the resultset. This preps the first (and then each subsequent) row to be acted on by the rows.Scan() method. Note that if iteration over all of the rows completes then the resultset automatically closes itself and frees-up the connection. We use the rows.Scan() method to copy the values from each field in the row to a new Book object that we created. We then check for any errors that occurred during Scan, and add the new Book to a slice of books." - Alex Edwards + +## make sure everything ran well +``` + if err = rows.Err(); err != nil { + panic(err) + } +``` +"When our rows.Next() loop has finished we call rows.Err(). This returns any error that was encountered during the interation. It's important to call this – don't just assume that we completed a successful iteration over the whole resultset." - Alex Edwards Err returns the error, if any, that was encountered during iteration. Err may be called after an explicit or implicit Close. \ No newline at end of file diff --git a/044_postgres/17_select/main.go b/044_postgres/17_select/main.go new file mode 100644 index 00000000..e9ca3f0e --- /dev/null +++ b/044_postgres/17_select/main.go @@ -0,0 +1,51 @@ +package main + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" +) + +type Book struct { + isbn string + title string + author string + price float32 +} + +func main() { + db, err := sql.Open("postgres", "postgres://bond:password@localhost/bookstore?sslmode=disable") + if err != nil { + panic(err) + } + defer db.Close() + + if err = db.Ping(); err != nil { + panic(err) + } + fmt.Println("You connected to your database.") + + rows, err := db.Query("SELECT * FROM books;") + if err != nil { + panic(err) + } + defer rows.Close() + + bks := make([]Book, 0) + for rows.Next() { + bk := Book{} + err := rows.Scan(&bk.isbn, &bk.title, &bk.author, &bk.price) // order matters + if err != nil { + panic(err) + } + bks = append(bks, bk) + } + if err = rows.Err(); err != nil { + panic(err) + } + + for _, bk := range bks { + // fmt.Println(bk.isbn, bk.title, bk.author, bk.price) + fmt.Printf("%s, %s, %s, $%.2f\n", bk.isbn, bk.title, bk.author, bk.price) + } +} diff --git a/044_postgres/18_routing/README.md b/044_postgres/18_routing/README.md new file mode 100644 index 00000000..9f65fa0e --- /dev/null +++ b/044_postgres/18_routing/README.md @@ -0,0 +1,72 @@ +# init + +Add a package level scope variable +``` +var db *sql.DB +``` + +# Initialize your database +Note: ```defer.db.Close()``` has been removed +``` +func init() { + var err error + db, err = sql.Open("postgres", "postgres://bond:password@localhost/bookstore?sslmode=disable") + if err != nil { + panic(err) + } + + if err = db.Ping(); err != nil { + panic(err) + } + fmt.Println("You connected to your database.") +} +``` + +# add routes & server +``` +func main() { + http.HandleFunc("/", index) + http.ListenAndServe(":8080", nil) +} +``` + +# add a index func +``` +func index(w http.ResponseWriter, r *http.Request){ + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + rows, err := db.Query("SELECT * FROM books") + if err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + defer rows.Close() + + bks := make([]Book, 0) + for rows.Next() { + bk := Book{} + err := rows.Scan(&bk.isbn, &bk.title, &bk.author, &bk.price) // order matters + if err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + bks = append(bks, bk) + } + if err = rows.Err(); err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + + for _, bk := range bks { + fmt.Fprintf(w, "%s, %s, %s, $%.2f\n", bk.isbn, bk.title, bk.author, bk.price) + } +} +``` + +# run the application and make a request +``` +curl -i localhost:8080/books +``` \ No newline at end of file diff --git a/044_postgres/18_routing/main.go b/044_postgres/18_routing/main.go new file mode 100644 index 00000000..e49c518a --- /dev/null +++ b/044_postgres/18_routing/main.go @@ -0,0 +1,68 @@ +package main + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" + "net/http" +) + +var db *sql.DB + +func init() { + var err error + db, err = sql.Open("postgres", "postgres://bond:password@localhost/bookstore?sslmode=disable") + if err != nil { + panic(err) + } + + if err = db.Ping(); err != nil { + panic(err) + } + fmt.Println("You connected to your database.") +} + +type Book struct { + isbn string + title string + author string + price float32 +} + +func main() { + http.HandleFunc("/books", booksIndex) + http.ListenAndServe(":8080", nil) +} + +func booksIndex(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + rows, err := db.Query("SELECT * FROM books") + if err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + defer rows.Close() + + bks := make([]Book, 0) + for rows.Next() { + bk := Book{} + err := rows.Scan(&bk.isbn, &bk.title, &bk.author, &bk.price) // order matters + if err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + bks = append(bks, bk) + } + if err = rows.Err(); err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + + for _, bk := range bks { + fmt.Fprintf(w, "%s, %s, %s, $%.2f\n", bk.isbn, bk.title, bk.author, bk.price) + } +} diff --git a/044_postgres/19_where-clause/README.md b/044_postgres/19_where-clause/README.md new file mode 100644 index 00000000..2b39f60d --- /dev/null +++ b/044_postgres/19_where-clause/README.md @@ -0,0 +1,22 @@ +# query a single book + +add these lines of code: + +## func main() +``` + http.HandleFunc("/books/show", booksShow) +``` + +## func bookShow added +Arguments to the SQL function are referenced in the function body using the syntax $n: $1 refers to the first argument, $2 to the second, and so on. If an argument is of a composite type, then the dot notation, e.g., $1.name, can be used to access attributes of the argument. The arguments can only be used as data values, not as identifiers.[source: postgres docs](https://www.postgresql.org/docs/9.1/static/xfunc-sql.html) + +"Behind the scenes, **db.QueryRow (and also db.Query() and db.Exec()) work by creating a new prepared statement** on the database, and subsequently execute that prepared statement using the placeholder parameters provided. This means that **all three methods are safe from SQL injection** when used correctly . From Wikipedia: + + Prepared statements are resilient against SQL injection, because parameter values, which are transmitted later using a different protocol, need not be correctly escaped. If the original statement template is not derived from external input, injection cannot occur. + +The placeholder parameter syntax differs depending on your database. Postgres uses the $N notation, but MySQL, SQL Server and others use the ? character as a placeholder." - Alex Edwards + +# run the application and make a request +``` +curl -i localhost:8080/books/show?isbn=978-1505255607 +``` \ No newline at end of file diff --git a/044_postgres/19_where-clause/main.go b/044_postgres/19_where-clause/main.go new file mode 100644 index 00000000..bbd3ea03 --- /dev/null +++ b/044_postgres/19_where-clause/main.go @@ -0,0 +1,97 @@ +package main + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" + "net/http" +) + +var db *sql.DB + +func init() { + var err error + db, err = sql.Open("postgres", "postgres://bond:password@localhost/bookstore?sslmode=disable") + if err != nil { + panic(err) + } + + if err = db.Ping(); err != nil { + panic(err) + } + fmt.Println("You connected to your database.") +} + +type Book struct { + isbn string + title string + author string + price float32 +} + +func main() { + http.HandleFunc("/books", booksIndex) + http.HandleFunc("/books/show", booksShow) + http.ListenAndServe(":8080", nil) +} + +func booksIndex(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + rows, err := db.Query("SELECT * FROM books;") + if err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + defer rows.Close() + + bks := make([]Book, 0) + for rows.Next() { + bk := Book{} + err := rows.Scan(&bk.isbn, &bk.title, &bk.author, &bk.price) // order matters + if err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + bks = append(bks, bk) + } + if err = rows.Err(); err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + + for _, bk := range bks { + fmt.Fprintf(w, "%s, %s, %s, $%.2f\n", bk.isbn, bk.title, bk.author, bk.price) + } +} + +func booksShow(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + isbn := r.FormValue("isbn") + if isbn == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + row := db.QueryRow("SELECT * FROM books WHERE isbn = $1", isbn) + + bk := Book{} + err := row.Scan(&bk.isbn, &bk.title, &bk.author, &bk.price) + switch { + case err == sql.ErrNoRows: + http.NotFound(w, r) + return + case err != nil: + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + fmt.Fprintf(w, "%s, %s, %s, $%.2f\n", bk.isbn, bk.title, bk.author, bk.price) +} diff --git a/044_postgres/20_insert/README.md b/044_postgres/20_insert/README.md new file mode 100644 index 00000000..8ae2c4ae --- /dev/null +++ b/044_postgres/20_insert/README.md @@ -0,0 +1,4 @@ +# run the application and make a request +``` +curl -i -X POST -d "isbn=978-1470184841&title=Metamorphosis&author=Franz Kafka&price=5.90" localhost:8080/books/create/process +``` \ No newline at end of file diff --git a/044_postgres/20_insert/main.go b/044_postgres/20_insert/main.go new file mode 100644 index 00000000..68384307 --- /dev/null +++ b/044_postgres/20_insert/main.go @@ -0,0 +1,151 @@ +package main + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" + "html/template" + "net/http" + "strconv" +) + +var db *sql.DB +var tpl *template.Template + +func init() { + var err error + db, err = sql.Open("postgres", "postgres://bond:password@localhost/bookstore?sslmode=disable") + if err != nil { + panic(err) + } + + if err = db.Ping(); err != nil { + panic(err) + } + fmt.Println("You connected to your database.") + + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +// export fields to templates +// fields changed to uppercase +type Book struct { + Isbn string + Title string + Author string + Price float32 +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/books", booksIndex) + http.HandleFunc("/books/show", booksShow) + http.HandleFunc("/books/create", booksCreateForm) + http.HandleFunc("/books/create/process", booksCreateProcess) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/books", http.StatusSeeOther) +} + +func booksIndex(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + rows, err := db.Query("SELECT * FROM books") + if err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + defer rows.Close() + + bks := make([]Book, 0) + for rows.Next() { + bk := Book{} + err := rows.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) // order matters + if err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + bks = append(bks, bk) + } + if err = rows.Err(); err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + + tpl.ExecuteTemplate(w, "books.gohtml", bks) +} + +func booksShow(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + isbn := r.FormValue("isbn") + if isbn == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + row := db.QueryRow("SELECT * FROM books WHERE isbn = $1", isbn) + + bk := Book{} + err := row.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) + switch { + case err == sql.ErrNoRows: + http.NotFound(w, r) + return + case err != nil: + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + tpl.ExecuteTemplate(w, "show.gohtml", bk) +} + +func booksCreateForm(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "create.gohtml", nil) +} + +func booksCreateProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + // get form values + bk := Book{} + bk.Isbn = r.FormValue("isbn") + bk.Title = r.FormValue("title") + bk.Author = r.FormValue("author") + p := r.FormValue("price") + + // validate form values + if bk.Isbn == "" || bk.Title == "" || bk.Author == "" || p == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + // convert form values + f64, err := strconv.ParseFloat(p, 32) + if err != nil { + http.Error(w, http.StatusText(406)+"Please hit back and enter a number for the price", http.StatusNotAcceptable) + return + } + bk.Price = float32(f64) + + // insert values + _, err = db.Exec("INSERT INTO books (isbn, title, author, price) VALUES ($1, $2, $3, $4)", bk.Isbn, bk.Title, bk.Author, bk.Price) + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + // confirm insertion + tpl.ExecuteTemplate(w, "created.gohtml", bk) +} diff --git a/044_postgres/20_insert/templates/books.gohtml b/044_postgres/20_insert/templates/books.gohtml new file mode 100644 index 00000000..39c95cf6 --- /dev/null +++ b/044_postgres/20_insert/templates/books.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + +{{range .}} +

{{.Isbn}} - {{.Title}} - {{.Author}} - {{.Price}}

+{{end}} + + + + \ No newline at end of file diff --git a/044_postgres/20_insert/templates/create.gohtml b/044_postgres/20_insert/templates/create.gohtml new file mode 100644 index 00000000..1d888873 --- /dev/null +++ b/044_postgres/20_insert/templates/create.gohtml @@ -0,0 +1,39 @@ + + + + + Create Book + + + + +

Create A New Book

+
+ + + + + + + + + \ No newline at end of file diff --git a/044_postgres/20_insert/templates/created.gohtml b/044_postgres/20_insert/templates/created.gohtml new file mode 100644 index 00000000..54cf8977 --- /dev/null +++ b/044_postgres/20_insert/templates/created.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + + +

Created A New Book

+ +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + \ No newline at end of file diff --git a/044_postgres/20_insert/templates/show.gohtml b/044_postgres/20_insert/templates/show.gohtml new file mode 100644 index 00000000..445298e5 --- /dev/null +++ b/044_postgres/20_insert/templates/show.gohtml @@ -0,0 +1,35 @@ + + + + + Create Book + + + + +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + + \ No newline at end of file diff --git a/044_postgres/21_update/main.go b/044_postgres/21_update/main.go new file mode 100644 index 00000000..c082b056 --- /dev/null +++ b/044_postgres/21_update/main.go @@ -0,0 +1,218 @@ +package main + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" + "html/template" + "net/http" + "strconv" +) + +var db *sql.DB +var tpl *template.Template + +func init() { + var err error + db, err = sql.Open("postgres", "postgres://bond:password@localhost/bookstore?sslmode=disable") + if err != nil { + panic(err) + } + + if err = db.Ping(); err != nil { + panic(err) + } + fmt.Println("You connected to your database.") + + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +// export fields to templates +// fields changed to uppercase +type Book struct { + Isbn string + Title string + Author string + Price float32 +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/books", booksIndex) + http.HandleFunc("/books/show", booksShow) + http.HandleFunc("/books/create", booksCreateForm) + http.HandleFunc("/books/create/process", booksCreateProcess) + http.HandleFunc("/books/update", booksUpdateForm) + http.HandleFunc("/books/update/process", booksUpdateProcess) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/books", http.StatusSeeOther) +} + +func booksIndex(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + rows, err := db.Query("SELECT * FROM books") + if err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + defer rows.Close() + + bks := make([]Book, 0) + for rows.Next() { + bk := Book{} + err := rows.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) // order matters + if err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + bks = append(bks, bk) + } + if err = rows.Err(); err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + + tpl.ExecuteTemplate(w, "books.gohtml", bks) +} + +func booksShow(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + isbn := r.FormValue("isbn") + if isbn == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + row := db.QueryRow("SELECT * FROM books WHERE isbn = $1", isbn) + + bk := Book{} + err := row.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) + switch { + case err == sql.ErrNoRows: + http.NotFound(w, r) + return + case err != nil: + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + tpl.ExecuteTemplate(w, "show.gohtml", bk) +} + +func booksCreateForm(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "create.gohtml", nil) +} + +func booksCreateProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + // get form values + bk := Book{} + bk.Isbn = r.FormValue("isbn") + bk.Title = r.FormValue("title") + bk.Author = r.FormValue("author") + p := r.FormValue("price") + + // validate form values + if bk.Isbn == "" || bk.Title == "" || bk.Author == "" || p == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + // convert form values + f64, err := strconv.ParseFloat(p, 32) + if err != nil { + http.Error(w, http.StatusText(406)+"Please hit back and enter a number for the price", http.StatusNotAcceptable) + return + } + bk.Price = float32(f64) + + // insert values + _, err = db.Exec("INSERT INTO books (isbn, title, author, price) VALUES ($1, $2, $3, $4)", bk.Isbn, bk.Title, bk.Author, bk.Price) + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + // confirm insertion + tpl.ExecuteTemplate(w, "created.gohtml", bk) +} + +func booksUpdateForm(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + isbn := r.FormValue("isbn") + if isbn == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + row := db.QueryRow("SELECT * FROM books WHERE isbn = $1", isbn) + + bk := Book{} + err := row.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) + switch { + case err == sql.ErrNoRows: + http.NotFound(w, r) + return + case err != nil: + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + tpl.ExecuteTemplate(w, "update.gohtml", bk) +} + +func booksUpdateProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + // get form values + bk := Book{} + bk.Isbn = r.FormValue("isbn") + bk.Title = r.FormValue("title") + bk.Author = r.FormValue("author") + p := r.FormValue("price") + + // validate form values + if bk.Isbn == "" || bk.Title == "" || bk.Author == "" || p == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + // convert form values + f64, err := strconv.ParseFloat(p, 32) + if err != nil { + http.Error(w, http.StatusText(406)+"Please hit back and enter a number for the price", http.StatusNotAcceptable) + return + } + bk.Price = float32(f64) + + // insert values + _, err = db.Exec("UPDATE books SET isbn = $1, title=$2, author=$3, price=$4 WHERE isbn=$1;", bk.Isbn, bk.Title, bk.Author, bk.Price) + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + // confirm insertion + tpl.ExecuteTemplate(w, "updated.gohtml", bk) +} diff --git a/044_postgres/21_update/templates/books.gohtml b/044_postgres/21_update/templates/books.gohtml new file mode 100644 index 00000000..b4abd252 --- /dev/null +++ b/044_postgres/21_update/templates/books.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + +{{range .}} +

{{.Isbn}} - {{.Title}} - {{.Author}} - {{.Price}} - update

+{{end}} + + + + \ No newline at end of file diff --git a/044_postgres/21_update/templates/create.gohtml b/044_postgres/21_update/templates/create.gohtml new file mode 100644 index 00000000..1d888873 --- /dev/null +++ b/044_postgres/21_update/templates/create.gohtml @@ -0,0 +1,39 @@ + + + + + Create Book + + + + +

Create A New Book

+
+ + + + + + + + + \ No newline at end of file diff --git a/044_postgres/21_update/templates/created.gohtml b/044_postgres/21_update/templates/created.gohtml new file mode 100644 index 00000000..54cf8977 --- /dev/null +++ b/044_postgres/21_update/templates/created.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + + +

Created A New Book

+ +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + \ No newline at end of file diff --git a/044_postgres/21_update/templates/show.gohtml b/044_postgres/21_update/templates/show.gohtml new file mode 100644 index 00000000..445298e5 --- /dev/null +++ b/044_postgres/21_update/templates/show.gohtml @@ -0,0 +1,35 @@ + + + + + Create Book + + + + +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + + \ No newline at end of file diff --git a/044_postgres/21_update/templates/update.gohtml b/044_postgres/21_update/templates/update.gohtml new file mode 100644 index 00000000..bc799ea3 --- /dev/null +++ b/044_postgres/21_update/templates/update.gohtml @@ -0,0 +1,39 @@ + + + + + Create Book + + + + +

Update A Book

+
+ + + + + + + + + \ No newline at end of file diff --git a/044_postgres/21_update/templates/updated.gohtml b/044_postgres/21_update/templates/updated.gohtml new file mode 100644 index 00000000..a435784b --- /dev/null +++ b/044_postgres/21_update/templates/updated.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + + +

Updated Book

+ +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + \ No newline at end of file diff --git a/044_postgres/22_delete/main.go b/044_postgres/22_delete/main.go new file mode 100644 index 00000000..5fc34179 --- /dev/null +++ b/044_postgres/22_delete/main.go @@ -0,0 +1,241 @@ +package main + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" + "html/template" + "net/http" + "strconv" +) + +var db *sql.DB +var tpl *template.Template + +func init() { + var err error + db, err = sql.Open("postgres", "postgres://bond:password@localhost/bookstore?sslmode=disable") + if err != nil { + panic(err) + } + + if err = db.Ping(); err != nil { + panic(err) + } + fmt.Println("You connected to your database.") + + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +// export fields to templates +// fields changed to uppercase +type Book struct { + Isbn string + Title string + Author string + Price float32 +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/books", booksIndex) + http.HandleFunc("/books/show", booksShow) + http.HandleFunc("/books/create", booksCreateForm) + http.HandleFunc("/books/create/process", booksCreateProcess) + http.HandleFunc("/books/update", booksUpdateForm) + http.HandleFunc("/books/update/process", booksUpdateProcess) + http.HandleFunc("/books/delete/process", booksDeleteProcess) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/books", http.StatusSeeOther) +} + +func booksIndex(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + rows, err := db.Query("SELECT * FROM books") + if err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + defer rows.Close() + + bks := make([]Book, 0) + for rows.Next() { + bk := Book{} + err := rows.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) // order matters + if err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + bks = append(bks, bk) + } + if err = rows.Err(); err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + + tpl.ExecuteTemplate(w, "books.gohtml", bks) +} + +func booksShow(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + isbn := r.FormValue("isbn") + if isbn == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + row := db.QueryRow("SELECT * FROM books WHERE isbn = $1", isbn) + + bk := Book{} + err := row.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) + switch { + case err == sql.ErrNoRows: + http.NotFound(w, r) + return + case err != nil: + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + tpl.ExecuteTemplate(w, "show.gohtml", bk) +} + +func booksCreateForm(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "create.gohtml", nil) +} + +func booksCreateProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + // get form values + bk := Book{} + bk.Isbn = r.FormValue("isbn") + bk.Title = r.FormValue("title") + bk.Author = r.FormValue("author") + p := r.FormValue("price") + + // validate form values + if bk.Isbn == "" || bk.Title == "" || bk.Author == "" || p == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + // convert form values + f64, err := strconv.ParseFloat(p, 32) + if err != nil { + http.Error(w, http.StatusText(406)+"Please hit back and enter a number for the price", http.StatusNotAcceptable) + return + } + bk.Price = float32(f64) + + // insert values + _, err = db.Exec("INSERT INTO books (isbn, title, author, price) VALUES ($1, $2, $3, $4)", bk.Isbn, bk.Title, bk.Author, bk.Price) + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + // confirm insertion + tpl.ExecuteTemplate(w, "created.gohtml", bk) +} + +func booksUpdateForm(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + isbn := r.FormValue("isbn") + if isbn == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + row := db.QueryRow("SELECT * FROM books WHERE isbn = $1", isbn) + + bk := Book{} + err := row.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) + switch { + case err == sql.ErrNoRows: + http.NotFound(w, r) + return + case err != nil: + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + tpl.ExecuteTemplate(w, "update.gohtml", bk) +} + +func booksUpdateProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + // get form values + bk := Book{} + bk.Isbn = r.FormValue("isbn") + bk.Title = r.FormValue("title") + bk.Author = r.FormValue("author") + p := r.FormValue("price") + + // validate form values + if bk.Isbn == "" || bk.Title == "" || bk.Author == "" || p == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + // convert form values + f64, err := strconv.ParseFloat(p, 32) + if err != nil { + http.Error(w, http.StatusText(406)+"Please hit back and enter a number for the price", http.StatusNotAcceptable) + return + } + bk.Price = float32(f64) + + // insert values + _, err = db.Exec("UPDATE books SET isbn = $1, title=$2, author=$3, price=$4 WHERE isbn=$1;", bk.Isbn, bk.Title, bk.Author, bk.Price) + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + // confirm insertion + tpl.ExecuteTemplate(w, "updated.gohtml", bk) +} + +func booksDeleteProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + isbn := r.FormValue("isbn") + if isbn == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + // delete book + _, err := db.Exec("DELETE FROM books WHERE isbn=$1;", isbn) + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + http.Redirect(w, r, "/books", http.StatusSeeOther) +} diff --git a/044_postgres/22_delete/templates/books.gohtml b/044_postgres/22_delete/templates/books.gohtml new file mode 100644 index 00000000..4aa7046a --- /dev/null +++ b/044_postgres/22_delete/templates/books.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + +{{range .}} +

{{.Isbn}} - {{.Title}} - {{.Author}} - {{.Price}} - update - delete

+{{end}} + + + + \ No newline at end of file diff --git a/044_postgres/22_delete/templates/create.gohtml b/044_postgres/22_delete/templates/create.gohtml new file mode 100644 index 00000000..1d888873 --- /dev/null +++ b/044_postgres/22_delete/templates/create.gohtml @@ -0,0 +1,39 @@ + + + + + Create Book + + + + +

Create A New Book

+
+ + + + + + + + + \ No newline at end of file diff --git a/044_postgres/22_delete/templates/created.gohtml b/044_postgres/22_delete/templates/created.gohtml new file mode 100644 index 00000000..54cf8977 --- /dev/null +++ b/044_postgres/22_delete/templates/created.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + + +

Created A New Book

+ +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + \ No newline at end of file diff --git a/044_postgres/22_delete/templates/show.gohtml b/044_postgres/22_delete/templates/show.gohtml new file mode 100644 index 00000000..445298e5 --- /dev/null +++ b/044_postgres/22_delete/templates/show.gohtml @@ -0,0 +1,35 @@ + + + + + Create Book + + + + +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + + \ No newline at end of file diff --git a/044_postgres/22_delete/templates/update.gohtml b/044_postgres/22_delete/templates/update.gohtml new file mode 100644 index 00000000..bc799ea3 --- /dev/null +++ b/044_postgres/22_delete/templates/update.gohtml @@ -0,0 +1,39 @@ + + + + + Create Book + + + + +

Update A Book

+
+ + + + + + + + + \ No newline at end of file diff --git a/044_postgres/22_delete/templates/updated.gohtml b/044_postgres/22_delete/templates/updated.gohtml new file mode 100644 index 00000000..a435784b --- /dev/null +++ b/044_postgres/22_delete/templates/updated.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + + +

Updated Book

+ +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + \ No newline at end of file diff --git a/044_postgres/README.md b/044_postgres/README.md new file mode 100644 index 00000000..3d1c4399 --- /dev/null +++ b/044_postgres/README.md @@ -0,0 +1,500 @@ +# Commands + +Here are all of the commands we will use in this section + +## log in +``` +/Applications/Postgres.app/Contents/Versions/9.6/bin/psql -p5432 +``` + +## list databases +``` +\l +``` + +## connect to a database +``` +\c +``` + +## switch back to postgres database +``` +\c postgres +``` + +## log out +``` +\q +``` + +# create database +``` +CREATE DATABASE employees; +``` + +## see current user +``` +SELECT current_user; +``` + +## see current database +``` +SELECT current_database(); +``` + +## drop (remove, delete) database +``` +DROP DATABASE ; +``` + +# create table +``` +CREATE TABLE employees ( + ID INT PRIMARY KEY NOT NULL, + NAME TEXT NOT NULL, + RANK INT NOT NULL, + ADDRESS CHAR(50), + SALARY REAL DEFAULT 25500.00, + BDAY DATE DEFAULT '1900-01-01' +); +``` + +## show tables in a database (list down) +``` +\d +``` + +## show details of a table +``` +\d
+``` + +## drop a table +``` +DROP TABLE
; +``` + +# insert a record +``` +INSERT INTO employees (ID,NAME,RANK,ADDRESS,SALARY,BDAY) VALUES (1, 'Mark', 7, '1212 E. Lane, Someville, AK, 57483', 43000.00 ,'1992-01-13'); +``` + +## list records in a table +``` +SELECT * FROM
; +``` + +## insert a record - variations +omitted values will have the [default value](https://www.postgresql.org/docs/9.3/static/ddl-default.html): +``` +INSERT INTO employees (ID,NAME,RANK,ADDRESS,BDAY) VALUES (2, 'Marian', 8, '7214 Wonderlust Ave, Lost Lake, KS, 22897', '1989-11-21'); +``` + +we can use DEFAULT rather leaving a field blank or specifying a value: +``` +INSERT INTO employees (ID,NAME,RANK,ADDRESS,SALARY,BDAY) VALUES (3, 'Maxwell', 6, '7215 Jasmine Place, Corinda, CA 98743', 87500.00, DEFAULT); +``` + +we can insert multiple rows: +``` +INSERT INTO employees (ID,NAME,RANK,ADDRESS,SALARY,BDAY) VALUES (4, 'Jasmine', 5, '983 Star Ave., Brooklyn, NY, 00912 ', 55700.00, '1997-12-13' ), (5, 'Orranda', 9, '745 Hammer Lane, Hammerfield, Texas, 75839', 65350.00 , '1992-12-13'); +``` + +# auto increment key field +``` +CREATE TABLE phonenumbers( + ID SERIAL PRIMARY KEY, + PHONE TEXT NOT NULL +); +``` + +``` +INSERT INTO phonenumbers (PHONE) VALUES ( '234-432-5234'), ('543-534-6543'), ('312-123-5432'); +``` + +``` +\d phonenumbers +``` + +``` +SELECT * FROM phonenumbers; +``` + +# hands-on exercise +1. delete all of your current tables. +1. READ ALL OF THIS: create a new table called employees with these fields ```id, name, score, salary``` AND give ```score``` a default value of 10 AND have the ```id``` field automatically increment. +1. add these records and then show all of the records +``` + id | name | score | salary +----+--------+-------+-------- + 1 | Daniel | 23 | 55000 + 2 | Arin | 25 | 65000 + 3 | Juan | 24 | 72000 + 4 | Shen | 26 | 64000 + 5 | Myke | 27 | 58000 + 6 | McLeod | 26 | 72000 + 7 | James | 32 | 35000 +``` + +# solution +``` +DROP TABLE employees, phonenumbers; +``` + +``` +CREATE TABLE employees ( + ID SERIAL PRIMARY KEY NOT NULL, + NAME TEXT NOT NULL, + SCORE INT DEFAULT 10 NOT NULL, + SALARY REAL +); +``` + +``` +INSERT INTO employees (NAME,SCORE,SALARY) VALUES ('Daniel', 23, 55000.00), ('Arin', 25, 65000.00), ('Juan', 24, 72000.00), ('Shen', 26, 64000.00), ('Myke', 27, 58000.00), ('McLeod', 26, 72000.00), ('James', 32, 35000.00); +``` + +``` +SELECT * FROM employees; +``` + +# relational databases + +![Understanding relational databases](db.png) + +``` +CREATE TABLE phonenumbers ( + ID SERIAL PRIMARY KEY NOT NULL, + PHONE CHAR(50) NOT NULL, + EMP_ID INT references employees(ID) +); +``` + +``` +INSERT INTO phonenumbers (PHONE,EMP_ID) VALUES ('555-777-8888', 4), ('555-222-3345', 4), ('777-543-3451', 1), ('544-756-2334', 2); +``` + +# queries +``` +SELECT employees.NAME, phonenumbers.PHONE FROM employees INNER JOIN phonenumbers ON employees.ID = phonenumbers.EMP_ID; +``` + +## cross join + +``` +CREATE TABLE person ( + ID SERIAL PRIMARY KEY NOT NULL, + NAME CHAR(50) NOT NULL +); +``` + +``` +INSERT INTO person (NAME) VALUES ('Shen'), ('Daniel'), ('Juan'), ('Arin'), ('McLeod'); +``` + +``` +CREATE TABLE sport ( + ID SERIAL PRIMARY KEY NOT NULL, + NAME CHAR(50) NOT NULL, + P_ID INT references person(ID) +); +``` + +``` +INSERT INTO sport (NAME, P_ID) VALUES ('Surf',1),('Soccer',3),('Ski',3),('Sail',3),('Bike',3); +``` + +``` +SELECT person.NAME, sport.NAME FROM person CROSS JOIN sport; +``` + +# inner join + +## two tables + +#### review basic select + +``` +SELECT FROM
; +``` + +``` +SELECT * FROM employees; +``` + +``` +SELECT name, score FROM employees; +``` + +#### review cross join +``` +SELECT FROM CROSS JOIN ; +``` + +``` +SELECT person.NAME, sport.NAME FROM person CROSS JOIN sport; +``` + +### inner join +``` +SELECT FROM
INNER JOIN
+ON = ; +``` + +``` +SELECT person.NAME, sport.NAME FROM person INNER JOIN sport +ON person.ID = sport.P_ID; +``` + +``` +SELECT employees.NAME, phonenumbers.PHONE FROM employees INNER JOIN phonenumbers ON employees.ID = phonenumbers.EMP_ID; +``` + +We can use one with our ```people``` and ```sports``` table too, if we wanted, as these tables are connected (remember ```P_ID INT references person(ID)```). + +``` +SELECT person.NAME, sport.NAME FROM person INNER JOIN sport ON person.ID = sport.P_ID; +``` + +## three tables - video rental database + +#### create a database +``` +create database blockbuster; +``` + +#### switch into the database +``` +\c blockbuster +``` + +#### create three tables + +``` +create table customers (cid serial primary key not null, cfirst char(50) not null); +``` + +``` +create table movies (mid serial primary key not null, mmovie char(50) not null); +``` + +``` +create table rentals (rid serial primary key not null, cid int references customers(cid), mid int references movies(mid)); +``` + +#### populate tables +``` +insert into customers (cfirst) values ('James Bond'), ('Miss Moneypenny'), ('Q'), ('M'), ('Fleming'); +``` + +``` +insert into movies (mmovie) values ('Jaws'), ('Alien'), ('Never Say Never'), ('Skyfall'), ('Highlander'); +``` + +``` +insert into rentals (cid, mid) values (1,3), (2,5), (4,1), (3,2), (5,4), (3,2), (1,3), (2,4), (5,4), (2,1), (2,3), (4,5), (5,2), (2,1), (3,2), (3,3), (2,3), (1,4), (3,2), (2,3), (3,3), (2,4), (2,3), (1,2), (3,5), (3,4), (1,5); +``` + +#### inner join query +``` +select customers.cfirst, movies.mmovie from customers inner join rentals on customers.cid = rentals.cid inner join movies on rentals.mid = movies.mid; +``` + + +### How this works + +``` +select * from +tableA inner join tableB + on tableA.common = tableB.common +inner join TableC + on tableB.common = TableC.common +``` + +#### you might also see alias use + +``` +select * from +tableA a inner join tableB b + on a.common = b.common +inner join TableC c + on b.common = c.common +``` + +# outer join + +#### left outer join + ``` + SELECT person.NAME, sport.NAME FROM person LEFT OUTER JOIN sport ON person.ID = sport.P_ID; + ``` + +#### right outer join +A right outer join is like a left outer join, but for the table on the right. + +``` +INSERT INTO sport (NAME) VALUES ('Squirrel Suit Flying'); +``` + +``` + SELECT person.NAME, sport.NAME FROM person RIGHT OUTER JOIN sport ON person.ID = sport.P_ID; +``` + +#### full outer join +A full outer join is like running both a left outer join and a right outer join at the same time. It gives you everything from all tables, and matches what matches. + +``` + SELECT person.NAME, sport.NAME FROM person FULL OUTER JOIN sport ON person.ID = sport.P_ID; +``` + +# clauses + +## where + +Adding **WHERE** to a SQL query allows you to filter results. + +``` +SELECT * FROM employees WHERE salary > 60000; +``` + +### and +``` +SELECT * FROM employees WHERE salary > 60000 AND score = 26; +``` + +### in +``` +SELECT * FROM employees WHERE score IN (25,26); +``` + +### not +``` +SELECT * FROM employees WHERE score NOT IN (25,26); +``` + +### between +``` +SELECT * FROM employees WHERE score BETWEEN 23 AND 26; +``` + +### is not null +``` +SELECT * FROM employees WHERE score IS NOT NULL; +``` + +### like +``` +SELECT * FROM employees WHERE name LIKE '%an%'; +``` + +### or +``` +SELECT * FROM employees WHERE score <= 24 OR salary < 50000; +``` + +## limit +Limit the number of records returned +``` +SELECT * FROM employees LIMIT 4; +``` + +``` +SELECT * FROM employees ORDER BY id LIMIT 4; +``` + +# update + +syntax +``` +UPDATE table +SET col1 = val1, col2 = val2, ..., colN = valN +WHERE ; +``` + +``` +SELECT * FROM employees; +``` + +``` +UPDATE employees SET score = 99 WHERE ID = 3; +``` + +## order by +``` +SELECT * FROM employees ORDER BY id; +``` + +# delete + +syntax +``` +DELETE FROM table +WHERE ; +``` + +``` +SELECT * FROM sport; +``` + +``` +DELETE FROM sport WHERE id = 6; +``` + +**WARNING: this deletes all records:** +``` +DELETE FROM sport; +``` + +# users & privileges + +## see current user +``` +SELECT current_user; +``` + +## details of users +``` +\du +``` + +## create user +``` +CREATE USER james WITH PASSWORD 'password'; +``` + +## grant privileges +``` +GRANT ALL PRIVILEGES ON DATABASE employees to james; +``` + +## alter +``` +ALTER USER james WITH SUPERUSER; +``` + +## remove +``` +DROP USER james; +``` + +# Go & postgres + +driver +``` +go get github.com/lib/pq +``` + +## create a db + +``` +CREATE DATABASE bookstore; +``` + +## create user +``` +CREATE USER bond WITH PASSWORD 'password'; +``` + +## grant privileges +``` +GRANT ALL PRIVILEGES ON DATABASE bookstore to bond; +``` \ No newline at end of file diff --git a/044_postgres/db.png b/044_postgres/db.png new file mode 100644 index 00000000..6af1da69 Binary files /dev/null and b/044_postgres/db.png differ diff --git a/045-code-organization/01_one-package/README.md b/045-code-organization/01_one-package/README.md new file mode 100644 index 00000000..80f0c5b2 --- /dev/null +++ b/045-code-organization/01_one-package/README.md @@ -0,0 +1,3 @@ +# Note + +This code is the same code from folder ```044_postgres / 22_delete``` \ No newline at end of file diff --git a/045-code-organization/01_one-package/main.go b/045-code-organization/01_one-package/main.go new file mode 100644 index 00000000..5fc34179 --- /dev/null +++ b/045-code-organization/01_one-package/main.go @@ -0,0 +1,241 @@ +package main + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" + "html/template" + "net/http" + "strconv" +) + +var db *sql.DB +var tpl *template.Template + +func init() { + var err error + db, err = sql.Open("postgres", "postgres://bond:password@localhost/bookstore?sslmode=disable") + if err != nil { + panic(err) + } + + if err = db.Ping(); err != nil { + panic(err) + } + fmt.Println("You connected to your database.") + + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +// export fields to templates +// fields changed to uppercase +type Book struct { + Isbn string + Title string + Author string + Price float32 +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/books", booksIndex) + http.HandleFunc("/books/show", booksShow) + http.HandleFunc("/books/create", booksCreateForm) + http.HandleFunc("/books/create/process", booksCreateProcess) + http.HandleFunc("/books/update", booksUpdateForm) + http.HandleFunc("/books/update/process", booksUpdateProcess) + http.HandleFunc("/books/delete/process", booksDeleteProcess) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/books", http.StatusSeeOther) +} + +func booksIndex(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + rows, err := db.Query("SELECT * FROM books") + if err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + defer rows.Close() + + bks := make([]Book, 0) + for rows.Next() { + bk := Book{} + err := rows.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) // order matters + if err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + bks = append(bks, bk) + } + if err = rows.Err(); err != nil { + http.Error(w, http.StatusText(500), 500) + return + } + + tpl.ExecuteTemplate(w, "books.gohtml", bks) +} + +func booksShow(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + isbn := r.FormValue("isbn") + if isbn == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + row := db.QueryRow("SELECT * FROM books WHERE isbn = $1", isbn) + + bk := Book{} + err := row.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) + switch { + case err == sql.ErrNoRows: + http.NotFound(w, r) + return + case err != nil: + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + tpl.ExecuteTemplate(w, "show.gohtml", bk) +} + +func booksCreateForm(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "create.gohtml", nil) +} + +func booksCreateProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + // get form values + bk := Book{} + bk.Isbn = r.FormValue("isbn") + bk.Title = r.FormValue("title") + bk.Author = r.FormValue("author") + p := r.FormValue("price") + + // validate form values + if bk.Isbn == "" || bk.Title == "" || bk.Author == "" || p == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + // convert form values + f64, err := strconv.ParseFloat(p, 32) + if err != nil { + http.Error(w, http.StatusText(406)+"Please hit back and enter a number for the price", http.StatusNotAcceptable) + return + } + bk.Price = float32(f64) + + // insert values + _, err = db.Exec("INSERT INTO books (isbn, title, author, price) VALUES ($1, $2, $3, $4)", bk.Isbn, bk.Title, bk.Author, bk.Price) + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + // confirm insertion + tpl.ExecuteTemplate(w, "created.gohtml", bk) +} + +func booksUpdateForm(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + isbn := r.FormValue("isbn") + if isbn == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + row := db.QueryRow("SELECT * FROM books WHERE isbn = $1", isbn) + + bk := Book{} + err := row.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) + switch { + case err == sql.ErrNoRows: + http.NotFound(w, r) + return + case err != nil: + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + tpl.ExecuteTemplate(w, "update.gohtml", bk) +} + +func booksUpdateProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + // get form values + bk := Book{} + bk.Isbn = r.FormValue("isbn") + bk.Title = r.FormValue("title") + bk.Author = r.FormValue("author") + p := r.FormValue("price") + + // validate form values + if bk.Isbn == "" || bk.Title == "" || bk.Author == "" || p == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + // convert form values + f64, err := strconv.ParseFloat(p, 32) + if err != nil { + http.Error(w, http.StatusText(406)+"Please hit back and enter a number for the price", http.StatusNotAcceptable) + return + } + bk.Price = float32(f64) + + // insert values + _, err = db.Exec("UPDATE books SET isbn = $1, title=$2, author=$3, price=$4 WHERE isbn=$1;", bk.Isbn, bk.Title, bk.Author, bk.Price) + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + // confirm insertion + tpl.ExecuteTemplate(w, "updated.gohtml", bk) +} + +func booksDeleteProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + isbn := r.FormValue("isbn") + if isbn == "" { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + // delete book + _, err := db.Exec("DELETE FROM books WHERE isbn=$1;", isbn) + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + http.Redirect(w, r, "/books", http.StatusSeeOther) +} diff --git a/045-code-organization/01_one-package/templates/books.gohtml b/045-code-organization/01_one-package/templates/books.gohtml new file mode 100644 index 00000000..4aa7046a --- /dev/null +++ b/045-code-organization/01_one-package/templates/books.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + +{{range .}} +

{{.Isbn}} - {{.Title}} - {{.Author}} - {{.Price}} - update - delete

+{{end}} + + + + \ No newline at end of file diff --git a/045-code-organization/01_one-package/templates/create.gohtml b/045-code-organization/01_one-package/templates/create.gohtml new file mode 100644 index 00000000..1d888873 --- /dev/null +++ b/045-code-organization/01_one-package/templates/create.gohtml @@ -0,0 +1,39 @@ + + + + + Create Book + + + + +

Create A New Book

+
+ + + + + + + + + \ No newline at end of file diff --git a/045-code-organization/01_one-package/templates/created.gohtml b/045-code-organization/01_one-package/templates/created.gohtml new file mode 100644 index 00000000..54cf8977 --- /dev/null +++ b/045-code-organization/01_one-package/templates/created.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + + +

Created A New Book

+ +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + \ No newline at end of file diff --git a/045-code-organization/01_one-package/templates/show.gohtml b/045-code-organization/01_one-package/templates/show.gohtml new file mode 100644 index 00000000..445298e5 --- /dev/null +++ b/045-code-organization/01_one-package/templates/show.gohtml @@ -0,0 +1,35 @@ + + + + + Create Book + + + + +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + + \ No newline at end of file diff --git a/045-code-organization/01_one-package/templates/update.gohtml b/045-code-organization/01_one-package/templates/update.gohtml new file mode 100644 index 00000000..bc799ea3 --- /dev/null +++ b/045-code-organization/01_one-package/templates/update.gohtml @@ -0,0 +1,39 @@ + + + + + Create Book + + + + +

Update A Book

+
+ + + + + + + + + \ No newline at end of file diff --git a/045-code-organization/01_one-package/templates/updated.gohtml b/045-code-organization/01_one-package/templates/updated.gohtml new file mode 100644 index 00000000..a435784b --- /dev/null +++ b/045-code-organization/01_one-package/templates/updated.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + + +

Updated Book

+ +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + \ No newline at end of file diff --git a/045-code-organization/02_two-packages/README.md b/045-code-organization/02_two-packages/README.md new file mode 100644 index 00000000..5ca7a23c --- /dev/null +++ b/045-code-organization/02_two-packages/README.md @@ -0,0 +1,12 @@ +# Note + +**Remember:** You need to capitalize to have a variable, type, or func exported from a package + +# run the application and make a request +``` +curl -i localhost:8080/books +``` + +``` +curl -i -X POST -d "isbn=978-1470184841&title=Metamorphosis&author=Franz Kafka&price=5.90" localhost:8080/books/create/process +``` \ No newline at end of file diff --git a/045-code-organization/02_two-packages/main.go b/045-code-organization/02_two-packages/main.go new file mode 100644 index 00000000..7c3f2bbe --- /dev/null +++ b/045-code-organization/02_two-packages/main.go @@ -0,0 +1,132 @@ +package main + +import ( + "database/sql" + "github.com/GoesToEleven/golang-web-dev/045-code-organization/02_two-packages/models" + "html/template" + "net/http" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*.gohtml")) +} + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/books", booksIndex) + http.HandleFunc("/books/show", booksShow) + http.HandleFunc("/books/create", booksCreateForm) + http.HandleFunc("/books/create/process", booksCreateProcess) + http.HandleFunc("/books/update", booksUpdateForm) + http.HandleFunc("/books/update/process", booksUpdateProcess) + http.HandleFunc("/books/delete/process", booksDeleteProcess) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/books", http.StatusSeeOther) +} + +func booksIndex(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bks, err := models.AllBooks() + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + tpl.ExecuteTemplate(w, "books.gohtml", bks) +} + +func booksShow(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := models.OneBook(r) + switch { + case err == sql.ErrNoRows: + http.NotFound(w, r) + return + case err != nil: + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + tpl.ExecuteTemplate(w, "show.gohtml", bk) +} + +func booksCreateForm(w http.ResponseWriter, r *http.Request) { + tpl.ExecuteTemplate(w, "create.gohtml", nil) +} + +func booksCreateProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := models.PutBook(r) + if err != nil { + http.Error(w, http.StatusText(406), http.StatusNotAcceptable) + return + } + + tpl.ExecuteTemplate(w, "created.gohtml", bk) +} + +func booksUpdateForm(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := models.OneBook(r) + switch { + case err == sql.ErrNoRows: + http.NotFound(w, r) + return + case err != nil: + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + tpl.ExecuteTemplate(w, "update.gohtml", bk) +} + +func booksUpdateProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := models.UpdateBook(r) + if err != nil { + http.Error(w, http.StatusText(406), http.StatusBadRequest) + return + } + + tpl.ExecuteTemplate(w, "updated.gohtml", bk) +} + +func booksDeleteProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + err := models.DeleteBook(r) + if err != nil { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + http.Redirect(w, r, "/books", http.StatusSeeOther) +} diff --git a/045-code-organization/02_two-packages/models/books.go b/045-code-organization/02_two-packages/models/books.go new file mode 100644 index 00000000..0ed9656c --- /dev/null +++ b/045-code-organization/02_two-packages/models/books.go @@ -0,0 +1,121 @@ +package models + +import ( + "errors" + "net/http" + "strconv" +) + +type Book struct { + Isbn string + Title string + Author string + Price float32 +} + +func AllBooks() ([]Book, error) { + rows, err := db.Query("SELECT * FROM books") + if err != nil { + return nil, err + } + defer rows.Close() + + bks := make([]Book, 0) + for rows.Next() { + bk := Book{} + err := rows.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) // order matters + if err != nil { + return nil, err + } + bks = append(bks, bk) + } + if err = rows.Err(); err != nil { + return nil, err + } + return bks, nil +} + +func OneBook(r *http.Request) (Book, error) { + bk := Book{} + isbn := r.FormValue("isbn") + if isbn == "" { + return bk, errors.New("400. Bad Request.") + } + + row := db.QueryRow("SELECT * FROM books WHERE isbn = $1", isbn) + + err := row.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) + if err != nil { + return bk, err + } + + return bk, nil +} + +func PutBook(r *http.Request) (Book, error) { + // get form values + bk := Book{} + bk.Isbn = r.FormValue("isbn") + bk.Title = r.FormValue("title") + bk.Author = r.FormValue("author") + p := r.FormValue("price") + + // validate form values + if bk.Isbn == "" || bk.Title == "" || bk.Author == "" || p == "" { + return bk, errors.New("400. Bad request. All fields must be complete.") + } + + // convert form values + f64, err := strconv.ParseFloat(p, 32) + if err != nil { + return bk, errors.New("406. Not Acceptable. Price must be a number.") + } + bk.Price = float32(f64) + + // insert values + _, err = db.Exec("INSERT INTO books (isbn, title, author, price) VALUES ($1, $2, $3, $4)", bk.Isbn, bk.Title, bk.Author, bk.Price) + if err != nil { + return bk, errors.New("500. Internal Server Error." + err.Error()) + } + return bk, nil +} + +func UpdateBook(r *http.Request) (Book, error) { + // get form values + bk := Book{} + bk.Isbn = r.FormValue("isbn") + bk.Title = r.FormValue("title") + bk.Author = r.FormValue("author") + p := r.FormValue("price") + + if bk.Isbn == "" || bk.Title == "" || bk.Author == "" || p == "" { + return bk, errors.New("400. Bad Request. Fields can't be empty.") + } + + // convert form values + f64, err := strconv.ParseFloat(p, 32) + if err != nil { + return bk, errors.New("406. Not Acceptable. Enter number for price.") + } + bk.Price = float32(f64) + + // insert values + _, err = db.Exec("UPDATE books SET isbn = $1, title=$2, author=$3, price=$4 WHERE isbn=$1;", bk.Isbn, bk.Title, bk.Author, bk.Price) + if err != nil { + return bk, err + } + return bk, nil +} + +func DeleteBook(r *http.Request) error { + isbn := r.FormValue("isbn") + if isbn == "" { + return errors.New("400. Bad Request.") + } + + _, err := db.Exec("DELETE FROM books WHERE isbn=$1;", isbn) + if err != nil { + return errors.New("500. Internal Server Error") + } + return nil +} diff --git a/045-code-organization/02_two-packages/models/db.go b/045-code-organization/02_two-packages/models/db.go new file mode 100644 index 00000000..5728625a --- /dev/null +++ b/045-code-organization/02_two-packages/models/db.go @@ -0,0 +1,22 @@ +package models + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" +) + +var db *sql.DB + +func init() { + var err error + db, err = sql.Open("postgres", "postgres://bond:password@localhost/bookstore?sslmode=disable") + if err != nil { + panic(err) + } + + if err = db.Ping(); err != nil { + panic(err) + } + fmt.Println("You connected to your database.") +} diff --git a/045-code-organization/02_two-packages/templates/books.gohtml b/045-code-organization/02_two-packages/templates/books.gohtml new file mode 100644 index 00000000..4aa7046a --- /dev/null +++ b/045-code-organization/02_two-packages/templates/books.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + +{{range .}} +

{{.Isbn}} - {{.Title}} - {{.Author}} - {{.Price}} - update - delete

+{{end}} + + + + \ No newline at end of file diff --git a/045-code-organization/02_two-packages/templates/create.gohtml b/045-code-organization/02_two-packages/templates/create.gohtml new file mode 100644 index 00000000..1d888873 --- /dev/null +++ b/045-code-organization/02_two-packages/templates/create.gohtml @@ -0,0 +1,39 @@ + + + + + Create Book + + + + +

Create A New Book

+
+ + + + + + + + + \ No newline at end of file diff --git a/045-code-organization/02_two-packages/templates/created.gohtml b/045-code-organization/02_two-packages/templates/created.gohtml new file mode 100644 index 00000000..54cf8977 --- /dev/null +++ b/045-code-organization/02_two-packages/templates/created.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + + +

Created A New Book

+ +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + \ No newline at end of file diff --git a/045-code-organization/02_two-packages/templates/show.gohtml b/045-code-organization/02_two-packages/templates/show.gohtml new file mode 100644 index 00000000..445298e5 --- /dev/null +++ b/045-code-organization/02_two-packages/templates/show.gohtml @@ -0,0 +1,35 @@ + + + + + Create Book + + + + +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + + \ No newline at end of file diff --git a/045-code-organization/02_two-packages/templates/update.gohtml b/045-code-organization/02_two-packages/templates/update.gohtml new file mode 100644 index 00000000..bc799ea3 --- /dev/null +++ b/045-code-organization/02_two-packages/templates/update.gohtml @@ -0,0 +1,39 @@ + + + + + Create Book + + + + +

Update A Book

+
+ + + + + + + + + \ No newline at end of file diff --git a/045-code-organization/02_two-packages/templates/updated.gohtml b/045-code-organization/02_two-packages/templates/updated.gohtml new file mode 100644 index 00000000..a435784b --- /dev/null +++ b/045-code-organization/02_two-packages/templates/updated.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + + +

Updated Book

+ +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + \ No newline at end of file diff --git a/045-code-organization/03_multiple-packages/README.md b/045-code-organization/03_multiple-packages/README.md new file mode 100644 index 00000000..5ca7a23c --- /dev/null +++ b/045-code-organization/03_multiple-packages/README.md @@ -0,0 +1,12 @@ +# Note + +**Remember:** You need to capitalize to have a variable, type, or func exported from a package + +# run the application and make a request +``` +curl -i localhost:8080/books +``` + +``` +curl -i -X POST -d "isbn=978-1470184841&title=Metamorphosis&author=Franz Kafka&price=5.90" localhost:8080/books/create/process +``` \ No newline at end of file diff --git a/045-code-organization/03_multiple-packages/books/handlers.go b/045-code-organization/03_multiple-packages/books/handlers.go new file mode 100644 index 00000000..79bd49c9 --- /dev/null +++ b/045-code-organization/03_multiple-packages/books/handlers.go @@ -0,0 +1,109 @@ +package books + +import ( + "database/sql" + "github.com/GoesToEleven/golang-web-dev/045-code-organization/03_multiple-packages/config" + "net/http" +) + +func Index(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bks, err := AllBooks() + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + config.TPL.ExecuteTemplate(w, "books.gohtml", bks) +} + +func Show(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := OneBook(r) + switch { + case err == sql.ErrNoRows: + http.NotFound(w, r) + return + case err != nil: + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + config.TPL.ExecuteTemplate(w, "show.gohtml", bk) +} + +func Create(w http.ResponseWriter, r *http.Request) { + config.TPL.ExecuteTemplate(w, "create.gohtml", nil) +} + +func CreateProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := PutBook(r) + if err != nil { + http.Error(w, http.StatusText(406), http.StatusNotAcceptable) + return + } + + config.TPL.ExecuteTemplate(w, "created.gohtml", bk) +} + +func Update(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := OneBook(r) + switch { + case err == sql.ErrNoRows: + http.NotFound(w, r) + return + case err != nil: + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + config.TPL.ExecuteTemplate(w, "update.gohtml", bk) +} + +func UpdateProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := UpdateBook(r) + if err != nil { + http.Error(w, http.StatusText(406), http.StatusBadRequest) + return + } + + config.TPL.ExecuteTemplate(w, "updated.gohtml", bk) +} + +func DeleteProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + err := DeleteBook(r) + if err != nil { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + http.Redirect(w, r, "/books", http.StatusSeeOther) +} diff --git a/045-code-organization/03_multiple-packages/books/models.go b/045-code-organization/03_multiple-packages/books/models.go new file mode 100644 index 00000000..c8e09e6c --- /dev/null +++ b/045-code-organization/03_multiple-packages/books/models.go @@ -0,0 +1,122 @@ +package books + +import ( + "errors" + "github.com/GoesToEleven/golang-web-dev/045-code-organization/03_multiple-packages/config" + "net/http" + "strconv" +) + +type Book struct { + Isbn string + Title string + Author string + Price float32 +} + +func AllBooks() ([]Book, error) { + rows, err := config.DB.Query("SELECT * FROM books") + if err != nil { + return nil, err + } + defer rows.Close() + + bks := make([]Book, 0) + for rows.Next() { + bk := Book{} + err := rows.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) // order matters + if err != nil { + return nil, err + } + bks = append(bks, bk) + } + if err = rows.Err(); err != nil { + return nil, err + } + return bks, nil +} + +func OneBook(r *http.Request) (Book, error) { + bk := Book{} + isbn := r.FormValue("isbn") + if isbn == "" { + return bk, errors.New("400. Bad Request.") + } + + row := config.DB.QueryRow("SELECT * FROM books WHERE isbn = $1", isbn) + + err := row.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) + if err != nil { + return bk, err + } + + return bk, nil +} + +func PutBook(r *http.Request) (Book, error) { + // get form values + bk := Book{} + bk.Isbn = r.FormValue("isbn") + bk.Title = r.FormValue("title") + bk.Author = r.FormValue("author") + p := r.FormValue("price") + + // validate form values + if bk.Isbn == "" || bk.Title == "" || bk.Author == "" || p == "" { + return bk, errors.New("400. Bad request. All fields must be complete.") + } + + // convert form values + f64, err := strconv.ParseFloat(p, 32) + if err != nil { + return bk, errors.New("406. Not Acceptable. Price must be a number.") + } + bk.Price = float32(f64) + + // insert values + _, err = config.DB.Exec("INSERT INTO books (isbn, title, author, price) VALUES ($1, $2, $3, $4)", bk.Isbn, bk.Title, bk.Author, bk.Price) + if err != nil { + return bk, errors.New("500. Internal Server Error." + err.Error()) + } + return bk, nil +} + +func UpdateBook(r *http.Request) (Book, error) { + // get form values + bk := Book{} + bk.Isbn = r.FormValue("isbn") + bk.Title = r.FormValue("title") + bk.Author = r.FormValue("author") + p := r.FormValue("price") + + if bk.Isbn == "" || bk.Title == "" || bk.Author == "" || p == "" { + return bk, errors.New("400. Bad Request. Fields can't be empty.") + } + + // convert form values + f64, err := strconv.ParseFloat(p, 32) + if err != nil { + return bk, errors.New("406. Not Acceptable. Enter number for price.") + } + bk.Price = float32(f64) + + // insert values + _, err = config.DB.Exec("UPDATE books SET isbn = $1, title=$2, author=$3, price=$4 WHERE isbn=$1;", bk.Isbn, bk.Title, bk.Author, bk.Price) + if err != nil { + return bk, err + } + return bk, nil +} + +func DeleteBook(r *http.Request) error { + isbn := r.FormValue("isbn") + if isbn == "" { + return errors.New("400. Bad Request.") + } + + _, err := config.DB.Exec("DELETE FROM books WHERE isbn=$1;", isbn) + if err != nil { + return errors.New("500. Internal Server Error") + } + return nil +} diff --git a/045-code-organization/03_multiple-packages/config/db.go b/045-code-organization/03_multiple-packages/config/db.go new file mode 100644 index 00000000..ea8f493f --- /dev/null +++ b/045-code-organization/03_multiple-packages/config/db.go @@ -0,0 +1,22 @@ +package config + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" +) + +var DB *sql.DB + +func init() { + var err error + DB, err = sql.Open("postgres", "postgres://bond:password@localhost/bookstore?sslmode=disable") + if err != nil { + panic(err) + } + + if err = DB.Ping(); err != nil { + panic(err) + } + fmt.Println("You connected to your database.") +} diff --git a/045-code-organization/03_multiple-packages/config/tpl.go b/045-code-organization/03_multiple-packages/config/tpl.go new file mode 100644 index 00000000..3be92065 --- /dev/null +++ b/045-code-organization/03_multiple-packages/config/tpl.go @@ -0,0 +1,9 @@ +package config + +import "html/template" + +var TPL *template.Template + +func init() { + TPL = template.Must(template.ParseGlob("templates/*.gohtml")) +} diff --git a/045-code-organization/03_multiple-packages/main.go b/045-code-organization/03_multiple-packages/main.go new file mode 100644 index 00000000..bee5d073 --- /dev/null +++ b/045-code-organization/03_multiple-packages/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "github.com/GoesToEleven/golang-web-dev/045-code-organization/03_multiple-packages/books" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/books", books.Index) + http.HandleFunc("/books/show", books.Show) + http.HandleFunc("/books/create", books.Create) + http.HandleFunc("/books/create/process", books.CreateProcess) + http.HandleFunc("/books/update", books.Update) + http.HandleFunc("/books/update/process", books.UpdateProcess) + http.HandleFunc("/books/delete/process", books.DeleteProcess) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/books", http.StatusSeeOther) +} diff --git a/045-code-organization/03_multiple-packages/templates/books.gohtml b/045-code-organization/03_multiple-packages/templates/books.gohtml new file mode 100644 index 00000000..4aa7046a --- /dev/null +++ b/045-code-organization/03_multiple-packages/templates/books.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + +{{range .}} +

{{.Isbn}} - {{.Title}} - {{.Author}} - {{.Price}} - update - delete

+{{end}} + + + + \ No newline at end of file diff --git a/045-code-organization/03_multiple-packages/templates/create.gohtml b/045-code-organization/03_multiple-packages/templates/create.gohtml new file mode 100644 index 00000000..1d888873 --- /dev/null +++ b/045-code-organization/03_multiple-packages/templates/create.gohtml @@ -0,0 +1,39 @@ + + + + + Create Book + + + + +

Create A New Book

+
+ + + + + + + + + \ No newline at end of file diff --git a/045-code-organization/03_multiple-packages/templates/created.gohtml b/045-code-organization/03_multiple-packages/templates/created.gohtml new file mode 100644 index 00000000..54cf8977 --- /dev/null +++ b/045-code-organization/03_multiple-packages/templates/created.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + + +

Created A New Book

+ +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + \ No newline at end of file diff --git a/045-code-organization/03_multiple-packages/templates/show.gohtml b/045-code-organization/03_multiple-packages/templates/show.gohtml new file mode 100644 index 00000000..445298e5 --- /dev/null +++ b/045-code-organization/03_multiple-packages/templates/show.gohtml @@ -0,0 +1,35 @@ + + + + + Create Book + + + + +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + + \ No newline at end of file diff --git a/045-code-organization/03_multiple-packages/templates/update.gohtml b/045-code-organization/03_multiple-packages/templates/update.gohtml new file mode 100644 index 00000000..bc799ea3 --- /dev/null +++ b/045-code-organization/03_multiple-packages/templates/update.gohtml @@ -0,0 +1,39 @@ + + + + + Create Book + + + + +

Update A Book

+
+ + + + + + + + + \ No newline at end of file diff --git a/045-code-organization/03_multiple-packages/templates/updated.gohtml b/045-code-organization/03_multiple-packages/templates/updated.gohtml new file mode 100644 index 00000000..a435784b --- /dev/null +++ b/045-code-organization/03_multiple-packages/templates/updated.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + + +

Updated Book

+ +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + \ No newline at end of file diff --git a/045-code-organization/README.md b/045-code-organization/README.md new file mode 100644 index 00000000..19896181 --- /dev/null +++ b/045-code-organization/README.md @@ -0,0 +1,30 @@ +# Great reference + +[Alex Edwards Code Organization Article](http://www.alexedwards.net/blog/organising-database-access) + +# Code organization + +How you organize your code depends upon the project and your abilities. + +Do not sacrifice simplicity & readability for brevity & cleverness. + +Your goal should be to write code which is maintainable. This means that an intermediate developer should be able to sit down, read your code, understand it, and work with it. + +# Different Approaches + +## One package + +When needed we can put variables in the package scope + +## Two packages + +We will import the code from the second package when needed + +## Three+ packages with package for config variables + +We will import the code from the config package when needed. The config package will hold variables like DB and TPL + +FYI: there is no global scope in Go +![Scope in Go (credit: Caleb Doxsey)](scope.png) + + diff --git a/045-code-organization/scope.png b/045-code-organization/scope.png new file mode 100644 index 00000000..e5c91700 Binary files /dev/null and b/045-code-organization/scope.png differ diff --git a/046_mongodb/00_about-nosql/README.md b/046_mongodb/00_about-nosql/README.md new file mode 100644 index 00000000..318d25ef --- /dev/null +++ b/046_mongodb/00_about-nosql/README.md @@ -0,0 +1,111 @@ +# NoSQL v SQL + +## Consistency, Availbility, Partitionability (CAP) + +The CAP Theorem says you can have any two of those three. + +### SQL: Consistency & Availability + +SQL doesn't scale well. + +### NoSQL: Availability & Partitionability + +Scales well, however, it is eventual consistent. + +FYI: NoSQL can also be thought of a **schemaless**. You do not define any schema. There is no defining that a table is this way or that way. There is no defining that tables are connected in different ways. With SQL, the schema is imposed by the RDBMS. With schemaless nosql, the schema needs to be imposed by the developer; the developer needs to make it all work. + +## Types + +### Key-Value + +Items are stored as key-value pairs. + +KV dbs usually lack the query capabilities of other nosql dbs. + +You can use KV dbs for memcache, tracking transient data, large object storage. + +![key value](images/dbtype-kv.png) +[source: www.3pillarglobal.com](http://www.3pillarglobal.com/insights/exploring-the-different-types-of-nosql-databases) + +Examples: Redis, Riak + +### Document + +Like a key-value store but the value has greater structure, such as JSON or BSON (binary encoding of JSON). + +**Denormalizing data is common with document dbs**: data that is frequently queried together should be stored together. + +Example: a blog post would have the blog post, comments, and likes all stored together. + +Document dbs have indexing and querying capability (you can look data up by more than just the key). + +You can use document dbs for web apps, data with variable schema, JSON, denormalized data (structures embedded in structures). + +![document store](images/dbtype-doc.png) + +Examples: Mongodb, couchdb + +### Column + +Designed for super huge scale; run on clusters. + +More complicated than key-value and document dbs. + +Data is stored in columns, rather than rows. + +Up to this point, we have been thinking about data storage in terms of rows. RDBMS stores data in rows. Key-value and Document nosql store data in rows (for this key, here is the value). + +With column nosql, data is stored in columns. This has performance gains. + +"Relational databases store all the data in a particular table’s rows together on-disk, making retrieval of a particular row fast. Column-family databases generally serialize all the values of a particular column together on-disk, which makes retrieval of a large amount of a specific attribute fast. This approach lends itself well to aggregate queries and analytics scenarios where you might run range queries over a specific field." [source](http://www.jamesserra.com/archive/2015/04/types-of-nosql-databases/) + +Examples: Big Table (google), Cassandra (facebook), HBase + +Use this if you are creating the next facebook social network, the next google search engine, big science, stock market analysis, writing vast amounts of data quickly and being able to query it. + +### Graph + +Great for interconnected data; relationships: who knows who. + +Stores information about networks such as social relations. + +# MongoDB + +The [world's leading NoSQL database](http://db-engines.com/en/ranking). + +![Ranking of DBs](images/dbranks.png) + +## Mongo --> Database --> Collection --> Document + +A nosql database has collections which have documents. +A rdbms database has tables which have records. + +### Document + +A collection of key-value pairs. + +The value is a dynamic schema - it can change from document to document. Documents can have different fields and structure; fields with the same name in different documents can hold different types of data. + +| RDBMS | MongoDB | +|--- | --- | +| database | database | +| table | collection | +| row | document | +| field | field | +| join | embed | +| primary key | default key _id provided by mongo | + +## advantages over RDBMS + +1. documents can vary +1. store objects as they are in your program +1. you don't have to do join queries +1. scalability performance + +## data modeling + +Denormalize your data (combine data that will be used together). Sometimes you hear this referred to as "join on write, not read." + +Having duplicates of stored data can be fine! + + diff --git a/046_mongodb/00_about-nosql/images/dbranks.png b/046_mongodb/00_about-nosql/images/dbranks.png new file mode 100644 index 00000000..684ef875 Binary files /dev/null and b/046_mongodb/00_about-nosql/images/dbranks.png differ diff --git a/046_mongodb/00_about-nosql/images/dbtype-doc.png b/046_mongodb/00_about-nosql/images/dbtype-doc.png new file mode 100644 index 00000000..5b94c1b4 Binary files /dev/null and b/046_mongodb/00_about-nosql/images/dbtype-doc.png differ diff --git a/046_mongodb/00_about-nosql/images/dbtype-kv.png b/046_mongodb/00_about-nosql/images/dbtype-kv.png new file mode 100644 index 00000000..9e6d4b09 Binary files /dev/null and b/046_mongodb/00_about-nosql/images/dbtype-kv.png differ diff --git a/046_mongodb/01_install/README.md b/046_mongodb/01_install/README.md new file mode 100644 index 00000000..5e003bb6 --- /dev/null +++ b/046_mongodb/01_install/README.md @@ -0,0 +1,45 @@ +# install mongo + +[installing mongodb](https://www.mongodb.com/download-center#community) + +## path + +Set a path environment variable pointing to the ```mongod``` program. + +## data folder + +Create a folder for data. + +#### mac +[i am on a mac](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/#install-mongodb-community-edition-manually) + +#### windows +[i am on windows](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/) + +#### linux +[i am on linux](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-linux/) + +# run mongo +``` +mongod +``` + +# use terminal with mongo +``` +mongo +``` + +# stop +``` +ctrl+c +``` + +``` +exit +``` + +# learn more about mongo + +[troubleshooting](https://www.tutorialspoint.com/mongodb/mongodb_environment.htm) + +[mongo university](https://university.mongodb.com/) \ No newline at end of file diff --git a/046_mongodb/02_db/README.md b/046_mongodb/02_db/README.md new file mode 100644 index 00000000..f8237b88 --- /dev/null +++ b/046_mongodb/02_db/README.md @@ -0,0 +1,69 @@ +# db commands + +## create + +``` +use +``` +The above will use the database of the provided name if it exists, and create it if it doesn't + +## use + +``` +use +``` + +#### example +``` +use temp +``` + +The above will use the database of the provided name if it exists, and create it if it doesn't + +## see current db + +``` +db +``` + +## see all db + +``` +show dbs +``` +You need to have at least one document in a db for it to be seen. + +### insert document + +``` +db..insert({"name":"McLeod"}) +``` + +example +``` +db.dogs.insert({"name":"toby"}) +``` + +### view documents +``` +db..find() +``` + +example +``` +db.cats.insert({"firstname":"coco"}) +``` + +``` +db.cats.find().pretty() +``` + +### view collections +``` +show collections +``` + +## drop db +``` +db.dropDatabase() +``` \ No newline at end of file diff --git a/046_mongodb/03_collection/README.md b/046_mongodb/03_collection/README.md new file mode 100644 index 00000000..30b92553 --- /dev/null +++ b/046_mongodb/03_collection/README.md @@ -0,0 +1,39 @@ +# collection commands + +### create implicitly +``` +db..insert({"name":"McLeod"}) +``` + +### create explicitly +``` +db.createCollection(, {}) +``` + +#### optional options +| option | type | description | +| --- | --- | --- | +| capped | bool | caps the size | +| size | number | sets size of cap in bytes | +| max | bool | maximum number of documents allowed in capped collection | + +[other options including validation](https://docs.mongodb.com/manual/reference/method/db.createCollection/) + +#### examples +``` +db.createCollection("customers") +``` + +``` +db.createCollection("crs",{capped:true, size:65536,max:1000000}) +``` + +### view collections +``` +show collections +``` + +### drop +``` +db..drop() +``` \ No newline at end of file diff --git a/046_mongodb/04_document/README.md b/046_mongodb/04_document/README.md new file mode 100644 index 00000000..4a9cc74d --- /dev/null +++ b/046_mongodb/04_document/README.md @@ -0,0 +1,82 @@ +# document commands + +### insert +``` +db..insert({document}) +``` + +### insert multiple +``` +db..insert(< [{document}, {document}, ..., {document}] >) +``` +pass in an array of documents + +#### example +``` +use playroom +``` + +``` +db +``` + +``` +show dbs +``` + +``` +db.crayons.insert([ + { + "hex": "#EFDECD", + "name": "Almond", + "rgb": "(239, 222, 205)" + }, + { + "hex": "#CD9575", + "name": "Antique Brass", + "rgb": "(205, 149, 117)" + }, + { + "hex": "#FDD9B5", + "name": "Apricot", + "rgb": "(253, 217, 181)" + }, + { + "hex": "#78DBE2", + "name": "Aquamarine", + "rgb": "(120, 219, 226)" + }, + { + "hex": "#87A96B", + "name": "Asparagus", + "rgb": "(135, 169, 107)" + }, + { + "hex": "#FFA474", + "name": "Atomic Tangerine", + "rgb": "(255, 164, 116)" + }, + { + "hex": "#FAE7B5", + "name": "Banana Mania", + "rgb": "(250, 231, 181)" + } + ]) +``` +[source of crayon json](https://gist.githubusercontent.com/jjdelc/1868136/raw/c9160b1e60bd8c10c03dbd1a61b704a8e977c46b/crayola.json) + +``` +show collections +``` + +``` +db.crayons.find() +``` + +``` +db.crayons.drop() +``` + +``` +db.dropDatabase() +``` diff --git a/046_mongodb/05_query/README.md b/046_mongodb/05_query/README.md new file mode 100644 index 00000000..88c58a16 --- /dev/null +++ b/046_mongodb/05_query/README.md @@ -0,0 +1,191 @@ +# find (aka, query) + +### setup + +``` +use store +db +show dbs +db.customers.insert([{"role":"double-zero","name": "Bond","age": 32},{"role":"citizen","name": "Moneypenny","age":32},{"role":"citizen","name": "Q","age":67},{"role":"citizen","name": "M","age":57},{"role":"citizen","name": "Dr. No","age":52}]) +``` + +### find +``` +db..find() +db.customers.find() +``` + +### find one +``` +db..findOne() +db.customers.findOne() +``` + +### find specific +``` +db.customers.find({"name":"Bond"}) +db.customers.find({name:"Bond"}) +``` +You can do it either way: ```"name" or name```. JSON specification is to enclose name (object name-value pair) in double qoutes + +### and +``` +db.customers.find({$and: [{name:"Bond"}, {age:32}]}) +db.customers.find({$and: [{name:"Bond"}, {age:{$lt:20}}]}) +db.customers.find({$and: [{name:"Bond"}, {age:{$gt:20}}]}) +``` + +### or +``` +db.customers.find({$or: [{name:"Bond"}, {age:67}]}) +db.customers.find({$or: [{name:"Bond"}, {age:{$lt:20}}]}) +db.customers.find({$or: [{name:"Bond"}, {age:{$gt:32}}]}) +``` + +### and or +``` +db.customers.find({role:"citizen"}) +db.customers.find({age:52}) +db.customers.find({$and: [{role:"citizen"}, {age:52}]}) +db.customers.find({$or: [{role:"citizen"}, {age:52}]}) +db.customers.find({$or: [{role:"citizen"}, {age:52}, {name:"Bond"}]}) +``` + +``` +db.customers.find({$or:[ +{ $and : [ { role : "citizen" }, { age : 32 } ] }, +{ $and : [ { role : "citizen" }, { age : 67 } ] } +]}) +``` + +### regex +``` +db.customers.find({name: {$regex: '^M'}}) +``` + +[regex cheatsheet](regex.pdf) + +### pretty +``` +db..find().pretty() +``` +pretty prints the results + +### operators + +| operator | syntax | example | +| --- | --- | --- | +| equality | {key:value} | db.customers.find({"name":"Bond"}).pretty() | +| less than | {key:{$lt:value}} | db.customers.find({"age":{$lt:20}}).pretty() | +| less than equals | {key:{$lte:value}} | db.customers.find({"age":{$lte:20}}).pretty() | +| greater than | {key:{$gt:value}} | db.customers.find({"age":{$gt:20}}).pretty() | +| greater than equals | {key:{$gte:value}} | db.customers.find({"age":{$gte:20}}).pretty() | +| not equals | {key:{$ne:value}} | db.customers.find({"age":{$ne:20}}).pretty() | + + +# JSON reminder +JavaScript Object Notation (JSON) is a text format for the serialization of structured data. + +It is derived from the object literals of JavaScript. + +JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and arrays) + +#### Primitive JSON + +Here are four small JSON texts containing only values: + +``` +"Hello world!" +42 +true +null +``` + +#### Object JSON + +An object structure is represented as a pair of curly brackets surrounding zero or more **name-value** pairs (or members). + +An object is an unordered collection of zero or more **name:value** pairs + +A **name** is a string + +A **value** is a string, number, boolean, null, object, or array. + +Declare properties using **name:value** pairings separated by commas + +Enclose names in curly braces + +There is no trailing comma + +This is a JSON object: + +``` +{ + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, 38793] + } +} +``` + +#### Array JSON + +An array structure is represented as square brackets surrounding zero or more values (or elements). + +Elements are separated by commas. + +A value must be an + +``` +object +array +number +string +three literal names +true +false +null +``` + +This is a JSON array containing two objects: + + [ + { + "precision": "zip", + "Latitude": 37.7668, + "Longitude": -122.3959, + "Address": "", + "City": "SAN FRANCISCO", + "State": "CA", + "Zip": "94107", + "Country": "US" + }, + { + "precision": "zip", + "Latitude": 37.371991, + "Longitude": -122.026020, + "Address": "", + "City": "SUNNYVALE", + "State": "CA", + "Zip": "94085", + "Country": "US" + } + ] + +#### Number + +The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. A fraction part is a decimal point followed by one or more digits. + +#### String + +The representation of strings is similar to conventions used in the C family of programming languages. A string begins and ends with **double quotation marks**. + +source: The Internet Engineering Task Force (IETF) \ No newline at end of file diff --git a/046_mongodb/05_query/regex.pdf b/046_mongodb/05_query/regex.pdf new file mode 100644 index 00000000..aab4eef4 Binary files /dev/null and b/046_mongodb/05_query/regex.pdf differ diff --git a/046_mongodb/06_update/README.md b/046_mongodb/06_update/README.md new file mode 100644 index 00000000..5345e38c --- /dev/null +++ b/046_mongodb/06_update/README.md @@ -0,0 +1,66 @@ +# update & save + +update will update a record + +save will overwrite a record + +### update +``` +db..update(, , ) +``` + +example +``` +db.customers.find() +``` + +gives this data +``` +{ "_id" : ObjectId("5891221756867ebff44cc885"), "role" : "double-zero", "name" : "Bond", "age" : 32 } +{ "_id" : ObjectId("5891221756867ebff44cc886"), "role" : "citizen", "name" : "Moneypenny", "age" : 32 } +{ "_id" : ObjectId("5891221756867ebff44cc887"), "role" : "citizen", "name" : "Q", "age" : 67 } +{ "_id" : ObjectId("5891221756867ebff44cc888"), "role" : "citizen", "name" : "M", "age" : 57 } +{ "_id" : ObjectId("5891221756867ebff44cc889"), "role" : "citizen", "name" : "Dr. No", "age" : 52 } +``` + +update like this +``` +db.customers.update({_id:ObjectId("5891221756867ebff44cc886")},{$set:{role:"double-zero"}}) +``` + +``` +db.customers.update({name:"Moneypenny"},{$set:{role:"double-zero"}}) +``` + +``` +db.customers.update({name:"Moneypenny"},{$set:{role:"citizen", name: "Miss Moneypenny"}}) +``` + +``` +db.customers.update({age:{$gt:35}},{$set:{role:"double-zero"}}) +``` + +``` +db.customers.update({age:{$gt:35}},{$set:{role:"double-zero"}}, {multi:true}) +``` +[see options](https://docs.mongodb.com/manual/reference/method/db.collection.update/) + +``` +db.customers.update({},{$set:{role:"citizen"}}, {multi:true}) +``` +[see query documentation](https://docs.mongodb.com/manual/tutorial/query-documents/) + +("5893888012acb8ada532a8e4" + +### save +``` +db.customers.save({"role":"villain","name":"Jaws","age":43}) +``` + +``` +db.customers.save({"_id":ObjectId("5891221756867ebff44cc889"),"role":"villain","name":"Goldfinger","age":77}) +``` + +``` +db.customers.save({"_id":ObjectId("5893888012acb8ada532a8e4"),"role":"villain","name":"PussyGalore","age":31}) +``` \ No newline at end of file diff --git a/046_mongodb/07_remove/README.md b/046_mongodb/07_remove/README.md new file mode 100644 index 00000000..427eb37c --- /dev/null +++ b/046_mongodb/07_remove/README.md @@ -0,0 +1,33 @@ +# remove document + +``` +db..remove() +db.customers.remove({role:"double-zero"}) +db.customers.remove({role:"villain"}) +``` +removes all it matches + +### remove only 1 +``` +db.customers.remove({role:"citizen"},1) +``` + +### remove +``` +db.customers.remove({role:"citizen"}) +``` + +### put documents back +``` +db.customers.insert([{"role":"double-zero","name": "Bond","age": 32},{"role":"citizen","name": "Moneypenny","age":32},{"role":"citizen","name": "Q","age":67},{"role":"citizen","name": "M","age":57},{"role":"citizen","name": "Dr. No","age":52}]) +``` + +### remove all +``` +db.customers.remove({}) +``` + +### put documents back +``` +db.customers.insert([{"role":"double-zero","name": "Bond","age": 32},{"role":"citizen","name": "Moneypenny","age":32},{"role":"citizen","name": "Q","age":67},{"role":"citizen","name": "M","age":57},{"role":"citizen","name": "Dr. No","age":52}]) +``` \ No newline at end of file diff --git a/046_mongodb/08_projection/README.md b/046_mongodb/08_projection/README.md new file mode 100644 index 00000000..ff9b4d60 --- /dev/null +++ b/046_mongodb/08_projection/README.md @@ -0,0 +1,19 @@ +# projection +Retrieving part of a document; only some of the fields. + +``` +db..find(,) +``` + +``` +db.customers.find({},{_id:0,name:1,}) +``` +_id is displayed by default; turn off with 0 + +``` +db.customers.find({},{_id:0,name:1,age:1}) +``` + +``` +db.customers.find({age:{$gt:32}},{_id:0,name:1,age:1}) +``` \ No newline at end of file diff --git a/046_mongodb/09_limit/README.md b/046_mongodb/09_limit/README.md new file mode 100644 index 00000000..b7db188a --- /dev/null +++ b/046_mongodb/09_limit/README.md @@ -0,0 +1,56 @@ +# limit + +### setup + +``` +db.crayons.insert([ + { + "hex": "#EFDECD", + "name": "Almond", + "rgb": "(239, 222, 205)" + }, + { + "hex": "#CD9575", + "name": "Antique Brass", + "rgb": "(205, 149, 117)" + }, + { + "hex": "#FDD9B5", + "name": "Apricot", + "rgb": "(253, 217, 181)" + }, + { + "hex": "#78DBE2", + "name": "Aquamarine", + "rgb": "(120, 219, 226)" + }, + { + "hex": "#87A96B", + "name": "Asparagus", + "rgb": "(135, 169, 107)" + }, + { + "hex": "#FFA474", + "name": "Atomic Tangerine", + "rgb": "(255, 164, 116)" + }, + { + "hex": "#FAE7B5", + "name": "Banana Mania", + "rgb": "(250, 231, 181)" + } + ]) +``` + +### limit +``` +db..find().limit(n) +``` + +``` +db.crayons.find().limit(3) +``` + +``` +db.customers.find({age:{$gt:32}},{_id:0,name:1,age:1}).limit(2) +``` \ No newline at end of file diff --git a/046_mongodb/10_sort/README.md b/046_mongodb/10_sort/README.md new file mode 100644 index 00000000..998f0ad8 --- /dev/null +++ b/046_mongodb/10_sort/README.md @@ -0,0 +1,788 @@ +# sort + +Run **setup** below first + +``` +db..find().sort(:<1 for ascend, -1 descend>) +``` + +``` +db.oscars.find().limit(10) +db.oscars.find({},{_id:0,year:1,title:1}).limit(10) +db.oscars.find({},{_id:0,year:1,title:1}).limit(10).sort({title:1}) +db.oscars.find({},{_id:0,year:1,title:1}).sort({title:1}).limit(10) +db.oscars.find({},{_id:0,year:1,title:1}).limit(10).sort({title:-1}) +db.oscars.find({releaseYear:{$gt:1970}},{_id:0,year:1,title:1}).limit(10).sort({title:1}) +db.oscars.find({releaseYear:{$gt:1980}},{_id:0,year:1,title:1}) +``` + + +### setup +``` +db.oscars.insert([ + { "year": "1927", + "title": "Wings", + "imdbId": "tt0018578", + "releaseDate": "1927-05-19T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1927, + "releaseMonth": 4, + "releaseDay": 19 + }, + { "year": "1929", + "title": "The Broadway Melody", + "imdbId": "tt0019729", + "releaseDate": "1929-02-01T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1929, + "releaseMonth": 1, + "releaseDay": 1 + }, + { "year": "1930", + "title": "All Quiet on the Western Front", + "imdbId": "tt0020629", + "releaseDate": "1930-04-21T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1930, + "releaseMonth": 3, + "releaseDay": 21 + }, + { "year": "1931", + "title": "Cimarron", + "imdbId": "tt0021746", + "releaseDate": "1931-01-26T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1931, + "releaseMonth": 0, + "releaseDay": 26 + }, + { "year": "1932", + "title": "Grand Hotel", + "imdbId": "tt0022958", + "releaseDate": "1932-04-12T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1932, + "releaseMonth": 3, + "releaseDay": 12 + }, + { "year": "1933", + "title": "Cavalcade", + "imdbId": "tt0023876", + "releaseDate": "1933-01-05T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1933, + "releaseMonth": 0, + "releaseDay": 5 + }, + { "year": "1934", + "title": "It Happened One Night", + "imdbId": "tt0025316", + "releaseDate": "1934-02-22T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1934, + "releaseMonth": 1, + "releaseDay": 22 + }, + { "year": "1935", + "title": "Mutiny on the Bounty", + "imdbId": "tt0026752", + "releaseDate": "1935-11-08T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1935, + "releaseMonth": 10, + "releaseDay": 8 + }, + { "year": "1936", + "title": "The Great Ziegfeld", + "imdbId": "tt0027698", + "releaseDate": "1936-03-22T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1936, + "releaseMonth": 2, + "releaseDay": 22 + }, + { "year": "1937", + "title": "The Life of Emile Zola", + "imdbId": "tt0029146", + "releaseDate": "1937-08-11T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1937, + "releaseMonth": 7, + "releaseDay": 11 + }, + { "year": "1938", + "title": "You Can't Take It with You", + "imdbId": "tt0030993", + "releaseDate": "1938-08-23T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1938, + "releaseMonth": 7, + "releaseDay": 23 + }, + { "year": "1939", + "title": "Gone with the Wind", + "imdbId": "tt0031381", + "releaseDate": "1939-12-28T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1939, + "releaseMonth": 11, + "releaseDay": 28 + }, + { "year": "1940", + "title": "Rebecca", + "imdbId": "tt0032976", + "releaseDate": "1940-03-27T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1940, + "releaseMonth": 2, + "releaseDay": 27 + }, + { "year": "1941", + "title": "How Green Was My Valley", + "imdbId": "tt0033729", + "releaseDate": "1941-10-28T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1941, + "releaseMonth": 9, + "releaseDay": 28 + }, + { "year": "1942", + "title": "Mrs. Miniver", + "imdbId": "tt0035093", + "releaseDate": "1942-07-22T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1942, + "releaseMonth": 6, + "releaseDay": 22 + }, + { "year": "1943", + "title": "Casablanca", + "imdbId": "tt0034583", + "releaseDate": "1942-11-26T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1942, + "releaseMonth": 10, + "releaseDay": 26 + }, + { "year": "1944", + "title": "Going My Way", + "imdbId": "tt0036872", + "releaseDate": "1944-08-16T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1944, + "releaseMonth": 7, + "releaseDay": 16 + }, + { "year": "1945", + "title": "The Lost Weekend", + "imdbId": "tt0037884", + "releaseDate": "1945-11-29T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1945, + "releaseMonth": 10, + "releaseDay": 29 + }, + { "year": "1946", + "title": "The Best Years of Our Lives", + "imdbId": "tt0036868", + "releaseDate": "1946-12-25T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1946, + "releaseMonth": 11, + "releaseDay": 25 + }, + { "year": "1947", + "title": "Gentleman's Agreement", + "imdbId": "tt0039416", + "releaseDate": "1947-11-11T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1947, + "releaseMonth": 10, + "releaseDay": 11 + }, + { "year": "1948", + "title": "Hamlet", + "imdbId": "tt0040416", + "releaseDate": "1948-10-27T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1948, + "releaseMonth": 9, + "releaseDay": 27 + }, + { "year": "1949", + "title": "All the Kings Men", + "imdbId": "tt0041113", + "releaseDate": "1949-11-08T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1949, + "releaseMonth": 10, + "releaseDay": 8 + }, + { "year": "1950", + "title": "All About Eve", + "imdbId": "tt0042192", + "releaseDate": "1950-10-13T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1950, + "releaseMonth": 9, + "releaseDay": 13 + }, + { "year": "1951", + "title": "An American in Paris", + "imdbId": "tt0043278", + "releaseDate": "1951-10-04T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1951, + "releaseMonth": 9, + "releaseDay": 4 + }, + { "year": "1952", + "title": "The Greatest Show on Earth", + "imdbId": "tt0044672", + "releaseDate": "1952-01-10T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1952, + "releaseMonth": 0, + "releaseDay": 10 + }, + { "year": "1953", + "title": "From Here to Eternity", + "imdbId": "tt0045793", + "releaseDate": "1953-09-30T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1953, + "releaseMonth": 8, + "releaseDay": 30 + }, + { "year": "1954", + "title": "On the Waterfront", + "imdbId": "tt0047296", + "releaseDate": "1954-07-28T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1954, + "releaseMonth": 6, + "releaseDay": 28 + }, + { "year": "1955", + "title": "Marty", + "imdbId": "tt0048356", + "releaseDate": "1955-07-15T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1955, + "releaseMonth": 6, + "releaseDay": 15 + }, + { "year": "1956", + "title": "Around the World in 80 Days", + "imdbId": "tt0048960", + "releaseDate": "1956-12-22T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1956, + "releaseMonth": 11, + "releaseDay": 22 + }, + { "year": "1957", + "title": "The Bridge on the River Kwai", + "imdbId": "tt0050212", + "releaseDate": "1957-12-19T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1957, + "releaseMonth": 11, + "releaseDay": 19 + }, + { "year": "1958", + "title": "Gigi", + "imdbId": "tt0051658", + "releaseDate": "1958-07-10T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1958, + "releaseMonth": 6, + "releaseDay": 10 + }, + { "year": "1959", + "title": "Ben-Hur", + "imdbId": "tt0052618", + "releaseDate": "1959-11-18T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1959, + "releaseMonth": 10, + "releaseDay": 18 + }, + { "year": "1960", + "title": "The Apartment", + "imdbId": "tt0053604", + "releaseDate": "1960-06-21T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1960, + "releaseMonth": 5, + "releaseDay": 21 + }, + { "year": "1961", + "title": "West Side Story", + "imdbId": "tt0055614", + "releaseDate": "1961-12-13T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1961, + "releaseMonth": 11, + "releaseDay": 13 + }, + { "year": "1962", + "title": "Lawrence of Arabia", + "imdbId": "tt0056172", + "releaseDate": "1962-12-21T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1962, + "releaseMonth": 11, + "releaseDay": 21 + }, + { "year": "1963", + "title": "Tom Jones", + "imdbId": "tt0057590", + "releaseDate": "1963-10-24T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1963, + "releaseMonth": 9, + "releaseDay": 24 + }, + { "year": "1964", + "title": "My Fair Lady", + "imdbId": "tt0058385", + "releaseDate": "1964-10-28T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1964, + "releaseMonth": 9, + "releaseDay": 28 + }, + { "year": "1965", + "title": "The Sound of Music", + "imdbId": "tt0059742", + "releaseDate": "1965-03-10T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1965, + "releaseMonth": 2, + "releaseDay": 10 + }, + { "year": "1966", + "title": "A Man for All Seasons", + "imdbId": "tt0060665", + "releaseDate": "1966-12-14T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1966, + "releaseMonth": 11, + "releaseDay": 14 + }, + { "year": "1967", + "title": "In the Heat of the Night", + "imdbId": "tt0061811", + "releaseDate": "1967-08-23T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1967, + "releaseMonth": 7, + "releaseDay": 23 + }, + { "year": "1968", + "title": "Oliver!", + "imdbId": "tt0063385", + "releaseDate": "1968-12-20T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1968, + "releaseMonth": 11, + "releaseDay": 20 + }, + { "year": "1969", + "title": "Midnight Cowboy", + "imdbId": "tt0064665", + "releaseDate": "1969-05-25T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1969, + "releaseMonth": 4, + "releaseDay": 25 + }, + { "year": "1970", + "title": "Patton", + "imdbId": "tt0066206", + "releaseDate": "1970-02-18T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1970, + "releaseMonth": 1, + "releaseDay": 18 + }, + { "year": "1971", + "title": "The French Connection", + "imdbId": "tt0067116", + "releaseDate": "1971-10-07T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1971, + "releaseMonth": 9, + "releaseDay": 7 + }, + { "year": "1972", + "title": "The Godfather", + "imdbId": "tt0068646", + "releaseDate": "1972-03-22T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1972, + "releaseMonth": 2, + "releaseDay": 22 + }, + { "year": "1973", + "title": "The Sting", + "imdbId": "tt0070735", + "releaseDate": "1973-12-25T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1973, + "releaseMonth": 11, + "releaseDay": 25 + }, + { "year": "1974", + "title": "The Godfather Part II", + "imdbId": "tt0071562", + "releaseDate": "1974-12-18T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1974, + "releaseMonth": 11, + "releaseDay": 18 + }, + { "year": "1975", + "title": "One Flew over the Cuckoo's Nest", + "imdbId": "tt0073486", + "releaseDate": "1975-11-19T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1975, + "releaseMonth": 10, + "releaseDay": 19 + }, + { "year": "1976", + "title": "Rocky", + "imdbId": "tt0075148", + "releaseDate": "1976-11-21T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1976, + "releaseMonth": 10, + "releaseDay": 21 + }, + { "year": "1977", + "title": "Annie Hall", + "imdbId": "tt0075686", + "releaseDate": "1977-04-20T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1977, + "releaseMonth": 3, + "releaseDay": 20 + }, + { "year": "1978", + "title": "The Deer Hunter", + "imdbId": "tt0077416", + "releaseDate": "1978-12-08T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1978, + "releaseMonth": 11, + "releaseDay": 8 + }, + { "year": "1979", + "title": "Kramer vs. Kramer", + "imdbId": "tt0079417", + "releaseDate": "1979-12-19T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1979, + "releaseMonth": 11, + "releaseDay": 19 + }, + { "year": "1980", + "title": "Ordinary People", + "imdbId": "tt0081283", + "releaseDate": "1980-09-26T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1980, + "releaseMonth": 8, + "releaseDay": 26 + }, + { "year": "1981", + "title": "Chariots of Fire", + "imdbId": "tt0082158", + "releaseDate": "1981-10-09T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1981, + "releaseMonth": 9, + "releaseDay": 9 + }, + { "year": "1982", + "title": "Gandhi", + "imdbId": "tt0083987", + "releaseDate": "1982-12-07T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1982, + "releaseMonth": 11, + "releaseDay": 7 + }, + { "year": "1983", + "title": "Terms of Endearment", + "imdbId": "tt0086425", + "releaseDate": "1983-11-20T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1983, + "releaseMonth": 10, + "releaseDay": 20 + }, + { "year": "1984", + "title": "Amadeus", + "imdbId": "tt0086879", + "releaseDate": "1984-09-06T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1984, + "releaseMonth": 8, + "releaseDay": 6 + }, + { "year": "1985", + "title": "Out of Africa", + "imdbId": "tt0089755", + "releaseDate": "1985-12-10T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1985, + "releaseMonth": 11, + "releaseDay": 10 + }, + { "year": "1986", + "title": "Platoon", + "imdbId": "tt0091763", + "releaseDate": "1986-12-19T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1986, + "releaseMonth": 11, + "releaseDay": 19 + }, + { "year": "1987", + "title": "The Last Emperor", + "imdbId": "tt0093389", + "releaseDate": "1987-11-19T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1987, + "releaseMonth": 10, + "releaseDay": 19 + }, + { "year": "1988", + "title": "Rain Man", + "imdbId": "tt0095953", + "releaseDate": "1988-12-14T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1988, + "releaseMonth": 11, + "releaseDay": 14 + }, + { "year": "1989", + "title": "Driving Miss Daisy", + "imdbId": "tt0097239", + "releaseDate": "1989-12-15T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1989, + "releaseMonth": 11, + "releaseDay": 15 + }, + { "year": "1990", + "title": "Dances With Wolves", + "imdbId": "tt0099348", + "releaseDate": "1990-10-19T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1990, + "releaseMonth": 9, + "releaseDay": 19 + }, + { "year": "1991", + "title": "The Silence of the Lambs", + "imdbId": "tt0102926", + "releaseDate": "1991-01-30T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1991, + "releaseMonth": 0, + "releaseDay": 30 + }, + { "year": "1992", + "title": "Unforgiven", + "imdbId": "tt0105695", + "releaseDate": "1992-08-03T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1992, + "releaseMonth": 7, + "releaseDay": 3 + }, + { "year": "1993", + "title": "Schindler's List", + "imdbId": "tt0108052", + "releaseDate": "1993-11-30T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1993, + "releaseMonth": 10, + "releaseDay": 30 + }, + { "year": "1994", + "title": "Forrest Gump", + "imdbId": "tt0109830", + "releaseDate": "1994-06-23T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1994, + "releaseMonth": 5, + "releaseDay": 23 + }, + { "year": "1995", + "title": "Braveheart", + "imdbId": "tt0112573", + "releaseDate": "1995-05-19T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1995, + "releaseMonth": 4, + "releaseDay": 19 + }, + { "year": "1996", + "title": "The English Patient", + "imdbId": "tt0116209", + "releaseDate": "1996-11-12T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1996, + "releaseMonth": 10, + "releaseDay": 12 + }, + { "year": "1997", + "title": "Titanic", + "imdbId": "tt0120338", + "releaseDate": "1997-12-14T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1997, + "releaseMonth": 11, + "releaseDay": 14 + }, + { "year": "1998", + "title": "Shakespeare in Love", + "imdbId": "tt0138097", + "releaseDate": "1998-12-08T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1998, + "releaseMonth": 11, + "releaseDay": 8 + }, + { "year": "1999", + "title": "American Beauty", + "imdbId": "tt0169547", + "releaseDate": "1999-09-08T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1999, + "releaseMonth": 8, + "releaseDay": 8 + }, + { "year": "2000", + "title": "Gladiator", + "imdbId": "tt0172495", + "releaseDate": "2000-05-01T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2000, + "releaseMonth": 4, + "releaseDay": 1 + }, + { "year": "2001", + "title": "A Beautiful Mind", + "imdbId": "tt0268978", + "releaseDate": "2001-12-13T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2001, + "releaseMonth": 11, + "releaseDay": 13 + }, + { "year": "2002", + "title": "Chicago", + "imdbId": "tt0299658", + "releaseDate": "2002-12-18T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2002, + "releaseMonth": 11, + "releaseDay": 18 + }, + { "year": "2003", + "title": "The Lord of the Rings: The Return of the King", + "imdbId": "tt0167260", + "releaseDate": "2003-12-17T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2003, + "releaseMonth": 11, + "releaseDay": 17 + }, + { "year": "2004", + "title": "Million Dollar Baby", + "imdbId": "tt0405159", + "releaseDate": "2004-12-15T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2004, + "releaseMonth": 11, + "releaseDay": 15 + }, + { "year": "2005", + "title": "Crash", + "imdbId": "tt0375679", + "releaseDate": "2005-04-26T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2005, + "releaseMonth": 3, + "releaseDay": 26 + }, + { "year": "2006", + "title": "The Departed", + "imdbId": "tt0407887", + "releaseDate": "2006-09-26T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2006, + "releaseMonth": 8, + "releaseDay": 26 + }, + { "year": "2007", + "title": "No Country for Old Men", + "imdbId": "tt0477348", + "releaseDate": "2007-11-04T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2007, + "releaseMonth": 10, + "releaseDay": 4 + }, + { "year": "2008", + "title": "Slumdog Millionaire", + "imdbId": "tt1010048", + "releaseDate": "2008-11-12T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2008, + "releaseMonth": 10, + "releaseDay": 12 + }, + { "year": "2009", + "title": "The Hurt Locker", + "imdbId": "tt1655246", + "releaseDate": "2009-01-29T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2009, + "releaseMonth": 0, + "releaseDay": 29 + }, + { "year": "2010", + "title": "The King's Speech", + "imdbId": "tt1504320", + "releaseDate": "2010-12-24T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2010, + "releaseMonth": 11, + "releaseDay": 24 + }, + { "year": "2011", + "title": "The Artist", + "imdbId": "tt1655442", + "releaseDate": "2011-11-23T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2011, + "releaseMonth": 10, + "releaseDay": 23 + }, + { "year": "2012", + "title": "Argo", + "imdbId": "tt1024648", + "releaseDate": "2012-10-04T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2012, + "releaseMonth": 9, + "releaseDay": 4 + }]) +``` \ No newline at end of file diff --git a/046_mongodb/11_index/README.md b/046_mongodb/11_index/README.md new file mode 100644 index 00000000..432a34db --- /dev/null +++ b/046_mongodb/11_index/README.md @@ -0,0 +1,17 @@ +# create index + +``` +db..createIndex({:<1 for ascend, -1 descend>}) +``` + +create index +``` +db.oscars.createIndex({title:1}) +``` + +see indexes +``` +db.oscars.getIndexes() +``` + +[learn to create a unique index and more](https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/#db.collection.createIndex) \ No newline at end of file diff --git a/046_mongodb/12_aggregate/README.md b/046_mongodb/12_aggregate/README.md new file mode 100644 index 00000000..df1028a7 --- /dev/null +++ b/046_mongodb/12_aggregate/README.md @@ -0,0 +1,102 @@ +# aggregate + +Aggregations operations process data records and return computed results. Aggregation operations group values from multiple documents together, and can perform a variety of operations on the grouped data to return a single result. MongoDB provides three ways to perform aggregation: the aggregation pipeline, the map-reduce function, and single purpose aggregation methods. + +[documenation about aggregation](https://docs.mongodb.com/manual/aggregation/) + +## single purpose aggregation + +[documenation about single purpose aggregation](https://docs.mongodb.com/manual/aggregation/#single-purpose-agg-operations) + +There are two functions you can use: + +#### [db.collection.count()](https://docs.mongodb.com/manual/reference/method/db.collection.count/#db.collection.count) + +#### [db.collection.distinct()](https://docs.mongodb.com/manual/reference/method/db.collection.distinct/#db.collection.distinct) + +``` +db.collection.distinct(field, query, options) +``` + +| Parameter | Description | +| --- | --- | +| field | The field for which to return distinct values. +| query | A query that specifies the documents from which to retrieve the distinct values. +| options | Optional. A document that specifies the options. See Options. + +#### examples - count() +``` +db.oscars.count() +``` + +``` +db.oscars.find().count() +``` + +``` +db.customers.find({role:"citizen"}).count() +``` + +``` +db.customers.find({$or: [{name:"Bond"}, {age:{$gt:32}}]}).count() +``` + +#### examples - distinct() - setup +``` +db.inventory.insert([ +{ "_id": 1, "dept": "A", "item": { "sku": "111", "color": "red" }, "sizes": [ "S", "M" ] }, +{ "_id": 2, "dept": "A", "item": { "sku": "111", "color": "blue" }, "sizes": [ "M", "L" ] }, +{ "_id": 3, "dept": "B", "item": { "sku": "222", "color": "blue" }, "sizes": "S" }, +{ "_id": 4, "dept": "A", "item": { "sku": "333", "color": "black" }, "sizes": [ "S" ] } +]) +``` + +#### examples - distinct() + +``` +db.inventory.distinct( "dept" ) +``` + +``` +db.inventory.distinct( "item.sku" ) +``` + +``` +db.inventory.distinct( "sizes" ) +``` + +## aggregation pipeline + +![aggregate pipeline](aggregate.png) + +``` +db..aggregate([{},{}]) +``` + +MongoDB’s aggregation framework is modeled on the concept of data processing pipelines. Documents enter a multi-stage pipeline that transforms the documents into an aggregated result. + +The most basic pipeline stages provide filters that operate like queries and document transformations that modify the form of the output document. + +Other pipeline operations provide tools for grouping and sorting documents by specific field or fields as well as tools for aggregating the contents of arrays, including arrays of documents. In addition, pipeline stages can use operators for tasks such as calculating the average or concatenating a string. + +The pipeline provides efficient data aggregation using native operations within MongoDB, and is the preferred method for data aggregation in MongoDB. + +[source](https://docs.mongodb.com/manual/aggregation/) + +#### example - setup +``` +db.orders.insert([ +{"cust_id":"A123","amount":500,"status":"A"}, +{"cust_id":"A123","amount":250,"status":"A"}, +{"cust_id":"B212","amount":200,"status":"A"}, +{"cust_id":"A123","amount":300,"status":"D"} +]) +``` + +#### example +``` +db.orders.aggregate([ +{$match:{status:"A"}}, +{$group:{_id: "$cust_id",total: {$sum:"$amount"}}} +]) +``` \ No newline at end of file diff --git a/046_mongodb/12_aggregate/aggregate.png b/046_mongodb/12_aggregate/aggregate.png new file mode 100644 index 00000000..0532a20d Binary files /dev/null and b/046_mongodb/12_aggregate/aggregate.png differ diff --git a/046_mongodb/13_additional/README.md b/046_mongodb/13_additional/README.md new file mode 100644 index 00000000..25eb3f59 --- /dev/null +++ b/046_mongodb/13_additional/README.md @@ -0,0 +1,4 @@ +# Learning more about mongo + +[relationships, deployment, sharding, replication, and more](https://www.tutorialspoint.com/mongodb/mongodb_relationships.htm) + diff --git a/046_mongodb/14_users/README.md b/046_mongodb/14_users/README.md new file mode 100644 index 00000000..17def2d5 --- /dev/null +++ b/046_mongodb/14_users/README.md @@ -0,0 +1,110 @@ +# locking down your database + +## create admin super user + +``` +use admin +db.createUser( + { + user: "jamesbond", + pwd: "moneypennyrocks007sworld", + roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] + } +) +``` + +[built in user roles](https://docs.mongodb.com/manual/reference/built-in-roles/) + +#### exit mongo & then start again +``` +mongod --auth +``` + +``` +mongo -u "jamesbond" -p "moneypennyrocks007sworld" --authenticationDatabase "admin" +``` + +#### see current user + +``` +db.runCommand({connectionStatus : 1}) +``` + +## create regular user +Give this user readwrite permissions on the ```store``` db. + +``` +db.createUser( + { + user: "bond", + pwd: "moneypenny007", + roles: [ { role: "readWrite", db: "store" } ] + } +) +``` + +#### exit mongo & then start again +``` +mongod --auth +``` + +``` +mongo -u "bond" -p "moneypenny007" --authenticationDatabase "store" +``` + +#### see current user + +``` +db.runCommand({connectionStatus : 1}) +``` + +#### lock down the database + +[enable auth](https://docs.mongodb.com/master/tutorial/enable-authentication/) + +[getting auth running on mongo](https://docs.mongodb.com/manual/tutorial/enable-authentication/) + +#### exit mongo & then start again with auth enabled +``` +mongod --auth +``` + +``` +mongo -u "bond" -p "moneypenny007" --authenticationDatabase "store" +``` + +#### test + +``` +use store +``` + +``` +show collections +``` + +``` +db.customers.find() +``` + +``` +db.customers.insert({"role" : "double-zero", "name" : "Elon Musk", "age" : 47 }) +``` + +#### test + +launch a new terminal window + +``` +mongo +``` + +should be unauthorized: +``` +show collections +``` + +#### drop user +``` +db.dropUser("") +``` \ No newline at end of file diff --git a/046_mongodb/15_postgres/README.md b/046_mongodb/15_postgres/README.md new file mode 100644 index 00000000..55203c6d --- /dev/null +++ b/046_mongodb/15_postgres/README.md @@ -0,0 +1,30 @@ +# THIS IS POSTGRES + +We are going to rebuild our postgres example using mongo instead. + +First we need to extract our the records from the books table in our bookstore database. + +The code in **this folder** has a new route which will give you the following json: + +``` +[{"Isbn":"978-1505255607","Title":"The Time Machine","Author":"H. G. Wells","Price":5.99},{"Isbn":"978-1503261960","Title":"Wind Sand \u0026 Stars","Author":"Antoine","Price":14.99},{"Isbn":"978-1503261961","Title":"West With The Night","Author":"Beryl Markham","Price":14.99}] +``` + +notice \u0026 + +That is valid JSON encoding. That is the unicode escape. & doesn't have to be encoded, but Go does this so we can just let it be. JSON encoders / decoders know how to deal with it. + +# To see this JSON output + +### turn on postgres +Make sure postgres is on. + +### run your server +``` +go run *.go +``` + +### get the json of the books +``` +curl -i localhost:8080/books/json +``` \ No newline at end of file diff --git a/046_mongodb/15_postgres/books/handlers.go b/046_mongodb/15_postgres/books/handlers.go new file mode 100644 index 00000000..cc4df487 --- /dev/null +++ b/046_mongodb/15_postgres/books/handlers.go @@ -0,0 +1,132 @@ +package books + +import ( + "database/sql" + "encoding/json" + "fmt" + "github.com/GoesToEleven/golang-web-dev/046_mongodb/15_postgres/config" + "net/http" +) + +func Index(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bks, err := AllBooks() + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + config.TPL.ExecuteTemplate(w, "books.gohtml", bks) +} + +func Show(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := OneBook(r) + switch { + case err == sql.ErrNoRows: + http.NotFound(w, r) + return + case err != nil: + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + config.TPL.ExecuteTemplate(w, "show.gohtml", bk) +} + +func Create(w http.ResponseWriter, r *http.Request) { + config.TPL.ExecuteTemplate(w, "create.gohtml", nil) +} + +func CreateProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := PutBook(r) + if err != nil { + http.Error(w, http.StatusText(406), http.StatusNotAcceptable) + return + } + + config.TPL.ExecuteTemplate(w, "created.gohtml", bk) +} + +func Update(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := OneBook(r) + switch { + case err == sql.ErrNoRows: + http.NotFound(w, r) + return + case err != nil: + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + config.TPL.ExecuteTemplate(w, "update.gohtml", bk) +} + +func UpdateProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := UpdateBook(r) + if err != nil { + http.Error(w, http.StatusText(406), http.StatusBadRequest) + return + } + + config.TPL.ExecuteTemplate(w, "updated.gohtml", bk) +} + +func DeleteProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + err := DeleteBook(r) + if err != nil { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + http.Redirect(w, r, "/books", http.StatusSeeOther) +} + +func ShowJSON(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bks, err := AllBooks() + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + bs, err := json.Marshal(bks) + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + config.TPL.ExecuteTemplate(w, "json.gohtml", string(bs)) +} diff --git a/046_mongodb/15_postgres/books/models.go b/046_mongodb/15_postgres/books/models.go new file mode 100644 index 00000000..fe7d29d7 --- /dev/null +++ b/046_mongodb/15_postgres/books/models.go @@ -0,0 +1,122 @@ +package books + +import ( + "errors" + "github.com/GoesToEleven/golang-web-dev/046_mongodb/15_postgres/config" + "net/http" + "strconv" +) + +type Book struct { + Isbn string + Title string + Author string + Price float32 +} + +func AllBooks() ([]Book, error) { + rows, err := config.DB.Query("SELECT * FROM books") + if err != nil { + return nil, err + } + defer rows.Close() + + bks := make([]Book, 0) + for rows.Next() { + bk := Book{} + err := rows.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) // order matters + if err != nil { + return nil, err + } + bks = append(bks, bk) + } + if err = rows.Err(); err != nil { + return nil, err + } + return bks, nil +} + +func OneBook(r *http.Request) (Book, error) { + bk := Book{} + isbn := r.FormValue("isbn") + if isbn == "" { + return bk, errors.New("400. Bad Request.") + } + + row := config.DB.QueryRow("SELECT * FROM books WHERE isbn = $1", isbn) + + err := row.Scan(&bk.Isbn, &bk.Title, &bk.Author, &bk.Price) + if err != nil { + return bk, err + } + + return bk, nil +} + +func PutBook(r *http.Request) (Book, error) { + // get form values + bk := Book{} + bk.Isbn = r.FormValue("isbn") + bk.Title = r.FormValue("title") + bk.Author = r.FormValue("author") + p := r.FormValue("price") + + // validate form values + if bk.Isbn == "" || bk.Title == "" || bk.Author == "" || p == "" { + return bk, errors.New("400. Bad request. All fields must be complete.") + } + + // convert form values + f64, err := strconv.ParseFloat(p, 32) + if err != nil { + return bk, errors.New("406. Not Acceptable. Price must be a number.") + } + bk.Price = float32(f64) + + // insert values + _, err = config.DB.Exec("INSERT INTO books (isbn, title, author, price) VALUES ($1, $2, $3, $4)", bk.Isbn, bk.Title, bk.Author, bk.Price) + if err != nil { + return bk, errors.New("500. Internal Server Error." + err.Error()) + } + return bk, nil +} + +func UpdateBook(r *http.Request) (Book, error) { + // get form values + bk := Book{} + bk.Isbn = r.FormValue("isbn") + bk.Title = r.FormValue("title") + bk.Author = r.FormValue("author") + p := r.FormValue("price") + + if bk.Isbn == "" || bk.Title == "" || bk.Author == "" || p == "" { + return bk, errors.New("400. Bad Request. Fields can't be empty.") + } + + // convert form values + f64, err := strconv.ParseFloat(p, 32) + if err != nil { + return bk, errors.New("406. Not Acceptable. Enter number for price.") + } + bk.Price = float32(f64) + + // insert values + _, err = config.DB.Exec("UPDATE books SET isbn = $1, title=$2, author=$3, price=$4 WHERE isbn=$1;", bk.Isbn, bk.Title, bk.Author, bk.Price) + if err != nil { + return bk, err + } + return bk, nil +} + +func DeleteBook(r *http.Request) error { + isbn := r.FormValue("isbn") + if isbn == "" { + return errors.New("400. Bad Request.") + } + + _, err := config.DB.Exec("DELETE FROM books WHERE isbn=$1;", isbn) + if err != nil { + return errors.New("500. Internal Server Error") + } + return nil +} diff --git a/046_mongodb/15_postgres/config/db.go b/046_mongodb/15_postgres/config/db.go new file mode 100644 index 00000000..ea8f493f --- /dev/null +++ b/046_mongodb/15_postgres/config/db.go @@ -0,0 +1,22 @@ +package config + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" +) + +var DB *sql.DB + +func init() { + var err error + DB, err = sql.Open("postgres", "postgres://bond:password@localhost/bookstore?sslmode=disable") + if err != nil { + panic(err) + } + + if err = DB.Ping(); err != nil { + panic(err) + } + fmt.Println("You connected to your database.") +} diff --git a/046_mongodb/15_postgres/config/tpl.go b/046_mongodb/15_postgres/config/tpl.go new file mode 100644 index 00000000..3be92065 --- /dev/null +++ b/046_mongodb/15_postgres/config/tpl.go @@ -0,0 +1,9 @@ +package config + +import "html/template" + +var TPL *template.Template + +func init() { + TPL = template.Must(template.ParseGlob("templates/*.gohtml")) +} diff --git a/046_mongodb/15_postgres/main.go b/046_mongodb/15_postgres/main.go new file mode 100644 index 00000000..4bcf3ceb --- /dev/null +++ b/046_mongodb/15_postgres/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "github.com/GoesToEleven/golang-web-dev/046_mongodb/15_postgres/books" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/books", books.Index) + http.HandleFunc("/books/show", books.Show) + http.HandleFunc("/books/create", books.Create) + http.HandleFunc("/books/create/process", books.CreateProcess) + http.HandleFunc("/books/update", books.Update) + http.HandleFunc("/books/update/process", books.UpdateProcess) + http.HandleFunc("/books/delete/process", books.DeleteProcess) + http.HandleFunc("/books/json", books.ShowJSON) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/books", http.StatusSeeOther) +} diff --git a/046_mongodb/15_postgres/templates/books.gohtml b/046_mongodb/15_postgres/templates/books.gohtml new file mode 100644 index 00000000..ce54e1bf --- /dev/null +++ b/046_mongodb/15_postgres/templates/books.gohtml @@ -0,0 +1,37 @@ + + + + + Create Book + + + +{{range .}} +

{{.Isbn}} - {{.Title}} - {{.Author}} - {{.Price}} - update - delete

+{{end}} + + + + + \ No newline at end of file diff --git a/046_mongodb/15_postgres/templates/create.gohtml b/046_mongodb/15_postgres/templates/create.gohtml new file mode 100644 index 00000000..1d888873 --- /dev/null +++ b/046_mongodb/15_postgres/templates/create.gohtml @@ -0,0 +1,39 @@ + + + + + Create Book + + + + +

Create A New Book

+
+ + + + + + + + + \ No newline at end of file diff --git a/046_mongodb/15_postgres/templates/created.gohtml b/046_mongodb/15_postgres/templates/created.gohtml new file mode 100644 index 00000000..54cf8977 --- /dev/null +++ b/046_mongodb/15_postgres/templates/created.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + + +

Created A New Book

+ +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + \ No newline at end of file diff --git a/046_mongodb/15_postgres/templates/json.gohtml b/046_mongodb/15_postgres/templates/json.gohtml new file mode 100644 index 00000000..f58c9b7b --- /dev/null +++ b/046_mongodb/15_postgres/templates/json.gohtml @@ -0,0 +1,35 @@ + + + + + Create Book + + + + +

{{.}}

+ + + + \ No newline at end of file diff --git a/046_mongodb/15_postgres/templates/show.gohtml b/046_mongodb/15_postgres/templates/show.gohtml new file mode 100644 index 00000000..445298e5 --- /dev/null +++ b/046_mongodb/15_postgres/templates/show.gohtml @@ -0,0 +1,35 @@ + + + + + Create Book + + + + +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + + \ No newline at end of file diff --git a/046_mongodb/15_postgres/templates/update.gohtml b/046_mongodb/15_postgres/templates/update.gohtml new file mode 100644 index 00000000..bc799ea3 --- /dev/null +++ b/046_mongodb/15_postgres/templates/update.gohtml @@ -0,0 +1,39 @@ + + + + + Create Book + + + + +

Update A Book

+
+ + + + + + + + + \ No newline at end of file diff --git a/046_mongodb/15_postgres/templates/updated.gohtml b/046_mongodb/15_postgres/templates/updated.gohtml new file mode 100644 index 00000000..a435784b --- /dev/null +++ b/046_mongodb/15_postgres/templates/updated.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + + +

Updated Book

+ +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + \ No newline at end of file diff --git a/046_mongodb/16_go-mongo/README.md b/046_mongodb/16_go-mongo/README.md new file mode 100644 index 00000000..20c40cbe --- /dev/null +++ b/046_mongodb/16_go-mongo/README.md @@ -0,0 +1,113 @@ +# setup + +``` +go get -u gopkg.in/mgo.v2 +``` + +[https://godoc.org/gopkg.in/mgo.v2](https://godoc.org/gopkg.in/mgo.v2) + +[http://labix.org/mgo](http://labix.org/mgo) + +# setup database + +#### restart mongo +close any open mongo connections, then restart with these commands: +``` +mongo +``` + +in a new tab +``` +mongod +``` + +#### create db +``` +use bookstore +``` + +#### create collection books & insert books +``` +db.books.insert([{"isbn":"978-1505255607","title":"The Time Machine","author":"H. G. Wells","price":5.99},{"isbn":"978-1503261960","title":"Wind Sand \u0026 Stars","author":"Antoine","price":14.99},{"isbn":"978-1503261961","title":"West With The Night","author":"Beryl Markham","price":14.99}]) +``` + +#### test +``` +db.books.find() +``` + +#### user setup +``` +db.createUser( + { + user: "bond", + pwd: "moneypenny007", + roles: [ { role: "readWrite", db: "bookstore" } ] + } +) +``` + +#### exit mongo & then start again with auth enabled +``` +mongod --auth +``` + +``` +mongo -u "bond" -p "moneypenny007" --authenticationDatabase "bookstore" +``` + +#### test + +``` +use bookstore +``` + +``` +show collections +``` + +``` +db.books.find() +``` + +``` +db.books.insert({"isbn" : "978-1503261777", "title" : "Never Say Never", "author" : "Ian Fleming", "price" : 24.99 }) +``` + +``` +db.books.find() +``` + +# GO & MONGO + +#### db access + +``` +mongodb://myuser:mypass@localhost:27017/dbToAccess +``` + +If the port number is not provided for a server, it defaults to 27017. + +for our example: +``` +mongodb://bond:moneypenny007@localhost:27017/bookstore +``` +[https://godoc.org/gopkg.in/mgo.v2#Dial](https://godoc.org/gopkg.in/mgo.v2#Dial) + +#### db.go +Update to use mongo. You will use the ```mgo.Dial``` to create a session. You can still assign this to the variable ```DB```. + + + +#### models.go +Update to use mongo. + + +# run the application and make a request +``` +curl -i localhost:8080/books +``` + +``` +curl -i -X POST -d "isbn=978-1470184841&title=Metamorphosis&author=Franz Kafka&price=5.90" localhost:8080/books/create/process +``` \ No newline at end of file diff --git a/046_mongodb/16_go-mongo/books/handlers.go b/046_mongodb/16_go-mongo/books/handlers.go new file mode 100644 index 00000000..be15314a --- /dev/null +++ b/046_mongodb/16_go-mongo/books/handlers.go @@ -0,0 +1,100 @@ +package books + +import ( + "github.com/GoesToEleven/golang-web-dev/046_mongodb/16_go-mongo/config" + "net/http" +) + +func Index(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bks, err := AllBooks() + if err != nil { + http.Error(w, http.StatusText(500)+err.Error(), http.StatusInternalServerError) + return + } + + config.TPL.ExecuteTemplate(w, "books.gohtml", bks) +} + +func Show(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := OneBook(r) + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + config.TPL.ExecuteTemplate(w, "show.gohtml", bk) +} + +func Create(w http.ResponseWriter, r *http.Request) { + config.TPL.ExecuteTemplate(w, "create.gohtml", nil) +} + +func CreateProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := PutBook(r) + if err != nil { + http.Error(w, http.StatusText(406), http.StatusNotAcceptable) + return + } + + config.TPL.ExecuteTemplate(w, "created.gohtml", bk) +} + +func Update(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := OneBook(r) + if err != nil { + http.Error(w, http.StatusText(500), http.StatusInternalServerError) + return + } + + config.TPL.ExecuteTemplate(w, "update.gohtml", bk) +} + +func UpdateProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + bk, err := UpdateBook(r) + if err != nil { + http.Error(w, http.StatusText(406), http.StatusBadRequest) + return + } + + config.TPL.ExecuteTemplate(w, "updated.gohtml", bk) +} + +func DeleteProcess(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed) + return + } + + err := DeleteBook(r) + if err != nil { + http.Error(w, http.StatusText(400), http.StatusBadRequest) + return + } + + http.Redirect(w, r, "/books", http.StatusSeeOther) +} diff --git a/046_mongodb/16_go-mongo/books/models.go b/046_mongodb/16_go-mongo/books/models.go new file mode 100644 index 00000000..1a5f7212 --- /dev/null +++ b/046_mongodb/16_go-mongo/books/models.go @@ -0,0 +1,108 @@ +package books + +import ( + "errors" + "github.com/GoesToEleven/golang-web-dev/046_mongodb/16_go-mongo/config" + "gopkg.in/mgo.v2/bson" + "net/http" + "strconv" +) + +type Book struct { + // add ID and tags if you need them + // ID bson.ObjectId // `json:"id" bson:"_id"` + Isbn string // `json:"isbn" bson:"isbn"` + Title string // `json:"title" bson:"title"` + Author string // `json:"author" bson:"author"` + Price float32 // `json:"price" bson:"price"` +} + +func AllBooks() ([]Book, error) { + bks := []Book{} + err := config.Books.Find(bson.M{}).All(&bks) + if err != nil { + return nil, err + } + return bks, nil +} + +func OneBook(r *http.Request) (Book, error) { + bk := Book{} + isbn := r.FormValue("isbn") + if isbn == "" { + return bk, errors.New("400. Bad Request.") + } + err := config.Books.Find(bson.M{"isbn": isbn}).One(&bk) + if err != nil { + return bk, err + } + return bk, nil +} + +func PutBook(r *http.Request) (Book, error) { + // get form values + bk := Book{} + bk.Isbn = r.FormValue("isbn") + bk.Title = r.FormValue("title") + bk.Author = r.FormValue("author") + p := r.FormValue("price") + + // validate form values + if bk.Isbn == "" || bk.Title == "" || bk.Author == "" || p == "" { + return bk, errors.New("400. Bad request. All fields must be complete.") + } + + // convert form values + f64, err := strconv.ParseFloat(p, 32) + if err != nil { + return bk, errors.New("406. Not Acceptable. Price must be a number.") + } + bk.Price = float32(f64) + + // insert values + err = config.Books.Insert(bk) + if err != nil { + return bk, errors.New("500. Internal Server Error." + err.Error()) + } + return bk, nil +} + +func UpdateBook(r *http.Request) (Book, error) { + // get form values + bk := Book{} + bk.Isbn = r.FormValue("isbn") + bk.Title = r.FormValue("title") + bk.Author = r.FormValue("author") + p := r.FormValue("price") + + if bk.Isbn == "" || bk.Title == "" || bk.Author == "" || p == "" { + return bk, errors.New("400. Bad Request. Fields can't be empty.") + } + + // convert form values + f64, err := strconv.ParseFloat(p, 32) + if err != nil { + return bk, errors.New("406. Not Acceptable. Enter number for price.") + } + bk.Price = float32(f64) + + // update values + err = config.Books.Update(bson.M{"isbn": bk.Isbn}, &bk) + if err != nil { + return bk, err + } + return bk, nil +} + +func DeleteBook(r *http.Request) error { + isbn := r.FormValue("isbn") + if isbn == "" { + return errors.New("400. Bad Request.") + } + + err := config.Books.Remove(bson.M{"isbn": isbn}) + if err != nil { + return errors.New("500. Internal Server Error") + } + return nil +} diff --git a/046_mongodb/16_go-mongo/config/db.go b/046_mongodb/16_go-mongo/config/db.go new file mode 100644 index 00000000..25ec7b96 --- /dev/null +++ b/046_mongodb/16_go-mongo/config/db.go @@ -0,0 +1,31 @@ +package config + +import ( + "fmt" + _ "github.com/lib/pq" + "gopkg.in/mgo.v2" +) + +// database +var DB *mgo.Database + +// collections +var Books *mgo.Collection + +func init() { + // get a mongo sessions + //s, err := mgo.Dial("mongodb://bond:moneypenny007@localhost/bookstore") + s, err := mgo.Dial("mongodb://localhost/bookstore") + if err != nil { + panic(err) + } + + if err = s.Ping(); err != nil { + panic(err) + } + + DB = s.DB("bookstore") + Books = DB.C("books") + + fmt.Println("You connected to your mongo database.") +} diff --git a/046_mongodb/16_go-mongo/config/tpl.go b/046_mongodb/16_go-mongo/config/tpl.go new file mode 100644 index 00000000..3be92065 --- /dev/null +++ b/046_mongodb/16_go-mongo/config/tpl.go @@ -0,0 +1,9 @@ +package config + +import "html/template" + +var TPL *template.Template + +func init() { + TPL = template.Must(template.ParseGlob("templates/*.gohtml")) +} diff --git a/046_mongodb/16_go-mongo/main.go b/046_mongodb/16_go-mongo/main.go new file mode 100644 index 00000000..02c8d9ef --- /dev/null +++ b/046_mongodb/16_go-mongo/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "github.com/GoesToEleven/golang-web-dev/046_mongodb/16_go-mongo/books" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + http.HandleFunc("/books", books.Index) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.HandleFunc("/books/show", books.Show) + http.HandleFunc("/books/create", books.Create) + http.HandleFunc("/books/create/process", books.CreateProcess) + http.HandleFunc("/books/update", books.Update) + http.HandleFunc("/books/update/process", books.UpdateProcess) + http.HandleFunc("/books/delete/process", books.DeleteProcess) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/books", http.StatusSeeOther) +} diff --git a/046_mongodb/16_go-mongo/templates/books.gohtml b/046_mongodb/16_go-mongo/templates/books.gohtml new file mode 100644 index 00000000..a40d9c4d --- /dev/null +++ b/046_mongodb/16_go-mongo/templates/books.gohtml @@ -0,0 +1,36 @@ + + + + + All Books + + + +{{range .}} +

{{.Isbn}} - {{.Title}} - {{.Author}} - {{.Price}} - update - delete

+{{end}} + + + + \ No newline at end of file diff --git a/046_mongodb/16_go-mongo/templates/create.gohtml b/046_mongodb/16_go-mongo/templates/create.gohtml new file mode 100644 index 00000000..1d888873 --- /dev/null +++ b/046_mongodb/16_go-mongo/templates/create.gohtml @@ -0,0 +1,39 @@ + + + + + Create Book + + + + +

Create A New Book

+
+ + + + + + + + + \ No newline at end of file diff --git a/046_mongodb/16_go-mongo/templates/created.gohtml b/046_mongodb/16_go-mongo/templates/created.gohtml new file mode 100644 index 00000000..52576e54 --- /dev/null +++ b/046_mongodb/16_go-mongo/templates/created.gohtml @@ -0,0 +1,36 @@ + + + + + Created Book + + + + +

Created A New Book

+ +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + \ No newline at end of file diff --git a/046_mongodb/16_go-mongo/templates/show.gohtml b/046_mongodb/16_go-mongo/templates/show.gohtml new file mode 100644 index 00000000..4e60889a --- /dev/null +++ b/046_mongodb/16_go-mongo/templates/show.gohtml @@ -0,0 +1,35 @@ + + + + + One Book + + + + +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + + \ No newline at end of file diff --git a/046_mongodb/16_go-mongo/templates/update.gohtml b/046_mongodb/16_go-mongo/templates/update.gohtml new file mode 100644 index 00000000..bc799ea3 --- /dev/null +++ b/046_mongodb/16_go-mongo/templates/update.gohtml @@ -0,0 +1,39 @@ + + + + + Create Book + + + + +

Update A Book

+
+ + + + + + + + + \ No newline at end of file diff --git a/046_mongodb/16_go-mongo/templates/updated.gohtml b/046_mongodb/16_go-mongo/templates/updated.gohtml new file mode 100644 index 00000000..a435784b --- /dev/null +++ b/046_mongodb/16_go-mongo/templates/updated.gohtml @@ -0,0 +1,36 @@ + + + + + Create Book + + + + +

Updated Book

+ +

{{.Isbn}} - {{.Title}} - {{.Author}} {{.Price}}

+ + + \ No newline at end of file diff --git a/046_mongodb/README.md b/046_mongodb/README.md new file mode 100644 index 00000000..5b14e52b --- /dev/null +++ b/046_mongodb/README.md @@ -0,0 +1,1592 @@ +# Mongo Commands + +## 02_db + +#### create + +``` +use +``` +The above will use the database of the provided name if it exists, and create it if it doesn't + +#### use + +``` +use +``` + +#### example +``` +use temp +``` + +The above will use the database of the provided name if it exists, and create it if it doesn't + +#### see current db + +``` +db +``` + +#### see all db + +``` +show dbs +``` +You need to have at least one document in a db for it to be seen. + +#### insert document + +``` +db..insert({"name":"McLeod"}) +``` + +example +``` +db.dogs.insert({"name":"toby"}) +``` + +#### view documents +``` +db..find() +``` + +example +``` +db.cats.insert({"firstname":"coco"}) +``` + +``` +db.cats.find().pretty() +``` + +#### view collections +``` +show collections +``` + +#### drop db +``` +db.dropDatabase() +``` + +## 03_collection + +# collection commands + +#### create implicitly +``` +db..insert({"name":"McLeod"}) +``` + +#### create explicitly +``` +db.createCollection(, {}) +``` + +#### optional options +| option | type | description | +| --- | --- | --- | +| capped | bool | caps the size | +| size | number | sets size of cap in bytes | +| max | bool | maximum number of documents allowed in capped collection | + +[other options including validation](https://docs.mongodb.com/manual/reference/method/db.createCollection/) + +#### examples +``` +db.createCollection("customers") +``` + +``` +db.createCollection("crs",{capped:true, size:65536,max:1000000}) +``` + +#### view collections +``` +show collections +``` + +#### drop +``` +db..drop() +``` + +## 04_document + +#### insert +``` +db..insert({document}) +``` + +#### insert multiple +``` +db..insert(< [{document}, {document}, ..., {document}] >) +``` +pass in an array of documents + +#### example +``` +use playroom +``` + +``` +db +``` + +``` +show dbs +``` + +``` +db.crayons.insert([ + { + "hex": "#EFDECD", + "name": "Almond", + "rgb": "(239, 222, 205)" + }, + { + "hex": "#CD9575", + "name": "Antique Brass", + "rgb": "(205, 149, 117)" + }, + { + "hex": "#FDD9B5", + "name": "Apricot", + "rgb": "(253, 217, 181)" + }, + { + "hex": "#78DBE2", + "name": "Aquamarine", + "rgb": "(120, 219, 226)" + }, + { + "hex": "#87A96B", + "name": "Asparagus", + "rgb": "(135, 169, 107)" + }, + { + "hex": "#FFA474", + "name": "Atomic Tangerine", + "rgb": "(255, 164, 116)" + }, + { + "hex": "#FAE7B5", + "name": "Banana Mania", + "rgb": "(250, 231, 181)" + } + ]) +``` +[source of crayon json](https://gist.githubusercontent.com/jjdelc/1868136/raw/c9160b1e60bd8c10c03dbd1a61b704a8e977c46b/crayola.json) + +``` +show collections +``` + +``` +db.crayons.find() +``` + +``` +db.crayons.drop() +``` + +``` +db.dropDatabase() +``` + +## 05_query + +#### setup + +``` +use store +db +show dbs +db.customers.insert([{"role":"double-zero","name": "Bond","age": 32},{"role":"citizen","name": "Moneypenny","age":32},{"role":"citizen","name": "Q","age":67},{"role":"citizen","name": "M","age":57},{"role":"citizen","name": "Dr. No","age":52}]) +``` + +#### find +``` +db..find() +db.customers.find() +``` + +#### find one +``` +db..findOne() +db.customers.findOne() +``` + +#### find specific +``` +db.customers.find({"name":"Bond"}) +db.customers.find({name:"Bond"}) +``` +You can do it either way: ```"name" or name```. JSON specification is to enclose name (object name-value pair) in double qoutes + +#### and +``` +db.customers.find({$and: [{name:"Bond"}, {age:32}]}) +db.customers.find({$and: [{name:"Bond"}, {age:{$lt:20}}]}) +db.customers.find({$and: [{name:"Bond"}, {age:{$gt:20}}]}) +``` + +#### or +``` +db.customers.find({$or: [{name:"Bond"}, {age:67}]}) +db.customers.find({$or: [{name:"Bond"}, {age:{$lt:20}}]}) +db.customers.find({$or: [{name:"Bond"}, {age:{$gt:32}}]}) +``` + +#### and or +``` +db.customers.find({role:"citizen"}) +db.customers.find({age:52}) +db.customers.find({$and: [{role:"citizen"}, {age:52}]}) +db.customers.find({$or: [{role:"citizen"}, {age:52}]}) +db.customers.find({$or: [{role:"citizen"}, {age:52}, {name:"Bond"}]}) +``` + +``` +db.customers.find({$or:[ +{ $and : [ { role : "citizen" }, { age : 32 } ] }, +{ $and : [ { role : "citizen" }, { age : 67 } ] } +]}) +``` + +#### regex +``` +db.customers.find({name: {$regex: '^M'}}) +``` + +[regex cheatsheet](05_query/regex.pdf) + +#### pretty +``` +db..find().pretty() +``` +pretty prints the results + +#### operators + +| operator | syntax | example | +| --- | --- | --- | +| equality | {key:value} | db.customers.find({"name":"Bond"}).pretty() | +| less than | {key:{$lt:value}} | db.customers.find({"age":{$lt:20}}).pretty() | +| less than equals | {key:{$lte:value}} | db.customers.find({"age":{$lte:20}}).pretty() | +| greater than | {key:{$gt:value}} | db.customers.find({"age":{$gt:20}}).pretty() | +| greater than equals | {key:{$gte:value}} | db.customers.find({"age":{$gte:20}}).pretty() | +| not equals | {key:{$ne:value}} | db.customers.find({"age":{$ne:20}}).pretty() | + + +#### JSON reminder +JavaScript Object Notation (JSON) is a text format for the serialization of structured data. + +It is derived from the object literals of JavaScript. + +JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and arrays) + +#### Primitive JSON + +Here are four small JSON texts containing only values: + +``` +"Hello world!" +42 +true +null +``` + +#### Object JSON + +An object structure is represented as a pair of curly brackets surrounding zero or more **name-value** pairs (or members). + +An object is an unordered collection of zero or more **name:value** pairs + +A **name** is a string + +A **value** is a string, number, boolean, null, object, or array. + +Declare properties using **name:value** pairings separated by commas + +Enclose names in curly braces + +There is no trailing comma + +This is a JSON object: + +``` +{ + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, 38793] + } +} +``` + +#### Array JSON + +An array structure is represented as square brackets surrounding zero or more values (or elements). + +Elements are separated by commas. + +A value must be an + +``` +object +array +number +string +three literal names +true +false +null +``` + +This is a JSON array containing two objects: + + [ + { + "precision": "zip", + "Latitude": 37.7668, + "Longitude": -122.3959, + "Address": "", + "City": "SAN FRANCISCO", + "State": "CA", + "Zip": "94107", + "Country": "US" + }, + { + "precision": "zip", + "Latitude": 37.371991, + "Longitude": -122.026020, + "Address": "", + "City": "SUNNYVALE", + "State": "CA", + "Zip": "94085", + "Country": "US" + } + ] + +#### Number + +The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. A fraction part is a decimal point followed by one or more digits. + +#### String + +The representation of strings is similar to conventions used in the C family of programming languages. A string begins and ends with **double quotation marks**. + +source: The Internet Engineering Task Force (IETF) + +## 06_update + +#### update & save + +update will update a record + +save will overwrite a record + +#### update +``` +db..update(, , ) +``` + +example +``` +db.customers.find() +``` + +gives this data +``` +{ "_id" : ObjectId("5891221756867ebff44cc885"), "role" : "double-zero", "name" : "Bond", "age" : 32 } +{ "_id" : ObjectId("5891221756867ebff44cc886"), "role" : "citizen", "name" : "Moneypenny", "age" : 32 } +{ "_id" : ObjectId("5891221756867ebff44cc887"), "role" : "citizen", "name" : "Q", "age" : 67 } +{ "_id" : ObjectId("5891221756867ebff44cc888"), "role" : "citizen", "name" : "M", "age" : 57 } +{ "_id" : ObjectId("5891221756867ebff44cc889"), "role" : "citizen", "name" : "Dr. No", "age" : 52 } +``` + +update like this +``` +db.customers.update({_id:ObjectId("5891221756867ebff44cc886")},{$set:{role:"double-zero"}}) +``` + +``` +db.customers.update({name:"Moneypenny"},{$set:{role:"double-zero"}}) +``` + +``` +db.customers.update({name:"Moneypenny"},{$set:{role:"citizen", name: "Miss Moneypenny"}}) +``` + +``` +db.customers.update({age:{$gt:35}},{$set:{role:"double-zero"}}) +``` + +``` +db.customers.update({age:{$gt:35}},{$set:{role:"double-zero"}}, {multi:true}) +``` +[see options](https://docs.mongodb.com/manual/reference/method/db.collection.update/) + +``` +db.customers.update({},{$set:{role:"citizen"}}, {multi:true}) +``` +[see query documentation](https://docs.mongodb.com/manual/tutorial/query-documents/) + +("5893888012acb8ada532a8e4" + +#### save +``` +db.customers.save({"role":"villain","name":"Jaws","age":43}) +``` + +``` +db.customers.save({"_id":ObjectId("5891221756867ebff44cc889"),"role":"villain","name":"Goldfinger","age":77}) +``` + +``` +db.customers.save({"_id":ObjectId("5893888012acb8ada532a8e4"),"role":"villain","name":"PussyGalore","age":31}) +``` + +## 07_remove + +``` +db..remove() +db.customers.remove({role:"double-zero"}) +db.customers.remove({role:"villain"}) +``` +removes all it matches + +#### remove only 1 +``` +db.customers.remove({role:"citizen"},1) +``` + +#### remove +``` +db.customers.remove({role:"citizen"}) +``` + +#### put documents back +``` +db.customers.insert([{"role":"double-zero","name": "Bond","age": 32},{"role":"citizen","name": "Moneypenny","age":32},{"role":"citizen","name": "Q","age":67},{"role":"citizen","name": "M","age":57},{"role":"citizen","name": "Dr. No","age":52}]) +``` + +#### remove all +``` +db.customers.remove({}) +``` + +#### put documents back +``` +db.customers.insert([{"role":"double-zero","name": "Bond","age": 32},{"role":"citizen","name": "Moneypenny","age":32},{"role":"citizen","name": "Q","age":67},{"role":"citizen","name": "M","age":57},{"role":"citizen","name": "Dr. No","age":52}]) +``` + +## 08_projection + +Retrieving part of a document; only some of the fields. + +``` +db..find(,) +``` + +``` +db.customers.find({},{_id:0,name:1,}) +``` +_id is displayed by default; turn off with 0 + +``` +db.customers.find({},{_id:0,name:1,age:1}) +``` + +``` +db.customers.find({age:{$gt:32}},{_id:0,name:1,age:1}) +``` + +## 09_limit + +#### setup + +``` +db.crayons.insert([ + { + "hex": "#EFDECD", + "name": "Almond", + "rgb": "(239, 222, 205)" + }, + { + "hex": "#CD9575", + "name": "Antique Brass", + "rgb": "(205, 149, 117)" + }, + { + "hex": "#FDD9B5", + "name": "Apricot", + "rgb": "(253, 217, 181)" + }, + { + "hex": "#78DBE2", + "name": "Aquamarine", + "rgb": "(120, 219, 226)" + }, + { + "hex": "#87A96B", + "name": "Asparagus", + "rgb": "(135, 169, 107)" + }, + { + "hex": "#FFA474", + "name": "Atomic Tangerine", + "rgb": "(255, 164, 116)" + }, + { + "hex": "#FAE7B5", + "name": "Banana Mania", + "rgb": "(250, 231, 181)" + } + ]) +``` + +#### limit +``` +db..find().limit(n) +``` + +``` +db.crayons.find().limit(3) +``` + +``` +db.customers.find({age:{$gt:32}},{_id:0,name:1,age:1}).limit(2) +``` + +## 10_sort + +Run **setup** below first + +``` +db..find().sort(:<1 for ascend, -1 descend>) +``` + +``` +db.oscars.find().limit(10) +db.oscars.find({},{_id:0,year:1,title:1}).limit(10) +db.oscars.find({},{_id:0,year:1,title:1}).limit(10).sort({title:1}) +db.oscars.find({},{_id:0,year:1,title:1}).sort({title:1}).limit(10) +db.oscars.find({},{_id:0,year:1,title:1}).limit(10).sort({title:-1}) +db.oscars.find({releaseYear:{$gt:1970}},{_id:0,year:1,title:1}).limit(10).sort({title:1}) +db.oscars.find({releaseYear:{$gt:1980}},{_id:0,year:1,title:1}) +``` + + +#### setup +``` +db.oscars.insert([ + { "year": "1927", + "title": "Wings", + "imdbId": "tt0018578", + "releaseDate": "1927-05-19T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1927, + "releaseMonth": 4, + "releaseDay": 19 + }, + { "year": "1929", + "title": "The Broadway Melody", + "imdbId": "tt0019729", + "releaseDate": "1929-02-01T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1929, + "releaseMonth": 1, + "releaseDay": 1 + }, + { "year": "1930", + "title": "All Quiet on the Western Front", + "imdbId": "tt0020629", + "releaseDate": "1930-04-21T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1930, + "releaseMonth": 3, + "releaseDay": 21 + }, + { "year": "1931", + "title": "Cimarron", + "imdbId": "tt0021746", + "releaseDate": "1931-01-26T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1931, + "releaseMonth": 0, + "releaseDay": 26 + }, + { "year": "1932", + "title": "Grand Hotel", + "imdbId": "tt0022958", + "releaseDate": "1932-04-12T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1932, + "releaseMonth": 3, + "releaseDay": 12 + }, + { "year": "1933", + "title": "Cavalcade", + "imdbId": "tt0023876", + "releaseDate": "1933-01-05T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1933, + "releaseMonth": 0, + "releaseDay": 5 + }, + { "year": "1934", + "title": "It Happened One Night", + "imdbId": "tt0025316", + "releaseDate": "1934-02-22T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1934, + "releaseMonth": 1, + "releaseDay": 22 + }, + { "year": "1935", + "title": "Mutiny on the Bounty", + "imdbId": "tt0026752", + "releaseDate": "1935-11-08T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1935, + "releaseMonth": 10, + "releaseDay": 8 + }, + { "year": "1936", + "title": "The Great Ziegfeld", + "imdbId": "tt0027698", + "releaseDate": "1936-03-22T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1936, + "releaseMonth": 2, + "releaseDay": 22 + }, + { "year": "1937", + "title": "The Life of Emile Zola", + "imdbId": "tt0029146", + "releaseDate": "1937-08-11T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1937, + "releaseMonth": 7, + "releaseDay": 11 + }, + { "year": "1938", + "title": "You Can't Take It with You", + "imdbId": "tt0030993", + "releaseDate": "1938-08-23T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1938, + "releaseMonth": 7, + "releaseDay": 23 + }, + { "year": "1939", + "title": "Gone with the Wind", + "imdbId": "tt0031381", + "releaseDate": "1939-12-28T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1939, + "releaseMonth": 11, + "releaseDay": 28 + }, + { "year": "1940", + "title": "Rebecca", + "imdbId": "tt0032976", + "releaseDate": "1940-03-27T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1940, + "releaseMonth": 2, + "releaseDay": 27 + }, + { "year": "1941", + "title": "How Green Was My Valley", + "imdbId": "tt0033729", + "releaseDate": "1941-10-28T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1941, + "releaseMonth": 9, + "releaseDay": 28 + }, + { "year": "1942", + "title": "Mrs. Miniver", + "imdbId": "tt0035093", + "releaseDate": "1942-07-22T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1942, + "releaseMonth": 6, + "releaseDay": 22 + }, + { "year": "1943", + "title": "Casablanca", + "imdbId": "tt0034583", + "releaseDate": "1942-11-26T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1942, + "releaseMonth": 10, + "releaseDay": 26 + }, + { "year": "1944", + "title": "Going My Way", + "imdbId": "tt0036872", + "releaseDate": "1944-08-16T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1944, + "releaseMonth": 7, + "releaseDay": 16 + }, + { "year": "1945", + "title": "The Lost Weekend", + "imdbId": "tt0037884", + "releaseDate": "1945-11-29T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1945, + "releaseMonth": 10, + "releaseDay": 29 + }, + { "year": "1946", + "title": "The Best Years of Our Lives", + "imdbId": "tt0036868", + "releaseDate": "1946-12-25T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1946, + "releaseMonth": 11, + "releaseDay": 25 + }, + { "year": "1947", + "title": "Gentleman's Agreement", + "imdbId": "tt0039416", + "releaseDate": "1947-11-11T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1947, + "releaseMonth": 10, + "releaseDay": 11 + }, + { "year": "1948", + "title": "Hamlet", + "imdbId": "tt0040416", + "releaseDate": "1948-10-27T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1948, + "releaseMonth": 9, + "releaseDay": 27 + }, + { "year": "1949", + "title": "All the Kings Men", + "imdbId": "tt0041113", + "releaseDate": "1949-11-08T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1949, + "releaseMonth": 10, + "releaseDay": 8 + }, + { "year": "1950", + "title": "All About Eve", + "imdbId": "tt0042192", + "releaseDate": "1950-10-13T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1950, + "releaseMonth": 9, + "releaseDay": 13 + }, + { "year": "1951", + "title": "An American in Paris", + "imdbId": "tt0043278", + "releaseDate": "1951-10-04T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1951, + "releaseMonth": 9, + "releaseDay": 4 + }, + { "year": "1952", + "title": "The Greatest Show on Earth", + "imdbId": "tt0044672", + "releaseDate": "1952-01-10T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1952, + "releaseMonth": 0, + "releaseDay": 10 + }, + { "year": "1953", + "title": "From Here to Eternity", + "imdbId": "tt0045793", + "releaseDate": "1953-09-30T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1953, + "releaseMonth": 8, + "releaseDay": 30 + }, + { "year": "1954", + "title": "On the Waterfront", + "imdbId": "tt0047296", + "releaseDate": "1954-07-28T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1954, + "releaseMonth": 6, + "releaseDay": 28 + }, + { "year": "1955", + "title": "Marty", + "imdbId": "tt0048356", + "releaseDate": "1955-07-15T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1955, + "releaseMonth": 6, + "releaseDay": 15 + }, + { "year": "1956", + "title": "Around the World in 80 Days", + "imdbId": "tt0048960", + "releaseDate": "1956-12-22T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1956, + "releaseMonth": 11, + "releaseDay": 22 + }, + { "year": "1957", + "title": "The Bridge on the River Kwai", + "imdbId": "tt0050212", + "releaseDate": "1957-12-19T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1957, + "releaseMonth": 11, + "releaseDay": 19 + }, + { "year": "1958", + "title": "Gigi", + "imdbId": "tt0051658", + "releaseDate": "1958-07-10T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1958, + "releaseMonth": 6, + "releaseDay": 10 + }, + { "year": "1959", + "title": "Ben-Hur", + "imdbId": "tt0052618", + "releaseDate": "1959-11-18T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1959, + "releaseMonth": 10, + "releaseDay": 18 + }, + { "year": "1960", + "title": "The Apartment", + "imdbId": "tt0053604", + "releaseDate": "1960-06-21T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1960, + "releaseMonth": 5, + "releaseDay": 21 + }, + { "year": "1961", + "title": "West Side Story", + "imdbId": "tt0055614", + "releaseDate": "1961-12-13T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1961, + "releaseMonth": 11, + "releaseDay": 13 + }, + { "year": "1962", + "title": "Lawrence of Arabia", + "imdbId": "tt0056172", + "releaseDate": "1962-12-21T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1962, + "releaseMonth": 11, + "releaseDay": 21 + }, + { "year": "1963", + "title": "Tom Jones", + "imdbId": "tt0057590", + "releaseDate": "1963-10-24T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1963, + "releaseMonth": 9, + "releaseDay": 24 + }, + { "year": "1964", + "title": "My Fair Lady", + "imdbId": "tt0058385", + "releaseDate": "1964-10-28T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1964, + "releaseMonth": 9, + "releaseDay": 28 + }, + { "year": "1965", + "title": "The Sound of Music", + "imdbId": "tt0059742", + "releaseDate": "1965-03-10T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1965, + "releaseMonth": 2, + "releaseDay": 10 + }, + { "year": "1966", + "title": "A Man for All Seasons", + "imdbId": "tt0060665", + "releaseDate": "1966-12-14T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1966, + "releaseMonth": 11, + "releaseDay": 14 + }, + { "year": "1967", + "title": "In the Heat of the Night", + "imdbId": "tt0061811", + "releaseDate": "1967-08-23T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1967, + "releaseMonth": 7, + "releaseDay": 23 + }, + { "year": "1968", + "title": "Oliver!", + "imdbId": "tt0063385", + "releaseDate": "1968-12-20T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1968, + "releaseMonth": 11, + "releaseDay": 20 + }, + { "year": "1969", + "title": "Midnight Cowboy", + "imdbId": "tt0064665", + "releaseDate": "1969-05-25T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1969, + "releaseMonth": 4, + "releaseDay": 25 + }, + { "year": "1970", + "title": "Patton", + "imdbId": "tt0066206", + "releaseDate": "1970-02-18T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1970, + "releaseMonth": 1, + "releaseDay": 18 + }, + { "year": "1971", + "title": "The French Connection", + "imdbId": "tt0067116", + "releaseDate": "1971-10-07T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1971, + "releaseMonth": 9, + "releaseDay": 7 + }, + { "year": "1972", + "title": "The Godfather", + "imdbId": "tt0068646", + "releaseDate": "1972-03-22T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1972, + "releaseMonth": 2, + "releaseDay": 22 + }, + { "year": "1973", + "title": "The Sting", + "imdbId": "tt0070735", + "releaseDate": "1973-12-25T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1973, + "releaseMonth": 11, + "releaseDay": 25 + }, + { "year": "1974", + "title": "The Godfather Part II", + "imdbId": "tt0071562", + "releaseDate": "1974-12-18T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1974, + "releaseMonth": 11, + "releaseDay": 18 + }, + { "year": "1975", + "title": "One Flew over the Cuckoo's Nest", + "imdbId": "tt0073486", + "releaseDate": "1975-11-19T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1975, + "releaseMonth": 10, + "releaseDay": 19 + }, + { "year": "1976", + "title": "Rocky", + "imdbId": "tt0075148", + "releaseDate": "1976-11-21T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1976, + "releaseMonth": 10, + "releaseDay": 21 + }, + { "year": "1977", + "title": "Annie Hall", + "imdbId": "tt0075686", + "releaseDate": "1977-04-20T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1977, + "releaseMonth": 3, + "releaseDay": 20 + }, + { "year": "1978", + "title": "The Deer Hunter", + "imdbId": "tt0077416", + "releaseDate": "1978-12-08T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1978, + "releaseMonth": 11, + "releaseDay": 8 + }, + { "year": "1979", + "title": "Kramer vs. Kramer", + "imdbId": "tt0079417", + "releaseDate": "1979-12-19T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1979, + "releaseMonth": 11, + "releaseDay": 19 + }, + { "year": "1980", + "title": "Ordinary People", + "imdbId": "tt0081283", + "releaseDate": "1980-09-26T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1980, + "releaseMonth": 8, + "releaseDay": 26 + }, + { "year": "1981", + "title": "Chariots of Fire", + "imdbId": "tt0082158", + "releaseDate": "1981-10-09T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1981, + "releaseMonth": 9, + "releaseDay": 9 + }, + { "year": "1982", + "title": "Gandhi", + "imdbId": "tt0083987", + "releaseDate": "1982-12-07T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1982, + "releaseMonth": 11, + "releaseDay": 7 + }, + { "year": "1983", + "title": "Terms of Endearment", + "imdbId": "tt0086425", + "releaseDate": "1983-11-20T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1983, + "releaseMonth": 10, + "releaseDay": 20 + }, + { "year": "1984", + "title": "Amadeus", + "imdbId": "tt0086879", + "releaseDate": "1984-09-06T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1984, + "releaseMonth": 8, + "releaseDay": 6 + }, + { "year": "1985", + "title": "Out of Africa", + "imdbId": "tt0089755", + "releaseDate": "1985-12-10T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1985, + "releaseMonth": 11, + "releaseDay": 10 + }, + { "year": "1986", + "title": "Platoon", + "imdbId": "tt0091763", + "releaseDate": "1986-12-19T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1986, + "releaseMonth": 11, + "releaseDay": 19 + }, + { "year": "1987", + "title": "The Last Emperor", + "imdbId": "tt0093389", + "releaseDate": "1987-11-19T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1987, + "releaseMonth": 10, + "releaseDay": 19 + }, + { "year": "1988", + "title": "Rain Man", + "imdbId": "tt0095953", + "releaseDate": "1988-12-14T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1988, + "releaseMonth": 11, + "releaseDay": 14 + }, + { "year": "1989", + "title": "Driving Miss Daisy", + "imdbId": "tt0097239", + "releaseDate": "1989-12-15T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1989, + "releaseMonth": 11, + "releaseDay": 15 + }, + { "year": "1990", + "title": "Dances With Wolves", + "imdbId": "tt0099348", + "releaseDate": "1990-10-19T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1990, + "releaseMonth": 9, + "releaseDay": 19 + }, + { "year": "1991", + "title": "The Silence of the Lambs", + "imdbId": "tt0102926", + "releaseDate": "1991-01-30T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1991, + "releaseMonth": 0, + "releaseDay": 30 + }, + { "year": "1992", + "title": "Unforgiven", + "imdbId": "tt0105695", + "releaseDate": "1992-08-03T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1992, + "releaseMonth": 7, + "releaseDay": 3 + }, + { "year": "1993", + "title": "Schindler's List", + "imdbId": "tt0108052", + "releaseDate": "1993-11-30T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1993, + "releaseMonth": 10, + "releaseDay": 30 + }, + { "year": "1994", + "title": "Forrest Gump", + "imdbId": "tt0109830", + "releaseDate": "1994-06-23T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1994, + "releaseMonth": 5, + "releaseDay": 23 + }, + { "year": "1995", + "title": "Braveheart", + "imdbId": "tt0112573", + "releaseDate": "1995-05-19T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1995, + "releaseMonth": 4, + "releaseDay": 19 + }, + { "year": "1996", + "title": "The English Patient", + "imdbId": "tt0116209", + "releaseDate": "1996-11-12T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1996, + "releaseMonth": 10, + "releaseDay": 12 + }, + { "year": "1997", + "title": "Titanic", + "imdbId": "tt0120338", + "releaseDate": "1997-12-14T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1997, + "releaseMonth": 11, + "releaseDay": 14 + }, + { "year": "1998", + "title": "Shakespeare in Love", + "imdbId": "tt0138097", + "releaseDate": "1998-12-08T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1998, + "releaseMonth": 11, + "releaseDay": 8 + }, + { "year": "1999", + "title": "American Beauty", + "imdbId": "tt0169547", + "releaseDate": "1999-09-08T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 1999, + "releaseMonth": 8, + "releaseDay": 8 + }, + { "year": "2000", + "title": "Gladiator", + "imdbId": "tt0172495", + "releaseDate": "2000-05-01T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2000, + "releaseMonth": 4, + "releaseDay": 1 + }, + { "year": "2001", + "title": "A Beautiful Mind", + "imdbId": "tt0268978", + "releaseDate": "2001-12-13T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2001, + "releaseMonth": 11, + "releaseDay": 13 + }, + { "year": "2002", + "title": "Chicago", + "imdbId": "tt0299658", + "releaseDate": "2002-12-18T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2002, + "releaseMonth": 11, + "releaseDay": 18 + }, + { "year": "2003", + "title": "The Lord of the Rings: The Return of the King", + "imdbId": "tt0167260", + "releaseDate": "2003-12-17T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2003, + "releaseMonth": 11, + "releaseDay": 17 + }, + { "year": "2004", + "title": "Million Dollar Baby", + "imdbId": "tt0405159", + "releaseDate": "2004-12-15T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2004, + "releaseMonth": 11, + "releaseDay": 15 + }, + { "year": "2005", + "title": "Crash", + "imdbId": "tt0375679", + "releaseDate": "2005-04-26T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2005, + "releaseMonth": 3, + "releaseDay": 26 + }, + { "year": "2006", + "title": "The Departed", + "imdbId": "tt0407887", + "releaseDate": "2006-09-26T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2006, + "releaseMonth": 8, + "releaseDay": 26 + }, + { "year": "2007", + "title": "No Country for Old Men", + "imdbId": "tt0477348", + "releaseDate": "2007-11-04T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2007, + "releaseMonth": 10, + "releaseDay": 4 + }, + { "year": "2008", + "title": "Slumdog Millionaire", + "imdbId": "tt1010048", + "releaseDate": "2008-11-12T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2008, + "releaseMonth": 10, + "releaseDay": 12 + }, + { "year": "2009", + "title": "The Hurt Locker", + "imdbId": "tt1655246", + "releaseDate": "2009-01-29T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2009, + "releaseMonth": 0, + "releaseDay": 29 + }, + { "year": "2010", + "title": "The King's Speech", + "imdbId": "tt1504320", + "releaseDate": "2010-12-24T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2010, + "releaseMonth": 11, + "releaseDay": 24 + }, + { "year": "2011", + "title": "The Artist", + "imdbId": "tt1655442", + "releaseDate": "2011-11-23T05:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2011, + "releaseMonth": 10, + "releaseDay": 23 + }, + { "year": "2012", + "title": "Argo", + "imdbId": "tt1024648", + "releaseDate": "2012-10-04T04:00:00.000Z", + "releaseCountry": "USA", + "releaseYear": 2012, + "releaseMonth": 9, + "releaseDay": 4 + }]) +``` + +## 11_index + +``` +db..createIndex({:<1 for ascend, -1 descend>}) +``` + +#### create index +``` +db.oscars.createIndex({title:1}) +``` + +#### see indexes +``` +db.oscars.getIndexes() +``` + +[learn to create a unique index and more](https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/#db.collection.createIndex) + +## 12_aggregate + +Aggregations operations process data records and return computed results. Aggregation operations group values from multiple documents together, and can perform a variety of operations on the grouped data to return a single result. MongoDB provides three ways to perform aggregation: the aggregation pipeline, the map-reduce function, and single purpose aggregation methods. + +[documenation about aggregation](https://docs.mongodb.com/manual/aggregation/) + +#### single purpose aggregation + +[documenation about single purpose aggregation](https://docs.mongodb.com/manual/aggregation/#single-purpose-agg-operations) + +There are two functions you can use: + +#### [db.collection.count()](https://docs.mongodb.com/manual/reference/method/db.collection.count/#db.collection.count) + +#### [db.collection.distinct()](https://docs.mongodb.com/manual/reference/method/db.collection.distinct/#db.collection.distinct) + +``` +db.collection.distinct(field, query, options) +``` + +| Parameter | Description | +| --- | --- | +| field | The field for which to return distinct values. +| query | A query that specifies the documents from which to retrieve the distinct values. +| options | Optional. A document that specifies the options. See Options. + +#### examples - count() +``` +db.oscars.count() +``` + +``` +db.oscars.find().count() +``` + +``` +db.customers.find({role:"citizen"}).count() +``` + +``` +db.customers.find({$or: [{name:"Bond"}, {age:{$gt:32}}]}).count() +``` + +#### examples - distinct() - setup +``` +db.inventory.insert([ +{ "_id": 1, "dept": "A", "item": { "sku": "111", "color": "red" }, "sizes": [ "S", "M" ] }, +{ "_id": 2, "dept": "A", "item": { "sku": "111", "color": "blue" }, "sizes": [ "M", "L" ] }, +{ "_id": 3, "dept": "B", "item": { "sku": "222", "color": "blue" }, "sizes": "S" }, +{ "_id": 4, "dept": "A", "item": { "sku": "333", "color": "black" }, "sizes": [ "S" ] } +]) +``` + +#### examples - distinct() + +``` +db.inventory.distinct( "dept" ) +``` + +``` +db.inventory.distinct( "item.sku" ) +``` + +``` +db.inventory.distinct( "sizes" ) +``` + +#### aggregation pipeline + +![aggregate pipeline](aggregate.png) + +``` +db..aggregate([{},{}]) +``` + +MongoDB’s aggregation framework is modeled on the concept of data processing pipelines. Documents enter a multi-stage pipeline that transforms the documents into an aggregated result. + +The most basic pipeline stages provide filters that operate like queries and document transformations that modify the form of the output document. + +Other pipeline operations provide tools for grouping and sorting documents by specific field or fields as well as tools for aggregating the contents of arrays, including arrays of documents. In addition, pipeline stages can use operators for tasks such as calculating the average or concatenating a string. + +The pipeline provides efficient data aggregation using native operations within MongoDB, and is the preferred method for data aggregation in MongoDB. + +[source](https://docs.mongodb.com/manual/aggregation/) + +#### example - setup +``` +db.orders.insert([ +{"cust_id":"A123","amount":500,"status":"A"}, +{"cust_id":"A123","amount":250,"status":"A"}, +{"cust_id":"B212","amount":200,"status":"A"}, +{"cust_id":"A123","amount":300,"status":"D"} +]) +``` + +#### example +``` +db.orders.aggregate([ +{$match:{status:"A"}}, +{$group:{_id: "$cust_id",total: {$sum:"$amount"}}} +]) +``` + +## 14_users + +#### locking down your database + +#### create admin super user + +``` +use admin +db.createUser( + { + user: "jamesbond", + pwd: "moneypennyrocks007sworld", + roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] + } +) +``` + +[built in user roles](https://docs.mongodb.com/manual/reference/built-in-roles/) + +#### exit mongo & then start again +``` +mongod --auth +``` + +``` +mongo -u "jamesbond" -p "moneypennyrocks007sworld" --authenticationDatabase "admin" +``` + +#### see current user + +``` +db.runCommand({connectionStatus : 1}) +``` + +#### create regular user +Give this user readwrite permissions on the ```store``` db. + +``` +db.createUser( + { + user: "bond", + pwd: "moneypenny007", + roles: [ { role: "readWrite", db: "store" } ] + } +) +``` + +#### exit mongo & then start again +``` +mongod --auth +``` + +``` +mongo -u "bond" -p "moneypenny007" --authenticationDatabase "store" +``` + +#### see current user + +``` +db.runCommand({connectionStatus : 1}) +``` + +#### lock down the database + +[enable auth](https://docs.mongodb.com/master/tutorial/enable-authentication/) + +[getting auth running on mongo](https://docs.mongodb.com/manual/tutorial/enable-authentication/) + +#### exit mongo & then start again with auth enabled +``` +mongod --auth +``` + +``` +mongo -u "bond" -p "moneypenny007" --authenticationDatabase "store" +``` + +#### test + +``` +use store +``` + +``` +show collections +``` + +``` +db.customers.find() +``` + +``` +db.customers.insert({"role" : "double-zero", "name" : "Elon Musk", "age" : 47 }) +``` + +#### test + +launch a new terminal window + +``` +mongo +``` + +should be unauthorized: +``` +show collections +``` + +#### drop user +``` +db.dropUser("") +``` \ No newline at end of file diff --git a/999_old-code/040_appengine-introduction/01_hello-world/app.yaml b/047_google-cloud/01_hello-world/01/app.yaml similarity index 100% rename from 999_old-code/040_appengine-introduction/01_hello-world/app.yaml rename to 047_google-cloud/01_hello-world/01/app.yaml diff --git a/999_old-code/040_appengine-introduction/01_hello-world/hello.go b/047_google-cloud/01_hello-world/01/hello.go similarity index 50% rename from 999_old-code/040_appengine-introduction/01_hello-world/hello.go rename to 047_google-cloud/01_hello-world/01/hello.go index 49b26199..6e65fed7 100755 --- a/999_old-code/040_appengine-introduction/01_hello-world/hello.go +++ b/047_google-cloud/01_hello-world/01/hello.go @@ -9,6 +9,6 @@ func init() { http.HandleFunc("/", index) } -func index(res http.ResponseWriter, req *http.Request) { - fmt.Fprint(res, "Hello, World!") +func index(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, "Hello, World!") } diff --git a/999_old-code/041_memcache/01_get-nil/app.yaml b/047_google-cloud/01_hello-world/02/app.yaml similarity index 100% rename from 999_old-code/041_memcache/01_get-nil/app.yaml rename to 047_google-cloud/01_hello-world/02/app.yaml diff --git a/047_google-cloud/01_hello-world/02/main.go b/047_google-cloud/01_hello-world/02/main.go new file mode 100755 index 00000000..4d8d35c7 --- /dev/null +++ b/047_google-cloud/01_hello-world/02/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "fmt" + "google.golang.org/appengine" + "net/http" +) + +func main() { + http.HandleFunc("/", index) + appengine.Main() +} + +func index(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, "Hello, World!") +} diff --git a/999_old-code/040_appengine-introduction/02_hello-user/app.yaml b/047_google-cloud/02_hello-user/app.yaml similarity index 100% rename from 999_old-code/040_appengine-introduction/02_hello-user/app.yaml rename to 047_google-cloud/02_hello-user/app.yaml diff --git a/047_google-cloud/02_hello-user/hello.go b/047_google-cloud/02_hello-user/hello.go new file mode 100755 index 00000000..44f94062 --- /dev/null +++ b/047_google-cloud/02_hello-user/hello.go @@ -0,0 +1,29 @@ +package hello + +import ( + "fmt" + "net/http" + + "google.golang.org/appengine" + "google.golang.org/appengine/user" +) + +func init() { + http.HandleFunc("/", index) +} + +func index(w http.ResponseWriter, r *http.Request) { + ctx := appengine.NewContext(r) + u := user.Current(ctx) + if u == nil { + url, err := user.LoginURL(ctx, r.URL.String()) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Location", url) + w.WriteHeader(http.StatusSeeOther) + return + } + fmt.Fprintf(w, "Hello, %v", u) +} diff --git a/999_old-code/040_appengine-introduction/03_user/app.yaml b/047_google-cloud/03_user/app.yaml similarity index 100% rename from 999_old-code/040_appengine-introduction/03_user/app.yaml rename to 047_google-cloud/03_user/app.yaml diff --git a/047_google-cloud/03_user/main.go b/047_google-cloud/03_user/main.go new file mode 100755 index 00000000..35b979c4 --- /dev/null +++ b/047_google-cloud/03_user/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "fmt" + "net/http" + + "google.golang.org/appengine" + "google.golang.org/appengine/user" +) + +func init() { + http.HandleFunc("/", index) + http.HandleFunc("/admin/", admin) +} + +func index(w http.ResponseWriter, r *http.Request) { + ctx := appengine.NewContext(r) + u := user.Current(ctx) + url, err := user.LogoutURL(ctx, "/") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "text/html; charset=UTF-8") + fmt.Fprintf(w, `Welcome, %s! (sign out)`, u, url) +} + +func admin(w http.ResponseWriter, r *http.Request) { + ctx := appengine.NewContext(r) + u := user.Current(ctx) + url, _ := user.LogoutURL(ctx, "/") + w.Header().Set("Content-Type", "text/html; charset=UTF-8") + fmt.Fprintf(w, `Welcome ADMIN, %s! (sign out)`, u, url) +} diff --git a/999_old-code/040_appengine-introduction/README.md b/047_google-cloud/README.md similarity index 100% rename from 999_old-code/040_appengine-introduction/README.md rename to 047_google-cloud/README.md diff --git a/999_old-code/041_memcache/02_set_get/app.yaml b/048_memcache/01_get-nil/app.yaml similarity index 100% rename from 999_old-code/041_memcache/02_set_get/app.yaml rename to 048_memcache/01_get-nil/app.yaml diff --git a/048_memcache/01_get-nil/main.go b/048_memcache/01_get-nil/main.go new file mode 100755 index 00000000..9b10535f --- /dev/null +++ b/048_memcache/01_get-nil/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "fmt" + "net/http" +) +import ( + "google.golang.org/appengine" + "google.golang.org/appengine/memcache" +) + +func init() { + http.HandleFunc("/", index) +} + +func index(w http.ResponseWriter, r *http.Request) { + ctx := appengine.NewContext(r) + item, err := memcache.Get(ctx, "some-key") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + fmt.Fprintln(w, item) +} diff --git a/999_old-code/041_memcache/03_expiration/app.yaml b/048_memcache/02_set_get/app.yaml similarity index 100% rename from 999_old-code/041_memcache/03_expiration/app.yaml rename to 048_memcache/02_set_get/app.yaml diff --git a/999_old-code/041_memcache/02_set_get/main.go b/048_memcache/02_set_get/main.go similarity index 51% rename from 999_old-code/041_memcache/02_set_get/main.go rename to 048_memcache/02_set_get/main.go index 9cdea1e5..116f6f21 100755 --- a/999_old-code/041_memcache/02_set_get/main.go +++ b/048_memcache/02_set_get/main.go @@ -12,8 +12,8 @@ func init() { http.HandleFunc("/", index) } -func index(res http.ResponseWriter, req *http.Request) { - ctx := appengine.NewContext(req) +func index(w http.ResponseWriter, r *http.Request) { + ctx := appengine.NewContext(r) item1 := memcache.Item{ Key: "foo", @@ -22,8 +22,10 @@ func index(res http.ResponseWriter, req *http.Request) { memcache.Set(ctx, &item1) - item, _ := memcache.Get(ctx, "foo") - if item != nil { - fmt.Fprintln(res, string(item.Value)) + item, err := memcache.Get(ctx, "foo") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return } + fmt.Fprintln(w, string(item.Value)) } diff --git a/999_old-code/041_memcache/04_increment/app.yaml b/048_memcache/03_expiration/app.yaml similarity index 100% rename from 999_old-code/041_memcache/04_increment/app.yaml rename to 048_memcache/03_expiration/app.yaml diff --git a/999_old-code/041_memcache/03_expiration/main.go b/048_memcache/03_expiration/main.go similarity index 56% rename from 999_old-code/041_memcache/03_expiration/main.go rename to 048_memcache/03_expiration/main.go index 8ec40dc5..7ec93a0f 100755 --- a/999_old-code/041_memcache/03_expiration/main.go +++ b/048_memcache/03_expiration/main.go @@ -13,8 +13,8 @@ func init() { http.HandleFunc("/", index) } -func index(res http.ResponseWriter, req *http.Request) { - ctx := appengine.NewContext(req) +func index(w http.ResponseWriter, r *http.Request) { + ctx := appengine.NewContext(r) item1 := memcache.Item{ Key: "foo", @@ -24,8 +24,10 @@ func index(res http.ResponseWriter, req *http.Request) { memcache.Set(ctx, &item1) - item, _ := memcache.Get(ctx, "foo") - if item != nil { - fmt.Fprintln(res, string(item.Value)) + item, err := memcache.Get(ctx, "foo") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return } + fmt.Fprintln(w, string(item.Value)) } diff --git a/999_old-code/042_cookie_memcache/02_solution/01/app.yaml b/048_memcache/04_increment/app.yaml similarity index 100% rename from 999_old-code/042_cookie_memcache/02_solution/01/app.yaml rename to 048_memcache/04_increment/app.yaml diff --git a/999_old-code/041_memcache/04_increment/main.go b/048_memcache/04_increment/main.go similarity index 55% rename from 999_old-code/041_memcache/04_increment/main.go rename to 048_memcache/04_increment/main.go index 0fe12332..29dd33bc 100755 --- a/999_old-code/041_memcache/04_increment/main.go +++ b/048_memcache/04_increment/main.go @@ -13,25 +13,27 @@ func init() { http.HandleFunc("/", index) } -func index(res http.ResponseWriter, req *http.Request) { +func index(w http.ResponseWriter, r *http.Request) { - if req.URL.Path != "/" { - http.NotFound(res, req) + if r.URL.Path != "/" { + http.NotFound(w, r) return } - ctx := appengine.NewContext(req) + ctx := appengine.NewContext(r) u := user.Current(ctx) globalCount, err := memcache.Increment(ctx, "GLOBAL", 1, 0) if err != nil { - fmt.Println("1", err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return } + userCount, err := memcache.Increment(ctx, u.Email+".COUNTER", 1, 0) if err != nil { - fmt.Println("2", err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return } - fmt.Fprintln(res, "Global", globalCount) - fmt.Fprintln(res, "User", userCount) + fmt.Fprintln(w, "Global %v - User %v", globalCount, userCount) } diff --git a/999_old-code/042_cookie_memcache/01_challenge/instructions.md b/048_memcache/05_hands-on/instructions.md similarity index 100% rename from 999_old-code/042_cookie_memcache/01_challenge/instructions.md rename to 048_memcache/05_hands-on/instructions.md diff --git a/999_old-code/042_cookie_memcache/02_solution/02_refactor/app.yaml b/048_memcache/06_solution/01/app.yaml similarity index 100% rename from 999_old-code/042_cookie_memcache/02_solution/02_refactor/app.yaml rename to 048_memcache/06_solution/01/app.yaml diff --git a/999_old-code/042_cookie_memcache/02_solution/01/example.html b/048_memcache/06_solution/01/example.html similarity index 100% rename from 999_old-code/042_cookie_memcache/02_solution/01/example.html rename to 048_memcache/06_solution/01/example.html diff --git a/999_old-code/042_cookie_memcache/02_solution/01/main.go b/048_memcache/06_solution/01/main.go similarity index 51% rename from 999_old-code/042_cookie_memcache/02_solution/01/main.go rename to 048_memcache/06_solution/01/main.go index 5fd0cf5b..e133f4de 100755 --- a/999_old-code/042_cookie_memcache/02_solution/01/main.go +++ b/048_memcache/06_solution/01/main.go @@ -13,10 +13,10 @@ func init() { http.HandleFunc("/retrieve", noConfusion) } -func index(res http.ResponseWriter, req *http.Request) { +func index(w http.ResponseWriter, r *http.Request) { - if req.URL.Path != "/" { - http.NotFound(res, req) + if r.URL.Path != "/" { + http.NotFound(w, r) return } @@ -25,23 +25,25 @@ func index(res http.ResponseWriter, req *http.Request) { cookie := &http.Cookie{ Name: "session-id", Value: id.String(), - // Secure: true, - HttpOnly: true, } - http.SetCookie(res, cookie) + http.SetCookie(w, cookie) // set memcache - ctx := appengine.NewContext(req) + ctx := appengine.NewContext(r) item1 := memcache.Item{ Key: id.String(), Value: []byte("McLeod"), } - memcache.Set(ctx, &item1) + err := memcache.Set(ctx, &item1) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } - fmt.Fprint(res, "EVERYTHING SET ID:"+id.String()) + fmt.Fprint(w, "EVERYTHING SET ID:"+id.String()) } -func noConfusion(res http.ResponseWriter, req *http.Request) { +func noConfusion(w http.ResponseWriter, r *http.Request) { html := `
@@ -50,11 +52,15 @@ func noConfusion(res http.ResponseWriter, req *http.Request) { ` - if req.Method == "POST" { - id := req.FormValue("koala") + if r.Method == "POST" { + id := r.FormValue("koala") // get cookie value - cookie, _ := req.Cookie("session-id") + cookie, err := r.Cookie("session-id") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } if cookie != nil { html += `
@@ -63,8 +69,12 @@ func noConfusion(res http.ResponseWriter, req *http.Request) { } // get memcache value - ctx := appengine.NewContext(req) - item, _ := memcache.Get(ctx, id) + ctx := appengine.NewContext(r) + item, err := memcache.Get(ctx, id) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } if item != nil { html += `
@@ -74,6 +84,6 @@ func noConfusion(res http.ResponseWriter, req *http.Request) { ` } } - res.Header().Set("Content-Type", "text/html; charset=utf-8") - fmt.Fprint(res, html) + w.Header().Set("Content-Type", "text/html; charset=utf-8") + fmt.Fprint(w, html) } diff --git a/999_old-code/043_photo-blog_cookie_memcache/02_solution/app.yaml b/048_memcache/06_solution/02_refactor/app.yaml similarity index 100% rename from 999_old-code/043_photo-blog_cookie_memcache/02_solution/app.yaml rename to 048_memcache/06_solution/02_refactor/app.yaml diff --git a/999_old-code/042_cookie_memcache/02_solution/02_refactor/example.html b/048_memcache/06_solution/02_refactor/example.html similarity index 100% rename from 999_old-code/042_cookie_memcache/02_solution/02_refactor/example.html rename to 048_memcache/06_solution/02_refactor/example.html diff --git a/999_old-code/042_cookie_memcache/02_solution/02_refactor/main.go b/048_memcache/06_solution/02_refactor/main.go similarity index 63% rename from 999_old-code/042_cookie_memcache/02_solution/02_refactor/main.go rename to 048_memcache/06_solution/02_refactor/main.go index ad87848b..18bc377d 100755 --- a/999_old-code/042_cookie_memcache/02_solution/02_refactor/main.go +++ b/048_memcache/06_solution/02_refactor/main.go @@ -13,10 +13,10 @@ func init() { http.HandleFunc("/retrieve", noConfusion) } -func index(res http.ResponseWriter, req *http.Request) { +func index(w http.ResponseWriter, r *http.Request) { - if req.URL.Path != "/" { - http.NotFound(res, req) + if r.URL.Path != "/" { + http.NotFound(w, r) return } @@ -28,26 +28,30 @@ func index(res http.ResponseWriter, req *http.Request) { // Secure: true, HttpOnly: true, } - http.SetCookie(res, cookie) + http.SetCookie(w, cookie) // set memcache - ctx := appengine.NewContext(req) + ctx := appengine.NewContext(r) item1 := memcache.Item{ Key: id.String(), Value: []byte("McLeod"), } memcache.Set(ctx, &item1) - fmt.Fprint(res, "EVERYTHING SET ID:"+id.String()) + fmt.Fprint(w, "EVERYTHING SET ID:"+id.String()) } -func noConfusion(res http.ResponseWriter, req *http.Request) { +func noConfusion(w http.ResponseWriter, r *http.Request) { var html string // get cookie value var id string - cookie, _ := req.Cookie("session-id") + cookie, err := r.Cookie("session-id") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } if cookie != nil { id = cookie.Value html += ` @@ -57,7 +61,7 @@ func noConfusion(res http.ResponseWriter, req *http.Request) { } // get memcache value - ctx := appengine.NewContext(req) + ctx := appengine.NewContext(r) item, _ := memcache.Get(ctx, id) if item != nil { html += ` @@ -68,6 +72,6 @@ func noConfusion(res http.ResponseWriter, req *http.Request) { ` } - res.Header().Set("Content-Type", "text/html; charset=utf-8") - fmt.Fprint(res, html) + w.Header().Set("Content-Type", "text/html; charset=utf-8") + fmt.Fprint(w, html) } diff --git a/999_old-code/044_datastore/01_datastore-readme/ds01.png b/049_datastore/01_datastore-readme/ds01.png similarity index 100% rename from 999_old-code/044_datastore/01_datastore-readme/ds01.png rename to 049_datastore/01_datastore-readme/ds01.png diff --git a/999_old-code/044_datastore/01_datastore-readme/ds02.png b/049_datastore/01_datastore-readme/ds02.png similarity index 100% rename from 999_old-code/044_datastore/01_datastore-readme/ds02.png rename to 049_datastore/01_datastore-readme/ds02.png diff --git a/999_old-code/044_datastore/01_datastore-readme/ds03.png b/049_datastore/01_datastore-readme/ds03.png similarity index 100% rename from 999_old-code/044_datastore/01_datastore-readme/ds03.png rename to 049_datastore/01_datastore-readme/ds03.png diff --git a/999_old-code/044_datastore/01_datastore-readme/notes.txt b/049_datastore/01_datastore-readme/notes.txt similarity index 76% rename from 999_old-code/044_datastore/01_datastore-readme/notes.txt rename to 049_datastore/01_datastore-readme/notes.txt index 2985d647..dde9f92e 100755 --- a/999_old-code/044_datastore/01_datastore-readme/notes.txt +++ b/049_datastore/01_datastore-readme/notes.txt @@ -1,17 +1,17 @@ Generally speaking: SQL DATABASES --does not scale well +-does not scale -strongly consistent --durable +-persistent / durable NOSQL DATABASES --scales well +-scales -eventually consistent --durable +-persistent / durable MEMCACHE --scales well +-scales -strongly consistent -volatile diff --git a/999_old-code/044_datastore/02_put_NewKey_string/app.yaml b/049_datastore/02_put_NewKey_string/app.yaml similarity index 100% rename from 999_old-code/044_datastore/02_put_NewKey_string/app.yaml rename to 049_datastore/02_put_NewKey_string/app.yaml diff --git a/999_old-code/044_datastore/02_put_NewKey_string/words.go b/049_datastore/02_put_NewKey_string/words.go similarity index 100% rename from 999_old-code/044_datastore/02_put_NewKey_string/words.go rename to 049_datastore/02_put_NewKey_string/words.go diff --git a/999_old-code/044_datastore/03_get_NewKey_string/app.yaml b/049_datastore/03_get_NewKey_string/app.yaml similarity index 100% rename from 999_old-code/044_datastore/03_get_NewKey_string/app.yaml rename to 049_datastore/03_get_NewKey_string/app.yaml diff --git a/999_old-code/044_datastore/03_get_NewKey_string/words.go b/049_datastore/03_get_NewKey_string/words.go similarity index 100% rename from 999_old-code/044_datastore/03_get_NewKey_string/words.go rename to 049_datastore/03_get_NewKey_string/words.go diff --git a/999_old-code/044_datastore/04_get_NewKey_int64/app.yaml b/049_datastore/04_get_NewKey_int64/app.yaml similarity index 100% rename from 999_old-code/044_datastore/04_get_NewKey_int64/app.yaml rename to 049_datastore/04_get_NewKey_int64/app.yaml diff --git a/999_old-code/044_datastore/04_get_NewKey_int64/words.go b/049_datastore/04_get_NewKey_int64/words.go similarity index 100% rename from 999_old-code/044_datastore/04_get_NewKey_int64/words.go rename to 049_datastore/04_get_NewKey_int64/words.go diff --git a/999_old-code/044_datastore/05_put_NewIncompleteKey/app.yaml b/049_datastore/05_put_NewIncompleteKey/app.yaml similarity index 100% rename from 999_old-code/044_datastore/05_put_NewIncompleteKey/app.yaml rename to 049_datastore/05_put_NewIncompleteKey/app.yaml diff --git a/999_old-code/044_datastore/05_put_NewIncompleteKey/words.go b/049_datastore/05_put_NewIncompleteKey/words.go similarity index 100% rename from 999_old-code/044_datastore/05_put_NewIncompleteKey/words.go rename to 049_datastore/05_put_NewIncompleteKey/words.go diff --git a/999_old-code/044_datastore/06_put_get_doc-example/app.yaml b/049_datastore/06_put_get_doc-example/app.yaml similarity index 100% rename from 999_old-code/044_datastore/06_put_get_doc-example/app.yaml rename to 049_datastore/06_put_get_doc-example/app.yaml diff --git a/999_old-code/044_datastore/06_put_get_doc-example/employee.go b/049_datastore/06_put_get_doc-example/employee.go similarity index 100% rename from 999_old-code/044_datastore/06_put_get_doc-example/employee.go rename to 049_datastore/06_put_get_doc-example/employee.go diff --git a/999_old-code/044_datastore/06_put_get_doc-example/source.txt b/049_datastore/06_put_get_doc-example/source.txt similarity index 100% rename from 999_old-code/044_datastore/06_put_get_doc-example/source.txt rename to 049_datastore/06_put_get_doc-example/source.txt diff --git a/999_old-code/044_datastore/07_put_get_doc-example/app.yaml b/049_datastore/07_put_get_doc-example/app.yaml similarity index 100% rename from 999_old-code/044_datastore/07_put_get_doc-example/app.yaml rename to 049_datastore/07_put_get_doc-example/app.yaml diff --git a/999_old-code/044_datastore/07_put_get_doc-example/source.txt b/049_datastore/07_put_get_doc-example/source.txt similarity index 100% rename from 999_old-code/044_datastore/07_put_get_doc-example/source.txt rename to 049_datastore/07_put_get_doc-example/source.txt diff --git a/999_old-code/044_datastore/07_put_get_doc-example/url-path.go b/049_datastore/07_put_get_doc-example/url-path.go similarity index 100% rename from 999_old-code/044_datastore/07_put_get_doc-example/url-path.go rename to 049_datastore/07_put_get_doc-example/url-path.go diff --git a/999_old-code/044_datastore/08_query-iterator/app.yaml b/049_datastore/08_query-iterator/app.yaml similarity index 100% rename from 999_old-code/044_datastore/08_query-iterator/app.yaml rename to 049_datastore/08_query-iterator/app.yaml diff --git a/999_old-code/044_datastore/08_query-iterator/words.go b/049_datastore/08_query-iterator/words.go similarity index 100% rename from 999_old-code/044_datastore/08_query-iterator/words.go rename to 049_datastore/08_query-iterator/words.go diff --git a/999_old-code/044_datastore/09_put_NewKey_string_parent/01/app.yaml b/049_datastore/09_put_NewKey_string_parent/01/app.yaml similarity index 100% rename from 999_old-code/044_datastore/09_put_NewKey_string_parent/01/app.yaml rename to 049_datastore/09_put_NewKey_string_parent/01/app.yaml diff --git a/999_old-code/044_datastore/09_put_NewKey_string_parent/01/tools.go b/049_datastore/09_put_NewKey_string_parent/01/tools.go similarity index 100% rename from 999_old-code/044_datastore/09_put_NewKey_string_parent/01/tools.go rename to 049_datastore/09_put_NewKey_string_parent/01/tools.go diff --git a/999_old-code/044_datastore/09_put_NewKey_string_parent/02_html-select/main.go b/049_datastore/09_put_NewKey_string_parent/02_html-select/main.go similarity index 100% rename from 999_old-code/044_datastore/09_put_NewKey_string_parent/02_html-select/main.go rename to 049_datastore/09_put_NewKey_string_parent/02_html-select/main.go diff --git a/999_old-code/044_datastore/09_put_NewKey_string_parent/03/app.yaml b/049_datastore/09_put_NewKey_string_parent/03/app.yaml similarity index 100% rename from 999_old-code/044_datastore/09_put_NewKey_string_parent/03/app.yaml rename to 049_datastore/09_put_NewKey_string_parent/03/app.yaml diff --git a/999_old-code/044_datastore/09_put_NewKey_string_parent/03/tools.go b/049_datastore/09_put_NewKey_string_parent/03/tools.go similarity index 100% rename from 999_old-code/044_datastore/09_put_NewKey_string_parent/03/tools.go rename to 049_datastore/09_put_NewKey_string_parent/03/tools.go diff --git a/999_old-code/044_datastore/10_query-iterator_ancestor/app.yaml b/049_datastore/10_query-iterator_ancestor/app.yaml similarity index 100% rename from 999_old-code/044_datastore/10_query-iterator_ancestor/app.yaml rename to 049_datastore/10_query-iterator_ancestor/app.yaml diff --git a/999_old-code/044_datastore/10_query-iterator_ancestor/tools.go b/049_datastore/10_query-iterator_ancestor/tools.go similarity index 100% rename from 999_old-code/044_datastore/10_query-iterator_ancestor/tools.go rename to 049_datastore/10_query-iterator_ancestor/tools.go diff --git a/999_old-code/051_gcs/01_setup/instructions.md b/050_cloud-storage/01_setup/instructions.md similarity index 100% rename from 999_old-code/051_gcs/01_setup/instructions.md rename to 050_cloud-storage/01_setup/instructions.md diff --git a/999_old-code/051_gcs/02_readme-overview/overview.md b/050_cloud-storage/02_readme-overview/overview.md similarity index 100% rename from 999_old-code/051_gcs/02_readme-overview/overview.md rename to 050_cloud-storage/02_readme-overview/overview.md diff --git a/999_old-code/051_gcs/03_put-file/00-example.html b/050_cloud-storage/03_put-file/00-example.html similarity index 100% rename from 999_old-code/051_gcs/03_put-file/00-example.html rename to 050_cloud-storage/03_put-file/00-example.html diff --git a/999_old-code/051_gcs/03_put-file/01-sample.txt b/050_cloud-storage/03_put-file/01-sample.txt similarity index 100% rename from 999_old-code/051_gcs/03_put-file/01-sample.txt rename to 050_cloud-storage/03_put-file/01-sample.txt diff --git a/999_old-code/051_gcs/03_put-file/02-sample.md b/050_cloud-storage/03_put-file/02-sample.md similarity index 100% rename from 999_old-code/051_gcs/03_put-file/02-sample.md rename to 050_cloud-storage/03_put-file/02-sample.md diff --git a/999_old-code/051_gcs/03_put-file/app.yaml b/050_cloud-storage/03_put-file/app.yaml similarity index 100% rename from 999_old-code/051_gcs/03_put-file/app.yaml rename to 050_cloud-storage/03_put-file/app.yaml diff --git a/999_old-code/051_gcs/03_put-file/cookie.go b/050_cloud-storage/03_put-file/cookie.go similarity index 100% rename from 999_old-code/051_gcs/03_put-file/cookie.go rename to 050_cloud-storage/03_put-file/cookie.go diff --git a/999_old-code/051_gcs/03_put-file/file.go b/050_cloud-storage/03_put-file/file.go similarity index 100% rename from 999_old-code/051_gcs/03_put-file/file.go rename to 050_cloud-storage/03_put-file/file.go diff --git a/999_old-code/051_gcs/03_put-file/main.go b/050_cloud-storage/03_put-file/main.go similarity index 100% rename from 999_old-code/051_gcs/03_put-file/main.go rename to 050_cloud-storage/03_put-file/main.go diff --git a/999_old-code/051_gcs/03_put-file/storage.go b/050_cloud-storage/03_put-file/storage.go similarity index 100% rename from 999_old-code/051_gcs/03_put-file/storage.go rename to 050_cloud-storage/03_put-file/storage.go diff --git a/999_old-code/051_gcs/04_get-file/01-sample.txt b/050_cloud-storage/04_get-file/01-sample.txt similarity index 100% rename from 999_old-code/051_gcs/04_get-file/01-sample.txt rename to 050_cloud-storage/04_get-file/01-sample.txt diff --git a/999_old-code/051_gcs/04_get-file/02-sample.md b/050_cloud-storage/04_get-file/02-sample.md similarity index 100% rename from 999_old-code/051_gcs/04_get-file/02-sample.md rename to 050_cloud-storage/04_get-file/02-sample.md diff --git a/999_old-code/051_gcs/04_get-file/app.yaml b/050_cloud-storage/04_get-file/app.yaml similarity index 100% rename from 999_old-code/051_gcs/04_get-file/app.yaml rename to 050_cloud-storage/04_get-file/app.yaml diff --git a/999_old-code/051_gcs/04_get-file/cookie.go b/050_cloud-storage/04_get-file/cookie.go similarity index 100% rename from 999_old-code/051_gcs/04_get-file/cookie.go rename to 050_cloud-storage/04_get-file/cookie.go diff --git a/999_old-code/051_gcs/04_get-file/file.go b/050_cloud-storage/04_get-file/file.go similarity index 100% rename from 999_old-code/051_gcs/04_get-file/file.go rename to 050_cloud-storage/04_get-file/file.go diff --git a/999_old-code/051_gcs/04_get-file/main.go b/050_cloud-storage/04_get-file/main.go similarity index 100% rename from 999_old-code/051_gcs/04_get-file/main.go rename to 050_cloud-storage/04_get-file/main.go diff --git a/999_old-code/051_gcs/04_get-file/storage.go b/050_cloud-storage/04_get-file/storage.go similarity index 100% rename from 999_old-code/051_gcs/04_get-file/storage.go rename to 050_cloud-storage/04_get-file/storage.go diff --git a/999_old-code/051_gcs/05_media-link/01.jpeg b/050_cloud-storage/05_media-link/01.jpeg similarity index 100% rename from 999_old-code/051_gcs/05_media-link/01.jpeg rename to 050_cloud-storage/05_media-link/01.jpeg diff --git a/999_old-code/051_gcs/05_media-link/02.jpeg b/050_cloud-storage/05_media-link/02.jpeg similarity index 100% rename from 999_old-code/051_gcs/05_media-link/02.jpeg rename to 050_cloud-storage/05_media-link/02.jpeg diff --git a/999_old-code/051_gcs/05_media-link/app.yaml b/050_cloud-storage/05_media-link/app.yaml similarity index 100% rename from 999_old-code/051_gcs/05_media-link/app.yaml rename to 050_cloud-storage/05_media-link/app.yaml diff --git a/999_old-code/051_gcs/05_media-link/cookie.go b/050_cloud-storage/05_media-link/cookie.go similarity index 100% rename from 999_old-code/051_gcs/05_media-link/cookie.go rename to 050_cloud-storage/05_media-link/cookie.go diff --git a/999_old-code/051_gcs/05_media-link/file.go b/050_cloud-storage/05_media-link/file.go similarity index 100% rename from 999_old-code/051_gcs/05_media-link/file.go rename to 050_cloud-storage/05_media-link/file.go diff --git a/999_old-code/051_gcs/05_media-link/main.go b/050_cloud-storage/05_media-link/main.go similarity index 100% rename from 999_old-code/051_gcs/05_media-link/main.go rename to 050_cloud-storage/05_media-link/main.go diff --git a/999_old-code/051_gcs/05_media-link/storage.go b/050_cloud-storage/05_media-link/storage.go similarity index 100% rename from 999_old-code/051_gcs/05_media-link/storage.go rename to 050_cloud-storage/05_media-link/storage.go diff --git a/999_old-code/051_gcs/06_display-img/01/01.jpeg b/050_cloud-storage/06_display-img/01/01.jpeg similarity index 100% rename from 999_old-code/051_gcs/06_display-img/01/01.jpeg rename to 050_cloud-storage/06_display-img/01/01.jpeg diff --git a/999_old-code/051_gcs/06_display-img/01/02.jpeg b/050_cloud-storage/06_display-img/01/02.jpeg similarity index 100% rename from 999_old-code/051_gcs/06_display-img/01/02.jpeg rename to 050_cloud-storage/06_display-img/01/02.jpeg diff --git a/999_old-code/051_gcs/06_display-img/01/app.yaml b/050_cloud-storage/06_display-img/01/app.yaml similarity index 100% rename from 999_old-code/051_gcs/06_display-img/01/app.yaml rename to 050_cloud-storage/06_display-img/01/app.yaml diff --git a/999_old-code/051_gcs/06_display-img/01/cookie.go b/050_cloud-storage/06_display-img/01/cookie.go similarity index 100% rename from 999_old-code/051_gcs/06_display-img/01/cookie.go rename to 050_cloud-storage/06_display-img/01/cookie.go diff --git a/999_old-code/051_gcs/06_display-img/01/file.go b/050_cloud-storage/06_display-img/01/file.go similarity index 100% rename from 999_old-code/051_gcs/06_display-img/01/file.go rename to 050_cloud-storage/06_display-img/01/file.go diff --git a/999_old-code/051_gcs/06_display-img/01/main.go b/050_cloud-storage/06_display-img/01/main.go similarity index 100% rename from 999_old-code/051_gcs/06_display-img/01/main.go rename to 050_cloud-storage/06_display-img/01/main.go diff --git a/999_old-code/051_gcs/06_display-img/01/storage.go b/050_cloud-storage/06_display-img/01/storage.go similarity index 100% rename from 999_old-code/051_gcs/06_display-img/01/storage.go rename to 050_cloud-storage/06_display-img/01/storage.go diff --git a/999_old-code/051_gcs/06_display-img/02_medialink/app.yaml b/050_cloud-storage/06_display-img/02_medialink/app.yaml similarity index 100% rename from 999_old-code/051_gcs/06_display-img/02_medialink/app.yaml rename to 050_cloud-storage/06_display-img/02_medialink/app.yaml diff --git a/999_old-code/051_gcs/06_display-img/02_medialink/main.go b/050_cloud-storage/06_display-img/02_medialink/main.go similarity index 100% rename from 999_old-code/051_gcs/06_display-img/02_medialink/main.go rename to 050_cloud-storage/06_display-img/02_medialink/main.go diff --git a/999_old-code/051_gcs/06_display-img/02_medialink/readme.md b/050_cloud-storage/06_display-img/02_medialink/readme.md similarity index 100% rename from 999_old-code/051_gcs/06_display-img/02_medialink/readme.md rename to 050_cloud-storage/06_display-img/02_medialink/readme.md diff --git a/999_old-code/051_gcs/07_list-files/app.yaml b/050_cloud-storage/07_list-files/app.yaml similarity index 100% rename from 999_old-code/051_gcs/07_list-files/app.yaml rename to 050_cloud-storage/07_list-files/app.yaml diff --git a/999_old-code/051_gcs/07_list-files/main.go b/050_cloud-storage/07_list-files/main.go similarity index 100% rename from 999_old-code/051_gcs/07_list-files/main.go rename to 050_cloud-storage/07_list-files/main.go diff --git a/999_old-code/051_gcs/08_object-attributes/app.yaml b/050_cloud-storage/08_object-attributes/app.yaml similarity index 100% rename from 999_old-code/051_gcs/08_object-attributes/app.yaml rename to 050_cloud-storage/08_object-attributes/app.yaml diff --git a/999_old-code/051_gcs/08_object-attributes/main.go b/050_cloud-storage/08_object-attributes/main.go similarity index 100% rename from 999_old-code/051_gcs/08_object-attributes/main.go rename to 050_cloud-storage/08_object-attributes/main.go diff --git a/999_old-code/051_gcs/09_query-maxresults/app.yaml b/050_cloud-storage/09_query-maxresults/app.yaml similarity index 100% rename from 999_old-code/051_gcs/09_query-maxresults/app.yaml rename to 050_cloud-storage/09_query-maxresults/app.yaml diff --git a/999_old-code/051_gcs/09_query-maxresults/main.go b/050_cloud-storage/09_query-maxresults/main.go similarity index 100% rename from 999_old-code/051_gcs/09_query-maxresults/main.go rename to 050_cloud-storage/09_query-maxresults/main.go diff --git a/999_old-code/051_gcs/10_query-maxresults_next/app.yaml b/050_cloud-storage/10_query-maxresults_next/app.yaml similarity index 100% rename from 999_old-code/051_gcs/10_query-maxresults_next/app.yaml rename to 050_cloud-storage/10_query-maxresults_next/app.yaml diff --git a/999_old-code/051_gcs/10_query-maxresults_next/main.go b/050_cloud-storage/10_query-maxresults_next/main.go similarity index 100% rename from 999_old-code/051_gcs/10_query-maxresults_next/main.go rename to 050_cloud-storage/10_query-maxresults_next/main.go diff --git a/999_old-code/051_gcs/11_query-prefix/app.yaml b/050_cloud-storage/11_query-prefix/app.yaml similarity index 100% rename from 999_old-code/051_gcs/11_query-prefix/app.yaml rename to 050_cloud-storage/11_query-prefix/app.yaml diff --git a/999_old-code/051_gcs/11_query-prefix/main.go b/050_cloud-storage/11_query-prefix/main.go similarity index 100% rename from 999_old-code/051_gcs/11_query-prefix/main.go rename to 050_cloud-storage/11_query-prefix/main.go diff --git a/999_old-code/051_gcs/12_query-delimeter/01/app.yaml b/050_cloud-storage/12_query-delimeter/01/app.yaml similarity index 100% rename from 999_old-code/051_gcs/12_query-delimeter/01/app.yaml rename to 050_cloud-storage/12_query-delimeter/01/app.yaml diff --git a/999_old-code/051_gcs/12_query-delimeter/01/main.go b/050_cloud-storage/12_query-delimeter/01/main.go similarity index 100% rename from 999_old-code/051_gcs/12_query-delimeter/01/main.go rename to 050_cloud-storage/12_query-delimeter/01/main.go diff --git a/999_old-code/051_gcs/12_query-delimeter/02/app.yaml b/050_cloud-storage/12_query-delimeter/02/app.yaml similarity index 100% rename from 999_old-code/051_gcs/12_query-delimeter/02/app.yaml rename to 050_cloud-storage/12_query-delimeter/02/app.yaml diff --git a/999_old-code/051_gcs/12_query-delimeter/02/main.go b/050_cloud-storage/12_query-delimeter/02/main.go similarity index 100% rename from 999_old-code/051_gcs/12_query-delimeter/02/main.go rename to 050_cloud-storage/12_query-delimeter/02/main.go diff --git a/999_old-code/051_gcs/13_query-prefix-delimeter/01/app.yaml b/050_cloud-storage/13_query-prefix-delimeter/01/app.yaml similarity index 100% rename from 999_old-code/051_gcs/13_query-prefix-delimeter/01/app.yaml rename to 050_cloud-storage/13_query-prefix-delimeter/01/app.yaml diff --git a/999_old-code/051_gcs/13_query-prefix-delimeter/01/main.go b/050_cloud-storage/13_query-prefix-delimeter/01/main.go similarity index 100% rename from 999_old-code/051_gcs/13_query-prefix-delimeter/01/main.go rename to 050_cloud-storage/13_query-prefix-delimeter/01/main.go diff --git a/999_old-code/051_gcs/13_query-prefix-delimeter/02/app.yaml b/050_cloud-storage/13_query-prefix-delimeter/02/app.yaml similarity index 100% rename from 999_old-code/051_gcs/13_query-prefix-delimeter/02/app.yaml rename to 050_cloud-storage/13_query-prefix-delimeter/02/app.yaml diff --git a/999_old-code/051_gcs/13_query-prefix-delimeter/02/main.go b/050_cloud-storage/13_query-prefix-delimeter/02/main.go similarity index 100% rename from 999_old-code/051_gcs/13_query-prefix-delimeter/02/main.go rename to 050_cloud-storage/13_query-prefix-delimeter/02/main.go diff --git a/999_old-code/051_gcs/13_query-prefix-delimeter/03/app.yaml b/050_cloud-storage/13_query-prefix-delimeter/03/app.yaml similarity index 100% rename from 999_old-code/051_gcs/13_query-prefix-delimeter/03/app.yaml rename to 050_cloud-storage/13_query-prefix-delimeter/03/app.yaml diff --git a/999_old-code/051_gcs/13_query-prefix-delimeter/03/main.go b/050_cloud-storage/13_query-prefix-delimeter/03/main.go similarity index 100% rename from 999_old-code/051_gcs/13_query-prefix-delimeter/03/main.go rename to 050_cloud-storage/13_query-prefix-delimeter/03/main.go diff --git a/999_old-code/051_gcs/13_query-prefix-delimeter/04/app.yaml b/050_cloud-storage/13_query-prefix-delimeter/04/app.yaml similarity index 100% rename from 999_old-code/051_gcs/13_query-prefix-delimeter/04/app.yaml rename to 050_cloud-storage/13_query-prefix-delimeter/04/app.yaml diff --git a/999_old-code/051_gcs/13_query-prefix-delimeter/04/main.go b/050_cloud-storage/13_query-prefix-delimeter/04/main.go similarity index 100% rename from 999_old-code/051_gcs/13_query-prefix-delimeter/04/main.go rename to 050_cloud-storage/13_query-prefix-delimeter/04/main.go diff --git a/999_old-code/051_gcs/13_query-prefix-delimeter/05_recursive/app.yaml b/050_cloud-storage/13_query-prefix-delimeter/05_recursive/app.yaml similarity index 100% rename from 999_old-code/051_gcs/13_query-prefix-delimeter/05_recursive/app.yaml rename to 050_cloud-storage/13_query-prefix-delimeter/05_recursive/app.yaml diff --git a/999_old-code/051_gcs/13_query-prefix-delimeter/05_recursive/main.go b/050_cloud-storage/13_query-prefix-delimeter/05_recursive/main.go similarity index 100% rename from 999_old-code/051_gcs/13_query-prefix-delimeter/05_recursive/main.go rename to 050_cloud-storage/13_query-prefix-delimeter/05_recursive/main.go diff --git a/999_old-code/051_gcs/14_acl/01_readme/readme.md b/050_cloud-storage/14_acl/01_readme/readme.md similarity index 100% rename from 999_old-code/051_gcs/14_acl/01_readme/readme.md rename to 050_cloud-storage/14_acl/01_readme/readme.md diff --git a/999_old-code/051_gcs/14_acl/02_allusers_rolereader/app.yaml b/050_cloud-storage/14_acl/02_allusers_rolereader/app.yaml similarity index 100% rename from 999_old-code/051_gcs/14_acl/02_allusers_rolereader/app.yaml rename to 050_cloud-storage/14_acl/02_allusers_rolereader/app.yaml diff --git a/999_old-code/051_gcs/14_acl/02_allusers_rolereader/main.go b/050_cloud-storage/14_acl/02_allusers_rolereader/main.go similarity index 100% rename from 999_old-code/051_gcs/14_acl/02_allusers_rolereader/main.go rename to 050_cloud-storage/14_acl/02_allusers_rolereader/main.go diff --git a/999_old-code/051_gcs/14_acl/03_default/app.yaml b/050_cloud-storage/14_acl/03_default/app.yaml similarity index 100% rename from 999_old-code/051_gcs/14_acl/03_default/app.yaml rename to 050_cloud-storage/14_acl/03_default/app.yaml diff --git a/999_old-code/051_gcs/14_acl/03_default/main.go b/050_cloud-storage/14_acl/03_default/main.go similarity index 100% rename from 999_old-code/051_gcs/14_acl/03_default/main.go rename to 050_cloud-storage/14_acl/03_default/main.go diff --git a/999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/01-sample.txt b/050_cloud-storage/14_acl/04_permission-to-gmail-account/01-sample.txt similarity index 100% rename from 999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/01-sample.txt rename to 050_cloud-storage/14_acl/04_permission-to-gmail-account/01-sample.txt diff --git a/999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/02-sample.md b/050_cloud-storage/14_acl/04_permission-to-gmail-account/02-sample.md similarity index 100% rename from 999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/02-sample.md rename to 050_cloud-storage/14_acl/04_permission-to-gmail-account/02-sample.md diff --git a/999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/app.yaml b/050_cloud-storage/14_acl/04_permission-to-gmail-account/app.yaml similarity index 100% rename from 999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/app.yaml rename to 050_cloud-storage/14_acl/04_permission-to-gmail-account/app.yaml diff --git a/999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/cookie.go b/050_cloud-storage/14_acl/04_permission-to-gmail-account/cookie.go similarity index 100% rename from 999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/cookie.go rename to 050_cloud-storage/14_acl/04_permission-to-gmail-account/cookie.go diff --git a/999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/file.go b/050_cloud-storage/14_acl/04_permission-to-gmail-account/file.go similarity index 100% rename from 999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/file.go rename to 050_cloud-storage/14_acl/04_permission-to-gmail-account/file.go diff --git a/999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/main.go b/050_cloud-storage/14_acl/04_permission-to-gmail-account/main.go similarity index 100% rename from 999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/main.go rename to 050_cloud-storage/14_acl/04_permission-to-gmail-account/main.go diff --git a/999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/storage.go b/050_cloud-storage/14_acl/04_permission-to-gmail-account/storage.go similarity index 100% rename from 999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/storage.go rename to 050_cloud-storage/14_acl/04_permission-to-gmail-account/storage.go diff --git a/999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/xxmain.go b/050_cloud-storage/14_acl/04_permission-to-gmail-account/xxmain.go similarity index 100% rename from 999_old-code/051_gcs/14_acl/04_permission-to-gmail-account/xxmain.go rename to 050_cloud-storage/14_acl/04_permission-to-gmail-account/xxmain.go diff --git a/999_old-code/051_gcs/15_file-browser/01_create-files/app.yaml b/050_cloud-storage/15_file-browser/01_create-files/app.yaml similarity index 100% rename from 999_old-code/051_gcs/15_file-browser/01_create-files/app.yaml rename to 050_cloud-storage/15_file-browser/01_create-files/app.yaml diff --git a/999_old-code/051_gcs/15_file-browser/01_create-files/main.go b/050_cloud-storage/15_file-browser/01_create-files/main.go similarity index 100% rename from 999_old-code/051_gcs/15_file-browser/01_create-files/main.go rename to 050_cloud-storage/15_file-browser/01_create-files/main.go diff --git a/999_old-code/051_gcs/15_file-browser/02_browse/README.txt b/050_cloud-storage/15_file-browser/02_browse/README.txt similarity index 100% rename from 999_old-code/051_gcs/15_file-browser/02_browse/README.txt rename to 050_cloud-storage/15_file-browser/02_browse/README.txt diff --git a/999_old-code/051_gcs/15_file-browser/02_browse/app.yaml b/050_cloud-storage/15_file-browser/02_browse/app.yaml similarity index 100% rename from 999_old-code/051_gcs/15_file-browser/02_browse/app.yaml rename to 050_cloud-storage/15_file-browser/02_browse/app.yaml diff --git a/999_old-code/051_gcs/15_file-browser/02_browse/routes.go b/050_cloud-storage/15_file-browser/02_browse/routes.go similarity index 100% rename from 999_old-code/051_gcs/15_file-browser/02_browse/routes.go rename to 050_cloud-storage/15_file-browser/02_browse/routes.go diff --git a/999_old-code/051_gcs/15_file-browser/02_browse/session.go b/050_cloud-storage/15_file-browser/02_browse/session.go similarity index 100% rename from 999_old-code/051_gcs/15_file-browser/02_browse/session.go rename to 050_cloud-storage/15_file-browser/02_browse/session.go diff --git a/999_old-code/051_gcs/15_file-browser/02_browse/storage.go b/050_cloud-storage/15_file-browser/02_browse/storage.go similarity index 100% rename from 999_old-code/051_gcs/15_file-browser/02_browse/storage.go rename to 050_cloud-storage/15_file-browser/02_browse/storage.go diff --git a/999_old-code/051_gcs/15_file-browser/02_browse/templates/browse.html b/050_cloud-storage/15_file-browser/02_browse/templates/browse.html similarity index 100% rename from 999_old-code/051_gcs/15_file-browser/02_browse/templates/browse.html rename to 050_cloud-storage/15_file-browser/02_browse/templates/browse.html diff --git a/999_old-code/051_gcs/15_file-browser/02_browse/templates/index.html b/050_cloud-storage/15_file-browser/02_browse/templates/index.html similarity index 100% rename from 999_old-code/051_gcs/15_file-browser/02_browse/templates/index.html rename to 050_cloud-storage/15_file-browser/02_browse/templates/index.html diff --git a/999_old-code/051_gcs/16_gcs-example/app.yaml b/050_cloud-storage/16_gcs-example/app.yaml similarity index 100% rename from 999_old-code/051_gcs/16_gcs-example/app.yaml rename to 050_cloud-storage/16_gcs-example/app.yaml diff --git a/999_old-code/051_gcs/16_gcs-example/main.go b/050_cloud-storage/16_gcs-example/main.go similarity index 100% rename from 999_old-code/051_gcs/16_gcs-example/main.go rename to 050_cloud-storage/16_gcs-example/main.go diff --git a/999_old-code/051_gcs/17_challenge/01_helpful-starting-code/00-example.html b/050_cloud-storage/17_challenge/01_helpful-starting-code/00-example.html similarity index 100% rename from 999_old-code/051_gcs/17_challenge/01_helpful-starting-code/00-example.html rename to 050_cloud-storage/17_challenge/01_helpful-starting-code/00-example.html diff --git a/999_old-code/051_gcs/17_challenge/01_helpful-starting-code/01-sample.txt b/050_cloud-storage/17_challenge/01_helpful-starting-code/01-sample.txt similarity index 100% rename from 999_old-code/051_gcs/17_challenge/01_helpful-starting-code/01-sample.txt rename to 050_cloud-storage/17_challenge/01_helpful-starting-code/01-sample.txt diff --git a/999_old-code/051_gcs/17_challenge/01_helpful-starting-code/02-sample.md b/050_cloud-storage/17_challenge/01_helpful-starting-code/02-sample.md similarity index 100% rename from 999_old-code/051_gcs/17_challenge/01_helpful-starting-code/02-sample.md rename to 050_cloud-storage/17_challenge/01_helpful-starting-code/02-sample.md diff --git a/999_old-code/051_gcs/17_challenge/01_helpful-starting-code/app.yaml b/050_cloud-storage/17_challenge/01_helpful-starting-code/app.yaml similarity index 100% rename from 999_old-code/051_gcs/17_challenge/01_helpful-starting-code/app.yaml rename to 050_cloud-storage/17_challenge/01_helpful-starting-code/app.yaml diff --git a/999_old-code/051_gcs/17_challenge/01_helpful-starting-code/cookie.go b/050_cloud-storage/17_challenge/01_helpful-starting-code/cookie.go similarity index 100% rename from 999_old-code/051_gcs/17_challenge/01_helpful-starting-code/cookie.go rename to 050_cloud-storage/17_challenge/01_helpful-starting-code/cookie.go diff --git a/999_old-code/051_gcs/17_challenge/01_helpful-starting-code/file.go b/050_cloud-storage/17_challenge/01_helpful-starting-code/file.go similarity index 100% rename from 999_old-code/051_gcs/17_challenge/01_helpful-starting-code/file.go rename to 050_cloud-storage/17_challenge/01_helpful-starting-code/file.go diff --git a/999_old-code/051_gcs/17_challenge/01_helpful-starting-code/main.go b/050_cloud-storage/17_challenge/01_helpful-starting-code/main.go similarity index 100% rename from 999_old-code/051_gcs/17_challenge/01_helpful-starting-code/main.go rename to 050_cloud-storage/17_challenge/01_helpful-starting-code/main.go diff --git a/999_old-code/051_gcs/17_challenge/01_helpful-starting-code/storage.go b/050_cloud-storage/17_challenge/01_helpful-starting-code/storage.go similarity index 100% rename from 999_old-code/051_gcs/17_challenge/01_helpful-starting-code/storage.go rename to 050_cloud-storage/17_challenge/01_helpful-starting-code/storage.go diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/INSTRUCTIONS.txt b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/INSTRUCTIONS.txt similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/INSTRUCTIONS.txt rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/INSTRUCTIONS.txt diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/app.yaml b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/app.yaml similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/app.yaml rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/app.yaml diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/credit.txt b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/credit.txt similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/credit.txt rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/credit.txt diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/css/main.css b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/css/main.css similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/css/main.css rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/css/main.css diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/css/mq_500-less_images.css b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/css/mq_500-less_images.css similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/css/mq_500-less_images.css rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/css/mq_500-less_images.css diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/css/mq_501-plus.css b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/css/mq_501-plus.css similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/css/mq_501-plus.css rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/css/mq_501-plus.css diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/css/mq_900-plus.css b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/css/mq_900-plus.css similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/css/mq_900-plus.css rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/css/mq_900-plus.css diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/file.go b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/file.go similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/file.go rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/file.go diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/img/adventure-lg.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/img/adventure-lg.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/img/adventure-lg.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/img/adventure-lg.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/img/adventure-sm.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/img/adventure-sm.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/img/adventure-sm.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/img/adventure-sm.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/index.html b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/index.html similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/index.html rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/index.html diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/main.go b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/main.go similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/main.go rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/main.go diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/0.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/0.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/0.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/0.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/10.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/10.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/10.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/10.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/11.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/11.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/11.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/11.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/12.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/12.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/12.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/12.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/13.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/13.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/13.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/13.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/14.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/14.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/14.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/14.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/15.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/15.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/15.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/15.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/16.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/16.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/16.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/16.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/17.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/17.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/17.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/17.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/18.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/18.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/18.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/18.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/19.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/19.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/19.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/19.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/2.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/2.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/2.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/2.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/20.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/20.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/20.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/20.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/21.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/21.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/21.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/21.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/22.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/22.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/22.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/22.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/23.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/23.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/23.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/23.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/24.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/24.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/24.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/24.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/3.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/3.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/3.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/3.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/4.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/4.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/4.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/4.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/5.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/5.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/5.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/5.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/6.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/6.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/6.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/6.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/7.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/7.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/7.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/7.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/8.jpg b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/8.jpg similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/photos/8.jpg rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/photos/8.jpg diff --git a/999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/storage.go b/050_cloud-storage/17_challenge/02_solutions/01_one-solution/storage.go similarity index 100% rename from 999_old-code/051_gcs/17_challenge/02_solutions/01_one-solution/storage.go rename to 050_cloud-storage/17_challenge/02_solutions/01_one-solution/storage.go diff --git a/999_old-code/054_ajax/02_users_datastore_schmidt-router/app.yaml b/999_old-code/00_temp/xx02_users_datastore_schmidt-router/app.yaml old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/02_users_datastore_schmidt-router/app.yaml rename to 999_old-code/00_temp/xx02_users_datastore_schmidt-router/app.yaml diff --git a/999_old-code/054_ajax/02_users_datastore_schmidt-router/main.go b/999_old-code/00_temp/xx02_users_datastore_schmidt-router/main.go old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/02_users_datastore_schmidt-router/main.go rename to 999_old-code/00_temp/xx02_users_datastore_schmidt-router/main.go diff --git a/999_old-code/054_ajax/02_users_datastore_schmidt-router/templates/index.html b/999_old-code/00_temp/xx02_users_datastore_schmidt-router/templates/index.html old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/02_users_datastore_schmidt-router/templates/index.html rename to 999_old-code/00_temp/xx02_users_datastore_schmidt-router/templates/index.html diff --git a/999_old-code/054_ajax/03_entry-checker_challenge/01_instructions/index.html b/999_old-code/00_temp/xx03_entry-checker_challenge/01_instructions/index.html old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/03_entry-checker_challenge/01_instructions/index.html rename to 999_old-code/00_temp/xx03_entry-checker_challenge/01_instructions/index.html diff --git a/999_old-code/054_ajax/03_entry-checker_challenge/01_instructions/main.css b/999_old-code/00_temp/xx03_entry-checker_challenge/01_instructions/main.css old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/03_entry-checker_challenge/01_instructions/main.css rename to 999_old-code/00_temp/xx03_entry-checker_challenge/01_instructions/main.css diff --git a/999_old-code/054_ajax/03_entry-checker_challenge/01_instructions/main.js b/999_old-code/00_temp/xx03_entry-checker_challenge/01_instructions/main.js old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/03_entry-checker_challenge/01_instructions/main.js rename to 999_old-code/00_temp/xx03_entry-checker_challenge/01_instructions/main.js diff --git a/999_old-code/054_ajax/03_entry-checker_challenge/01_instructions/readme.txt b/999_old-code/00_temp/xx03_entry-checker_challenge/01_instructions/readme.txt old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/03_entry-checker_challenge/01_instructions/readme.txt rename to 999_old-code/00_temp/xx03_entry-checker_challenge/01_instructions/readme.txt diff --git a/999_old-code/054_ajax/03_entry-checker_challenge/02_solution/01_without-json/app.yaml b/999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/01_without-json/app.yaml old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/03_entry-checker_challenge/02_solution/01_without-json/app.yaml rename to 999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/01_without-json/app.yaml diff --git a/999_old-code/054_ajax/03_entry-checker_challenge/02_solution/01_without-json/index.html b/999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/01_without-json/index.html old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/03_entry-checker_challenge/02_solution/01_without-json/index.html rename to 999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/01_without-json/index.html diff --git a/999_old-code/054_ajax/03_entry-checker_challenge/02_solution/01_without-json/main.go b/999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/01_without-json/main.go old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/03_entry-checker_challenge/02_solution/01_without-json/main.go rename to 999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/01_without-json/main.go diff --git a/999_old-code/054_ajax/03_entry-checker_challenge/02_solution/01_without-json/public/main.css b/999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/01_without-json/public/main.css old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/03_entry-checker_challenge/02_solution/01_without-json/public/main.css rename to 999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/01_without-json/public/main.css diff --git a/999_old-code/054_ajax/03_entry-checker_challenge/02_solution/01_without-json/public/main.js b/999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/01_without-json/public/main.js old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/03_entry-checker_challenge/02_solution/01_without-json/public/main.js rename to 999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/01_without-json/public/main.js diff --git a/999_old-code/054_ajax/03_entry-checker_challenge/02_solution/02_with-json/app.yaml b/999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/02_with-json/app.yaml old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/03_entry-checker_challenge/02_solution/02_with-json/app.yaml rename to 999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/02_with-json/app.yaml diff --git a/999_old-code/054_ajax/03_entry-checker_challenge/02_solution/02_with-json/index.html b/999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/02_with-json/index.html old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/03_entry-checker_challenge/02_solution/02_with-json/index.html rename to 999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/02_with-json/index.html diff --git a/999_old-code/054_ajax/03_entry-checker_challenge/02_solution/02_with-json/main.go b/999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/02_with-json/main.go old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/03_entry-checker_challenge/02_solution/02_with-json/main.go rename to 999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/02_with-json/main.go diff --git a/999_old-code/054_ajax/03_entry-checker_challenge/02_solution/02_with-json/public/main.css b/999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/02_with-json/public/main.css old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/03_entry-checker_challenge/02_solution/02_with-json/public/main.css rename to 999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/02_with-json/public/main.css diff --git a/999_old-code/054_ajax/03_entry-checker_challenge/02_solution/02_with-json/public/main.js b/999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/02_with-json/public/main.js old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/03_entry-checker_challenge/02_solution/02_with-json/public/main.js rename to 999_old-code/00_temp/xx03_entry-checker_challenge/02_solution/02_with-json/public/main.js diff --git a/999_old-code/054_ajax/04_todo-list/app.yaml b/999_old-code/00_temp/xx04_todo-list/app.yaml old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/04_todo-list/app.yaml rename to 999_old-code/00_temp/xx04_todo-list/app.yaml diff --git a/999_old-code/054_ajax/04_todo-list/index.html b/999_old-code/00_temp/xx04_todo-list/index.html old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/04_todo-list/index.html rename to 999_old-code/00_temp/xx04_todo-list/index.html diff --git a/999_old-code/054_ajax/04_todo-list/main.go b/999_old-code/00_temp/xx04_todo-list/main.go old mode 100755 new mode 100644 similarity index 100% rename from 999_old-code/054_ajax/04_todo-list/main.go rename to 999_old-code/00_temp/xx04_todo-list/main.go diff --git a/999_old-code/040_appengine-introduction/02_hello-user/hello.go b/999_old-code/040_appengine-introduction/02_hello-user/hello.go deleted file mode 100755 index 7e634ab5..00000000 --- a/999_old-code/040_appengine-introduction/02_hello-user/hello.go +++ /dev/null @@ -1,29 +0,0 @@ -package hello - -import ( - "fmt" - "net/http" - - "google.golang.org/appengine" - "google.golang.org/appengine/user" -) - -func init() { - http.HandleFunc("/", index) -} - -func index(res http.ResponseWriter, req *http.Request) { - ctx := appengine.NewContext(req) - u := user.Current(ctx) - if u == nil { - url, err := user.LoginURL(ctx, req.URL.String()) - if err != nil { - http.Error(res, err.Error(), http.StatusInternalServerError) - return - } - res.Header().Set("Location", url) - res.WriteHeader(http.StatusFound) - return - } - fmt.Fprintf(res, "Hello, %v", u) -} diff --git a/999_old-code/040_appengine-introduction/03_user/main.go b/999_old-code/040_appengine-introduction/03_user/main.go deleted file mode 100755 index 0cfb8f60..00000000 --- a/999_old-code/040_appengine-introduction/03_user/main.go +++ /dev/null @@ -1,32 +0,0 @@ -package main - -import ( - "fmt" - "net/http" - - "google.golang.org/appengine" - "google.golang.org/appengine/user" -) - -func init() { - http.HandleFunc("/", index) - http.HandleFunc("/admin/", admin) -} - -func index(res http.ResponseWriter, req *http.Request) { - ctx := appengine.NewContext(req) - u := user.Current(ctx) - url, _ := user.LogoutURL(ctx, "/") - res.Header().Set("Content-Type", "text/html") - fmt.Fprintf(res, `Welcome, %s! (sign out)`, u, url) - -} - -func admin(res http.ResponseWriter, req *http.Request) { - ctx := appengine.NewContext(req) - u := user.Current(ctx) - url, _ := user.LogoutURL(ctx, "/") - res.Header().Set("Content-Type", "text/html") - fmt.Fprintf(res, `Welcome ADMIN, %s! (sign out)`, u, url) - -} diff --git a/999_old-code/041_memcache/01_get-nil/main.go b/999_old-code/041_memcache/01_get-nil/main.go deleted file mode 100755 index cf74b04c..00000000 --- a/999_old-code/041_memcache/01_get-nil/main.go +++ /dev/null @@ -1,20 +0,0 @@ -package main - -import ( - "fmt" - "net/http" -) -import ( - "google.golang.org/appengine" - "google.golang.org/appengine/memcache" -) - -func init() { - http.HandleFunc("/", index) -} - -func index(res http.ResponseWriter, req *http.Request) { - ctx := appengine.NewContext(req) - item, _ := memcache.Get(ctx, "some-key") - fmt.Fprintln(res, item) -} diff --git a/999_old-code/043_photo-blog_cookie_memcache/01_challenge/instructions.md b/999_old-code/043_photo-blog_cookie_memcache/01_challenge/instructions.md deleted file mode 100755 index 9ac08283..00000000 --- a/999_old-code/043_photo-blog_cookie_memcache/01_challenge/instructions.md +++ /dev/null @@ -1,2 +0,0 @@ -# Instructions -1. Take the code from "photo-blog_cookie" and also store the []string which holds the paths for the photos in memcache \ No newline at end of file diff --git a/999_old-code/054_ajax/01/index.html b/999_old-code/054_ajax/01/index.html deleted file mode 100755 index 2abfe855..00000000 --- a/999_old-code/054_ajax/01/index.html +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - -Make a request - - - - \ No newline at end of file diff --git a/xx045_photo-blog/01_hands-on/README.md b/xx045_photo-blog/01_hands-on/README.md new file mode 100755 index 00000000..49c7ab05 --- /dev/null +++ b/xx045_photo-blog/01_hands-on/README.md @@ -0,0 +1,9 @@ +Start with the code from "034_photo-blog / 05_display-pictures". + +This code is provided for you here in the "starting-files" + +Complete this hands-on exercise in three steps: + +1. Refactor the code to use julien schmidt's router +1. Modularize your code; put code into different packages +1. Store the paths for the photos in memcache \ No newline at end of file diff --git a/xx045_photo-blog/01_hands-on/starting-files/main.go b/xx045_photo-blog/01_hands-on/starting-files/main.go new file mode 100644 index 00000000..cd594e3e --- /dev/null +++ b/xx045_photo-blog/01_hands-on/starting-files/main.go @@ -0,0 +1,85 @@ +package main + +import ( + "crypto/sha1" + "fmt" + "github.com/satori/go.uuid" + "html/template" + "io" + "net/http" + "os" + "path/filepath" + "strings" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + http.HandleFunc("/", index) + // add route to serve pictures + http.Handle("/public/", http.StripPrefix("/public", http.FileServer(http.Dir("./public")))) + http.Handle("/favicon.ico", http.NotFoundHandler()) + http.ListenAndServe(":8080", nil) +} + +func index(w http.ResponseWriter, r *http.Request) { + c := getCookie(w, r) + if r.Method == http.MethodPost { + mf, fh, err := r.FormFile("nf") + if err != nil { + fmt.Println(err) + } + defer mf.Close() + // create sha for file name + ext := strings.Split(fh.Filename, ".")[1] + h := sha1.New() + io.Copy(h, mf) + fname := fmt.Sprintf("%x", h.Sum(nil)) + "." + ext + // create new file + wd, err := os.Getwd() + if err != nil { + fmt.Println(err) + } + path := filepath.Join(wd, "public", "pics", fname) + nf, err := os.Create(path) + if err != nil { + fmt.Println(err) + } + defer nf.Close() + // copy + mf.Seek(0, 0) + io.Copy(nf, mf) + // add filename to this user's cookie + c = appendValue(w, c, fname) + } + xs := strings.Split(c.Value, "|") + // sliced cookie values to only send over images + tpl.ExecuteTemplate(w, "index.gohtml", xs[1:]) +} + +func getCookie(w http.ResponseWriter, r *http.Request) *http.Cookie { + c, err := r.Cookie("session") + if err != nil { + sID, _ := uuid.NewV4() + c = &http.Cookie{ + Name: "session", + Value: sID.String(), + } + http.SetCookie(w, c) + } + return c +} + +func appendValue(w http.ResponseWriter, c *http.Cookie, fname string) *http.Cookie { + s := c.Value + if !strings.Contains(s, fname) { + s += "|" + fname + } + c.Value = s + http.SetCookie(w, c) + return c +} diff --git a/xx045_photo-blog/01_hands-on/starting-files/public/pics/f382716c1600421f127c7414a072016434fcd43a.jpg b/xx045_photo-blog/01_hands-on/starting-files/public/pics/f382716c1600421f127c7414a072016434fcd43a.jpg new file mode 100644 index 00000000..acb99360 Binary files /dev/null and b/xx045_photo-blog/01_hands-on/starting-files/public/pics/f382716c1600421f127c7414a072016434fcd43a.jpg differ diff --git a/xx045_photo-blog/01_hands-on/starting-files/templates/index.gohtml b/xx045_photo-blog/01_hands-on/starting-files/templates/index.gohtml new file mode 100644 index 00000000..b95e0dd8 --- /dev/null +++ b/xx045_photo-blog/01_hands-on/starting-files/templates/index.gohtml @@ -0,0 +1,20 @@ + + + + + INDEX + + + +

Your Pictures:

+{{range .}} + +{{end}} + +
+ + + + + + \ No newline at end of file diff --git a/xx045_photo-blog/02_solution/01/README.md b/xx045_photo-blog/02_solution/01/README.md new file mode 100644 index 00000000..5212965d --- /dev/null +++ b/xx045_photo-blog/02_solution/01/README.md @@ -0,0 +1 @@ +Refactored "034_photo-blog / 05_display-pictures" to use Julien Schmidt's router. \ No newline at end of file diff --git a/xx045_photo-blog/02_solution/01/main.go b/xx045_photo-blog/02_solution/01/main.go new file mode 100644 index 00000000..b3b2415b --- /dev/null +++ b/xx045_photo-blog/02_solution/01/main.go @@ -0,0 +1,92 @@ +package main + +import ( + "crypto/sha1" + "fmt" + "github.com/julienschmidt/httprouter" + "github.com/satori/go.uuid" + "html/template" + "io" + "net/http" + "os" + "path/filepath" + "strings" +) + +var tpl *template.Template + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) +} + +func main() { + r := httprouter.New() + r.GET("/", index) + r.POST("/", indexSubmission) + r.Handler("GET", "/favicon.ico", http.NotFoundHandler()) + r.ServeFiles("/public/*filepath", http.Dir("./public")) + http.ListenAndServe(":8080", r) +} + +func index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + c := getCookie(w, r) + xs := strings.Split(c.Value, "|") + tpl.ExecuteTemplate(w, "index.gohtml", xs[1:]) //only send over images +} + +func indexSubmission(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + c := getCookie(w, r) + + mf, fh, err := r.FormFile("nf") + if err != nil { + fmt.Println(err) + } + defer mf.Close() + // create sha for file name + ext := strings.Split(fh.Filename, ".")[1] + h := sha1.New() + io.Copy(h, mf) + fname := fmt.Sprintf("%x", h.Sum(nil)) + "." + ext + // create new file + wd, err := os.Getwd() + if err != nil { + fmt.Println(err) + } + path := filepath.Join(wd, "public", "pics", fname) + nf, err := os.Create(path) + if err != nil { + fmt.Println(err) + } + defer nf.Close() + // copy + mf.Seek(0, 0) + io.Copy(nf, mf) + // add filename to this user's cookie + c = appendValue(w, c, fname) + + xs := strings.Split(c.Value, "|") + tpl.ExecuteTemplate(w, "index.gohtml", xs[1:]) //only send over images +} + +func getCookie(w http.ResponseWriter, r *http.Request) *http.Cookie { + c, err := r.Cookie("session") + if err != nil { + sID, _ := uuid.NewV4() + c = &http.Cookie{ + Name: "session", + Value: sID.String(), + } + http.SetCookie(w, c) + } + return c +} + +func appendValue(w http.ResponseWriter, c *http.Cookie, fname string) *http.Cookie { + s := c.Value + if !strings.Contains(s, fname) { + s += "|" + fname + } + c.Value = s + http.SetCookie(w, c) + return c +} diff --git a/xx045_photo-blog/02_solution/01/public/pics/f382716c1600421f127c7414a072016434fcd43a.jpg b/xx045_photo-blog/02_solution/01/public/pics/f382716c1600421f127c7414a072016434fcd43a.jpg new file mode 100644 index 00000000..acb99360 Binary files /dev/null and b/xx045_photo-blog/02_solution/01/public/pics/f382716c1600421f127c7414a072016434fcd43a.jpg differ diff --git a/xx045_photo-blog/02_solution/01/templates/index.gohtml b/xx045_photo-blog/02_solution/01/templates/index.gohtml new file mode 100644 index 00000000..b95e0dd8 --- /dev/null +++ b/xx045_photo-blog/02_solution/01/templates/index.gohtml @@ -0,0 +1,20 @@ + + + + + INDEX + + + +

Your Pictures:

+{{range .}} + +{{end}} + +
+ + + + + + \ No newline at end of file diff --git a/xx045_photo-blog/02_solution/02/README.md b/xx045_photo-blog/02_solution/02/README.md new file mode 100644 index 00000000..16e18d4c --- /dev/null +++ b/xx045_photo-blog/02_solution/02/README.md @@ -0,0 +1 @@ +Modularized the code; put code into different packages. \ No newline at end of file diff --git a/xx045_photo-blog/02_solution/02/controllers/general.go b/xx045_photo-blog/02_solution/02/controllers/general.go new file mode 100644 index 00000000..5fda0c27 --- /dev/null +++ b/xx045_photo-blog/02_solution/02/controllers/general.go @@ -0,0 +1,78 @@ +package controllers + +import ( + "crypto/sha1" + "fmt" + "github.com/julienschmidt/httprouter" + "html/template" + "io" + "mime/multipart" + "net/http" + "os" + "path/filepath" + "strings" +) + +type Controller struct { + tpl *template.Template +} + +func NewController(tpl *template.Template) *Controller { + return &Controller{tpl} +} + +func (ctl Controller) Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + c := getCookie(w, r) + xs := strings.Split(c.Value, "|") + ctl.tpl.ExecuteTemplate(w, "index.gohtml", xs[1:]) //only send over images +} + +func (ctl Controller) IndexSubmission(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + c := getCookie(w, r) + + mf, fh, err := r.FormFile("nf") + if err != nil { + fmt.Println(err) + } + defer mf.Close() + + // create a new file + fname := createSHA(mf, fh) + nf, err := createNewFile(fname) + if err != nil { + fmt.Println(err) + } + defer nf.Close() + + // copy + mf.Seek(0, 0) + io.Copy(nf, mf) + + // add filename to this user's cookie + c = appendValue(w, c, fname) + + //only send over images + xs := strings.Split(c.Value, "|") + ctl.tpl.ExecuteTemplate(w, "index.gohtml", xs[1:]) +} + +func createSHA(mf multipart.File, fh *multipart.FileHeader) string { + ext := strings.Split(fh.Filename, ".")[1] + h := sha1.New() + io.Copy(h, mf) + return fmt.Sprintf("%x", h.Sum(nil)) + "." + ext +} + +func createNewFile(name string) (*os.File, error) { + wd, err := os.Getwd() + if err != nil { + fmt.Println(err) + return nil, err + } + path := filepath.Join(wd, "public", "pics", name) + nf, err := os.Create(path) + if err != nil { + fmt.Println(err) + } + return nf, nil +} diff --git a/xx045_photo-blog/02_solution/02/controllers/session.go b/xx045_photo-blog/02_solution/02/controllers/session.go new file mode 100644 index 00000000..7dc08d4d --- /dev/null +++ b/xx045_photo-blog/02_solution/02/controllers/session.go @@ -0,0 +1,30 @@ +package controllers + +import ( + "github.com/satori/go.uuid" + "net/http" + "strings" +) + +func getCookie(w http.ResponseWriter, r *http.Request) *http.Cookie { + c, err := r.Cookie("session") + if err != nil { + sID, _ := uuid.NewV4() + c = &http.Cookie{ + Name: "session", + Value: sID.String(), + } + http.SetCookie(w, c) + } + return c +} + +func appendValue(w http.ResponseWriter, c *http.Cookie, fname string) *http.Cookie { + s := c.Value + if !strings.Contains(s, fname) { + s += "|" + fname + } + c.Value = s + http.SetCookie(w, c) + return c +} diff --git a/xx045_photo-blog/02_solution/02/main.go b/xx045_photo-blog/02_solution/02/main.go new file mode 100644 index 00000000..1bfec7fd --- /dev/null +++ b/xx045_photo-blog/02_solution/02/main.go @@ -0,0 +1,25 @@ +package main + +import ( + "github.com/GoesToEleven/golang-web-dev/045_photo-blog/02_solution/02/controllers" + "github.com/julienschmidt/httprouter" + "html/template" + "net/http" +) + +var tpl *template.Template +var ctl *controllers.Controller + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) + ctl = controllers.NewController(tpl) +} + +func main() { + r := httprouter.New() + r.GET("/", ctl.Index) + r.POST("/", ctl.IndexSubmission) + r.Handler("GET", "/favicon.ico", http.NotFoundHandler()) + r.ServeFiles("/public/*filepath", http.Dir("./public")) + http.ListenAndServe(":8080", r) +} diff --git a/xx045_photo-blog/02_solution/02/public/pics/f382716c1600421f127c7414a072016434fcd43a.jpg b/xx045_photo-blog/02_solution/02/public/pics/f382716c1600421f127c7414a072016434fcd43a.jpg new file mode 100644 index 00000000..acb99360 Binary files /dev/null and b/xx045_photo-blog/02_solution/02/public/pics/f382716c1600421f127c7414a072016434fcd43a.jpg differ diff --git a/xx045_photo-blog/02_solution/02/templates/index.gohtml b/xx045_photo-blog/02_solution/02/templates/index.gohtml new file mode 100644 index 00000000..b95e0dd8 --- /dev/null +++ b/xx045_photo-blog/02_solution/02/templates/index.gohtml @@ -0,0 +1,20 @@ + + + + + INDEX + + + +

Your Pictures:

+{{range .}} + +{{end}} + +
+ + + + + + \ No newline at end of file diff --git a/xx045_photo-blog/02_solution/03/README.md b/xx045_photo-blog/02_solution/03/README.md new file mode 100644 index 00000000..16e18d4c --- /dev/null +++ b/xx045_photo-blog/02_solution/03/README.md @@ -0,0 +1 @@ +Modularized the code; put code into different packages. \ No newline at end of file diff --git a/xx045_photo-blog/02_solution/03/packages/controllers/general.go b/xx045_photo-blog/02_solution/03/packages/controllers/general.go new file mode 100644 index 00000000..44e5e96b --- /dev/null +++ b/xx045_photo-blog/02_solution/03/packages/controllers/general.go @@ -0,0 +1,91 @@ +package controllers + +import ( + "crypto/sha1" + "encoding/json" + "fmt" + "github.com/GoesToEleven/golang-web-dev/045_photo-blog/02_solution/03/packages/errors" + "github.com/GoesToEleven/golang-web-dev/045_photo-blog/02_solution/03/packages/memcache" + "github.com/julienschmidt/httprouter" + "google.golang.org/appengine" + "google.golang.org/appengine/log" + "html/template" + "io" + "mime/multipart" + "net/http" + "os" + "path/filepath" + "strings" +) + +type Controller struct { + tpl *template.Template +} + +func NewController(tpl *template.Template) *Controller { + return &Controller{tpl} +} + +func (ctl Controller) Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + ctx := appengine.NewContext(r) + log.Infof(ctx, "IN INDEX") // fyi + c := GetCookie(w, r) + xs, err := memcache.GetPictures(r, c) + errors.Handle(err) + + bs, err := json.Marshal(xs) + if err != nil { + log.Infof(ctx, "%v", err) + } + log.Infof(ctx, "%s", string(bs)) // fyi + ctl.tpl.ExecuteTemplate(w, "index.gohtml", xs) +} + +func (ctl Controller) IndexSubmission(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + + c := GetCookie(w, r) + + mf, fh, err := r.FormFile("nf") + errors.Handle(err) + defer mf.Close() + + // new file + fname := createSHA(mf, fh) + nf, err := createNewFile(r, fname) + errors.Handle(err) + defer nf.Close() + + // copy + mf.Seek(0, 0) + io.Copy(nf, mf) + + // store filename + xs, err := memcache.GetPictures(r, c) + errors.Handle(err) + xs = append(xs, fname) + memcache.SetPictures(r, c, xs) + + ctl.tpl.ExecuteTemplate(w, "index.gohtml", xs) +} + +func createSHA(mf multipart.File, fh *multipart.FileHeader) string { + ext := strings.Split(fh.Filename, ".")[1] + h := sha1.New() + io.Copy(h, mf) + return fmt.Sprintf("%x", h.Sum(nil)) + "." + ext +} + +func createNewFile(r *http.Request, name string) (*os.File, error) { + ctx := appengine.NewContext(r) + wd, err := os.Getwd() + if err != nil { + return nil, err + } + path := filepath.Join(wd, "public", "pics", name) + nf, err := os.Create(path) + log.Infof(ctx, "%s", path) // fyi + if err != nil { + return nil, err + } + return nf, nil +} diff --git a/xx045_photo-blog/02_solution/03/packages/controllers/session.go b/xx045_photo-blog/02_solution/03/packages/controllers/session.go new file mode 100644 index 00000000..d76d56ea --- /dev/null +++ b/xx045_photo-blog/02_solution/03/packages/controllers/session.go @@ -0,0 +1,19 @@ +package controllers + +import ( + "github.com/satori/go.uuid" + "net/http" +) + +func GetCookie(w http.ResponseWriter, r *http.Request) *http.Cookie { + c, err := r.Cookie("session") + if err != nil { + sID, _ := uuid.NewV4() + c = &http.Cookie{ + Name: "session", + Value: sID.String(), + } + http.SetCookie(w, c) + } + return c +} diff --git a/xx045_photo-blog/02_solution/03/packages/errors/general.go b/xx045_photo-blog/02_solution/03/packages/errors/general.go new file mode 100644 index 00000000..1ae50122 --- /dev/null +++ b/xx045_photo-blog/02_solution/03/packages/errors/general.go @@ -0,0 +1,7 @@ +package errors + +import "fmt" + +func Handle(e error) { + fmt.Println(e) +} diff --git a/xx045_photo-blog/02_solution/03/packages/memcache/picture.go b/xx045_photo-blog/02_solution/03/packages/memcache/picture.go new file mode 100644 index 00000000..9f9f9316 --- /dev/null +++ b/xx045_photo-blog/02_solution/03/packages/memcache/picture.go @@ -0,0 +1,33 @@ +package memcache + +import ( + "encoding/json" + "github.com/GoesToEleven/golang-web-dev/045_photo-blog/02_solution/03/packages/errors" + "google.golang.org/appengine" + "google.golang.org/appengine/memcache" + "net/http" +) + +func SetPictures(r *http.Request, c *http.Cookie, xs []string) error { + ctx := appengine.NewContext(r) + bs, err := json.Marshal(xs) + errors.Handle(err) + item1 := memcache.Item{ + Key: c.Value, + Value: bs, + } + err = memcache.Set(ctx, &item1) + return err +} + +func GetPictures(r *http.Request, c *http.Cookie) ([]string, error) { + ctx := appengine.NewContext(r) + + item, err := memcache.Get(ctx, c.Value) + if err != nil { + return nil, err + } + var xs []string + json.Unmarshal(item.Value, &xs) + return xs, nil +} diff --git a/xx045_photo-blog/02_solution/03/project/app.yaml b/xx045_photo-blog/02_solution/03/project/app.yaml new file mode 100755 index 00000000..bb28f442 --- /dev/null +++ b/xx045_photo-blog/02_solution/03/project/app.yaml @@ -0,0 +1,8 @@ +application: learning-1130 +version: 1 +runtime: go +api_version: go1 + +handlers: +- url: /.* + script: _go_app \ No newline at end of file diff --git a/xx045_photo-blog/02_solution/03/project/main.go b/xx045_photo-blog/02_solution/03/project/main.go new file mode 100644 index 00000000..dd1a2827 --- /dev/null +++ b/xx045_photo-blog/02_solution/03/project/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "github.com/GoesToEleven/golang-web-dev/045_photo-blog/02_solution/03/packages/controllers" + "github.com/julienschmidt/httprouter" + "google.golang.org/appengine" + "html/template" + "net/http" +) + +var tpl *template.Template +var ctl *controllers.Controller + +func init() { + tpl = template.Must(template.ParseGlob("templates/*")) + ctl = controllers.NewController(tpl) +} + +func main() { + // setup julienschmidt's router + // julienschmidt's router implements handler interface + r := httprouter.New() + http.Handle("/", r) + // user julienschmidt's router + r.GET("/", ctl.Index) + r.POST("/", ctl.IndexSubmission) + r.Handler("GET", "/favicon.ico", http.NotFoundHandler()) + r.ServeFiles("/public/*filepath", http.Dir("./public")) + // call appengine's main function + appengine.Main() +} diff --git a/xx045_photo-blog/02_solution/03/project/public/pics/f382716c1600421f127c7414a072016434fcd43a.jpg b/xx045_photo-blog/02_solution/03/project/public/pics/f382716c1600421f127c7414a072016434fcd43a.jpg new file mode 100644 index 00000000..acb99360 Binary files /dev/null and b/xx045_photo-blog/02_solution/03/project/public/pics/f382716c1600421f127c7414a072016434fcd43a.jpg differ diff --git a/xx045_photo-blog/02_solution/03/project/templates/index.gohtml b/xx045_photo-blog/02_solution/03/project/templates/index.gohtml new file mode 100644 index 00000000..b95e0dd8 --- /dev/null +++ b/xx045_photo-blog/02_solution/03/project/templates/index.gohtml @@ -0,0 +1,20 @@ + + + + + INDEX + + + +

Your Pictures:

+{{range .}} + +{{end}} + +
+ + + + + + \ No newline at end of file diff --git a/xx045_photo-blog/xx02_solution/app.yaml b/xx045_photo-blog/xx02_solution/app.yaml new file mode 100755 index 00000000..bb28f442 --- /dev/null +++ b/xx045_photo-blog/xx02_solution/app.yaml @@ -0,0 +1,8 @@ +application: learning-1130 +version: 1 +runtime: go +api_version: go1 + +handlers: +- url: /.* + script: _go_app \ No newline at end of file diff --git a/999_old-code/043_photo-blog_cookie_memcache/02_solution/assets/imgs/one.jpg b/xx045_photo-blog/xx02_solution/assets/imgs/one.jpg similarity index 100% rename from 999_old-code/043_photo-blog_cookie_memcache/02_solution/assets/imgs/one.jpg rename to xx045_photo-blog/xx02_solution/assets/imgs/one.jpg diff --git a/999_old-code/043_photo-blog_cookie_memcache/02_solution/cookie.go b/xx045_photo-blog/xx02_solution/cookie.go similarity index 100% rename from 999_old-code/043_photo-blog_cookie_memcache/02_solution/cookie.go rename to xx045_photo-blog/xx02_solution/cookie.go diff --git a/999_old-code/043_photo-blog_cookie_memcache/02_solution/main.go b/xx045_photo-blog/xx02_solution/main.go similarity index 100% rename from 999_old-code/043_photo-blog_cookie_memcache/02_solution/main.go rename to xx045_photo-blog/xx02_solution/main.go diff --git a/999_old-code/043_photo-blog_cookie_memcache/02_solution/memc.go b/xx045_photo-blog/xx02_solution/memc.go similarity index 100% rename from 999_old-code/043_photo-blog_cookie_memcache/02_solution/memc.go rename to xx045_photo-blog/xx02_solution/memc.go diff --git a/999_old-code/043_photo-blog_cookie_memcache/02_solution/model.go b/xx045_photo-blog/xx02_solution/model.go similarity index 100% rename from 999_old-code/043_photo-blog_cookie_memcache/02_solution/model.go rename to xx045_photo-blog/xx02_solution/model.go diff --git a/999_old-code/043_photo-blog_cookie_memcache/02_solution/photos.go b/xx045_photo-blog/xx02_solution/photos.go similarity index 100% rename from 999_old-code/043_photo-blog_cookie_memcache/02_solution/photos.go rename to xx045_photo-blog/xx02_solution/photos.go diff --git a/999_old-code/043_photo-blog_cookie_memcache/02_solution/refactor-notes.md b/xx045_photo-blog/xx02_solution/refactor-notes.md similarity index 100% rename from 999_old-code/043_photo-blog_cookie_memcache/02_solution/refactor-notes.md rename to xx045_photo-blog/xx02_solution/refactor-notes.md diff --git a/999_old-code/043_photo-blog_cookie_memcache/02_solution/templates/index.html b/xx045_photo-blog/xx02_solution/templates/index.html similarity index 100% rename from 999_old-code/043_photo-blog_cookie_memcache/02_solution/templates/index.html rename to xx045_photo-blog/xx02_solution/templates/index.html diff --git a/999_old-code/043_photo-blog_cookie_memcache/02_solution/templates/login.html b/xx045_photo-blog/xx02_solution/templates/login.html similarity index 100% rename from 999_old-code/043_photo-blog_cookie_memcache/02_solution/templates/login.html rename to xx045_photo-blog/xx02_solution/templates/login.html diff --git a/999_old-code/043_photo-blog_cookie_memcache/02_solution/user.go b/xx045_photo-blog/xx02_solution/user.go similarity index 100% rename from 999_old-code/043_photo-blog_cookie_memcache/02_solution/user.go rename to xx045_photo-blog/xx02_solution/user.go diff --git a/999_old-code/043_photo-blog_cookie_memcache/02_solution/validate.go b/xx045_photo-blog/xx02_solution/validate.go similarity index 100% rename from 999_old-code/043_photo-blog_cookie_memcache/02_solution/validate.go rename to xx045_photo-blog/xx02_solution/validate.go