diff --git a/.idea/CodeBusters.iml b/.idea/CodeBusters.iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/.idea/CodeBusters.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..b9d18bf
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..15a15b2
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..caf51dd
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..61e6741
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..d5d6b88
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,453 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ buildMessageDiv
+ fetch
+ conn
+ response
+ request
+ parse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1551233434483
+
+
+ 1551233434483
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app.yml b/app.yml
new file mode 100644
index 0000000..0e72d0d
--- /dev/null
+++ b/app.yml
@@ -0,0 +1,2 @@
+beta_settings:
+ cloud_sql_instances: sp19-codeu-14-7857:us-central1:taxoverflow-database=tcp:52785
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 8073b38..2b3a971 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,55 +32,75 @@ limitations under the License.
1.8
UTF-8
false
+
+ sp19-codeu-14-7857:us-central1:taxoverflow-database
+ root
+ devPW123
+ taxoverflow-database
+ jdbc:mysql://google/${database}?cloudSqlInstance=${INSTANCE_CONNECTION_NAME}&socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=${user}&password=${password}&useSSL=false
-
+
-
- javax.servlet
- javax.servlet-api
- 3.1.0
- provided
-
+
+ mysql
+ mysql-connector-java
+ 6.0.5
+
+
+ com.google.cloud.sql
+ mysql-socket-factory-connector-j-6
+ 1.0.12
+
-
- com.google.appengine
- appengine-api-1.0-sdk
- 1.9.59
-
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+ provided
+
-
- org.jsoup
- jsoup
- 1.8.3
-
+
+ com.google.appengine
+ appengine-api-1.0-sdk
+ 1.9.59
+
-
- com.google.cloud
- google-cloud-datastore
- 1.52.0
-
+
+ org.jsoup
+ jsoup
+ 1.8.3
+
-
+
+ com.google.cloud
+ google-cloud-datastore
+ 1.52.0
+
-
-
-
- com.google.appengine
- appengine-maven-plugin
- 1.9.59
-
-
- com.diffplug.spotless
- spotless-maven-plugin
- 1.16.0
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ com.google.appengine
+ appengine-maven-plugin
+ 1.9.59
+
+
+ com.diffplug.spotless
+ spotless-maven-plugin
+ 1.16.0
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/google/codeu/servlets/CloudSqlServlet.java b/src/main/java/com/google/codeu/servlets/CloudSqlServlet.java
new file mode 100644
index 0000000..2b8bc06
--- /dev/null
+++ b/src/main/java/com/google/codeu/servlets/CloudSqlServlet.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.appengine.cloudsql;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.sql.PreparedStatement;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import java.util.stream.Collectors;
+import com.google.gson.*;
+
+// [START gae_java8_mysql_app]
+@SuppressWarnings("serial")
+// With @WebServlet annotation the webapp/WEB-INF/web.xml is no longer required.
+@WebServlet(
+ name = "CloudSQL",
+ description = "CloudSQL: Store tax forum information",
+ urlPatterns = "/cloudsql"
+)
+public class CloudSqlServlet extends HttpServlet {
+ Connection conn;
+
+ @Override
+ public void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws IOException, ServletException {
+
+ String requestBody = req.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
+ JsonParser parse = new JsonParser();
+ JsonObject jObj = (JsonObject)parse.parse(requestBody);
+
+ String path = req.getRequestURI();
+ if (path.startsWith("/favicon.ico")) {
+ return; // ignore the request for favicon.ico
+ }
+
+
+ if (req.getRequestURI().startsWith("/question")) {
+ // Perform get Question.
+ final String selectQuestionSql =
+ "SELECT postId " + "FROM POST " + "WHERE header = '" + jObj.get("header") + "'";
+
+ try (ResultSet rs = conn.prepareStatement(selectQuestionSql).executeQuery()) {
+ System.out.println("Query successfully completed");
+ String queryResult = rs.getString(1);
+ PrintWriter writer = resp.getWriter();
+ resp.setContentType("text/plain");
+ writer.println(queryResult);
+ } catch (SQLException e) {
+ throw new ServletException("SQL GetQuestion error", e);
+ }
+ } else if (req.getRequestURI().startsWith("/member")) {
+ // Perform get Member.
+ final String selectMemberSql =
+ "SELECT profileId " + "FROM PROFILE " + "WHERE emailP = '" + jObj.get("emailP") + "'";
+
+ try (ResultSet rs = conn.prepareStatement(selectMemberSql).executeQuery()) {
+ System.out.println("Query successfully completed");
+ String queryResult = rs.getString(1);
+ PrintWriter writer = resp.getWriter();
+ resp.setContentType("text/plain");
+ writer.println(queryResult);
+ } catch (SQLException e) {
+ throw new ServletException("SQL GetMember error", e);
+ }
+ } else if (req.getRequestURI().startsWith("/login")) {
+ // Perform get Member.
+ final String selectMemberSql =
+ "SELECT emailU " + "FROM USER " + "WHERE emailU = '" + jObj.get("emailU") + "'";
+
+ try (ResultSet rs = conn.prepareStatement(selectMemberSql).executeQuery()) {
+ System.out.println("Query successfully completed");
+ String queryResult = rs.getString(1);
+ PrintWriter writer = resp.getWriter();
+ resp.setContentType("text/plain");
+ if(queryResult.isEmpty()) {
+ writer.println(false); //if user non-existent
+ }else {
+ writer.println(true); //if user existent
+ }
+ } catch (SQLException e) {
+ throw new ServletException("SQL GetUser error", e);
+ }
+ }else if (req.getRequestURI().startsWith("/reply")) {
+ // Perform get Member.
+ final String selectPostSql =
+ "SELECT postIdP " + "FROM POST " + "WHERE header = '" + jObj.get("header") + "'";
+
+ String queryResult;
+ try (ResultSet rs = conn.prepareStatement(selectPostSql).executeQuery()) {
+ System.out.println("Query successfully completed");
+ queryResult = rs.getString(1);
+ } catch (SQLException e) {
+ throw new ServletException("SQL GetPostId-Answer error", e);
+ }
+
+ final String selectAnswerSql =
+ "SELECT answer " + "FROM ANSWER " + "WHERE postIdA = '" + queryResult + "'";
+
+ try (ResultSet rs = conn.prepareStatement(selectPostSql).executeQuery()) {
+ System.out.println("Query successfully completed");
+ PrintWriter writer = resp.getWriter();
+ resp.setContentType("text/plain");
+ String queryAnswerResult = rs.getString(1);
+ } catch (SQLException e) {
+ throw new ServletException("SQL GetAnswer error", e);
+ }
+ }
+
+ @Override
+ public void doPost(HttpServletRequest req, HttpServletResponse resp)
+ throws IOException, ServletException {
+ String requestBody = req.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
+ JsonParser parse = new JsonParser();
+ JsonObject jObj = (JsonObject)parse.parse(requestBody);
+
+
+ String path = req.getRequestURI();
+ if (path.startsWith("/favicon.ico")) {
+ return; // ignore the request for favicon.ico
+ }
+
+ if(req.getRequestURI().startsWith("/reply")){
+ // Perform save Answer.
+ final String createAnswerSql =
+ "INSERT INTO ANSWERS (postId, answer) "
+ + "VALUES ( "
+// + req.body.postID
+ + jObj.get("postID")
+ + ", "
+// + req.body.answer
+ + jObj.get("answer")
+ + " )";
+
+ try (PreparedStatement statementCreateVisit = conn.prepareStatement(createAnswerSql)) {
+ System.out.println("Query successfully completed");
+ conn.createStatement().executeUpdate(createAnswerSql);
+
+ } catch (SQLException e) {
+ throw new ServletException("SQL CreateReply error", e);
+ }
+
+ } else if (req.getRequestURI().startsWith("/question")) {
+ // Perform save Question.
+ final String createQuestionSql =
+ "INSERT INTO POST (memberId, header, pointTotal) "
+ + "VALUES ( "
+ + jObj.get("memberId")
+ + ", "
+ + jObj.get("header")
+ + ", "
+ + jObj.get("pointTotal")
+ + " )";
+
+ try (PreparedStatement statementCreateVisit = conn.prepareStatement(createQuestionSql)) {
+ System.out.println("Query successfully compiled");
+ conn.createStatement().executeUpdate(createQuestionSql);
+
+ } catch (SQLException e) {
+ throw new ServletException("SQL CreateQuestion error", e);
+ }
+ }
+ }
+
+ @Override
+ public void doPut(HttpServletRequest req, HttpServletResponse resp)
+ throws IOException, ServletException {
+
+ String requestBody = req.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
+ JsonParser parse = new JsonParser();
+ JsonObject jObj = (JsonObject)parse.parse(requestBody);
+
+ String path = req.getRequestURI();
+ if (path.startsWith("/favicon.ico")) {
+ return; // ignore the request for favicon.ico
+ }
+
+ if (req.getRequestURI().startsWith("/reply")) {
+ // Perform save Answer.
+ final String updatePointsSql =
+ "UPDATE POST "
+ + "SET ( pointTotal = "
+ + jObj.get("pointTotal")
+ + " )"
+ + "WHERE postId = "
+ + jObj.get("postId");
+
+ try (PreparedStatement statementCreateVisit = conn.prepareStatement(updatePointsSql)) {
+ System.out.println("Query successfully compiled");
+ conn.createStatement().executeUpdate(updatePointsSql);
+
+ } catch (SQLException e) {
+ throw new ServletException("SQL UpdatePoint error", e);
+ }
+ }
+ }
+
+ @Override
+ public void init() throws ServletException {
+ String url = System.getProperty("cloudsql");
+ log("connecting to: " + url);
+ try {
+ conn = DriverManager.getConnection(url);
+ } catch (SQLException e) {
+ throw new ServletException("Unable to connect to Cloud SQL", e);
+ }
+
+ final String createUserTableSql =
+ "CREATE TABLE IF NOT EXISTS USER ( "
+ + "emailU NVARCHAR NOT NULL, "
+// + "password NVARCHAR NOT NULL"
+ + "PRIMARY KEY (emailU) );";
+ final String createProfileTableSql =
+ "CREATE TABLE IF NOT EXISTS PROFILE ( "
+ + "ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED, "
+ + "profileId AS 'UID' + RIGHT('00000000' + CAST(ID AS VARCHAR(8)), 8) PERSISTED, "
+ + "first VARCHAR NOT NULL, "
+ + "last VARCHAR NOT NULL, isCPA BIT NOT NULL, "
+ + "emailP NVARCHAR NOT NULL, "
+ + "FOREIGN KEY ( emailP ) REFERENCES USER.emailU, PRIMARY KEY (profileId) );";
+ final String createPostTableSql =
+ "CREATE TABLE IF NOT EXISTS POST ( "
+ + "ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,"
+ + "postIdP AS 'UID' + RIGHT('00000000' + CAST(ID AS VARCHAR(8)), 8) PERSISTED,"
+ + "memberId SERIAL NOT NULL, "
+ + "header VARCHAR, pointTotal INTEGER, "
+ + "FOREIGN KEY ( memberId ) REFERENCES PROFILE.profileId, PRIMARY KEY (postId) );";
+ final String createAnswerTableSql =
+ "CREATE TABLE IF NOT EXISTS ANSWERS ( "
+ + "ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,"
+ + "answerId AS 'UID' + RIGHT('00000000' + CAST(ID AS VARCHAR(8)), 8) PERSISTED,"
+ + "postIdA SERIAL NOT NULL, "
+ + "answer VARCHAR, "
+ + "FOREIGN KEY ( postIdA ) REFERENCES POST.postIdP, PRIMARY KEY (answerId) );";
+
+ try(PreparedStatement statementUserVisit = conn.prepareStatement(createUserTableSql)){
+ conn.createStatement().executeUpdate(createUserTableSql);
+ }catch(SQLException e) {
+ throw new ServletException("SQL UserTable error", e);
+ }
+
+ try(PreparedStatement statementProfileVisit = conn.prepareStatement(createProfileTableSql)){
+ conn.createStatement().executeUpdate(createProfileTableSql);
+ }catch(SQLException e) {
+ throw new ServletException("SQL ProfileTable error", e);
+ }
+
+ try(PreparedStatement statementPostVisit = conn.prepareStatement(createPostTableSql)){
+ conn.createStatement().executeUpdate(createPostTableSql);
+ }catch(SQLException e) {
+ throw new ServletException("SQL PostTable error", e);
+ }
+
+ try(PreparedStatement statementAnswerVisit = conn.prepareStatement(createAnswerTableSql)){
+ conn.createStatement().executeUpdate(createAnswerTableSql);
+ }catch(SQLException e) {
+ throw new ServletException("SQL AnswerTable error", e);
+ }
+
+ }
+}
+// [END gae_java8_mysql_app]
diff --git a/src/main/resources/config.properties b/src/main/resources/config.properties
new file mode 100644
index 0000000..0f95b05
--- /dev/null
+++ b/src/main/resources/config.properties
@@ -0,0 +1,17 @@
+# Copyright 2015 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# [START gae_flex_mysql_config_properties]
+sqlUrl=${sqlURL}
+# [END gae_flex_mysql_config_properties]
\ No newline at end of file