From 6c842541c3bd579d43572027277c7b416bc85186 Mon Sep 17 00:00:00 2001
From: Przemek Grondek <github@nerull7.info>
Date: Tue, 30 Sep 2014 15:41:43 +0200
Subject: [PATCH] Half implementation of SQL Query

 Need to finish it.
---
 app/src/main/AndroidManifest.xml              |   4 +
 .../nerull7/mysqlbrowser/ListActivity.java    |   4 +-
 .../nerull7/mysqlbrowser/SQLActivity.java     |  22 ++++++
 .../nerull7/mysqlbrowser/SQLFragment.java     |  72 ++++++++++++++++++
 .../info/nerull7/mysqlbrowser/Static.java     |   5 ++
 .../db/AsyncDatabaseConnector.java            |  44 ++++++++++-
 .../drawable-hdpi/ic_action_file_upload.png   | Bin 0 -> 380 bytes
 .../drawable-mdpi/ic_action_file_upload.png   | Bin 0 -> 271 bytes
 .../drawable-xhdpi/ic_action_file_upload.png  | Bin 0 -> 466 bytes
 .../drawable-xxhdpi/ic_action_file_upload.png | Bin 0 -> 832 bytes
 app/src/main/res/layout/activity_sql.xml      |   7 ++
 app/src/main/res/layout/fragment_sql.xml      |  24 ++++++
 app/src/main/res/menu/logged.xml              |  12 +++
 app/src/main/res/menu/sql.xml                 |  15 ++++
 app/src/main/res/values/strings.xml           |   5 ++
 15 files changed, 211 insertions(+), 3 deletions(-)
 create mode 100644 app/src/main/java/info/nerull7/mysqlbrowser/SQLActivity.java
 create mode 100644 app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java
 create mode 100644 app/src/main/res/drawable-hdpi/ic_action_file_upload.png
 create mode 100644 app/src/main/res/drawable-mdpi/ic_action_file_upload.png
 create mode 100644 app/src/main/res/drawable-xhdpi/ic_action_file_upload.png
 create mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_file_upload.png
 create mode 100644 app/src/main/res/layout/activity_sql.xml
 create mode 100644 app/src/main/res/layout/fragment_sql.xml
 create mode 100644 app/src/main/res/menu/logged.xml
 create mode 100644 app/src/main/res/menu/sql.xml

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 39f66fe..f6b00ce 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -34,6 +34,10 @@
             android:name=".ElementActivity"
             android:label="@string/title_activity_element" >
         </activity>
+        <activity
+            android:name=".SQLActivity"
+            android:label="@string/title_activity_sql">
+        </activity>
     </application>
 
     <uses-permission android:name="android.permission.INTERNET" />
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java
index e2863fd..c88c75f 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/ListActivity.java
@@ -33,7 +33,7 @@ public class ListActivity extends Activity {
 
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.main, menu);
+        getMenuInflater().inflate(R.menu.logged, menu);
         return true;
     }
 
@@ -47,6 +47,8 @@ public class ListActivity extends Activity {
         if (id == R.id.action_settings) {
             Static.startSettings(this);
             return true;
+        } else if (id == R.id.action_sql){
+            Static.startSQL(this);
         }
         return super.onOptionsItemSelected(item);
     }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/SQLActivity.java b/app/src/main/java/info/nerull7/mysqlbrowser/SQLActivity.java
new file mode 100644
index 0000000..396ce94
--- /dev/null
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/SQLActivity.java
@@ -0,0 +1,22 @@
+package info.nerull7.mysqlbrowser;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Created by nerull7 on 30.09.14.
+ */
+public class SQLActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_sql);
+
+        if (savedInstanceState == null) {
+            getFragmentManager().beginTransaction()
+                    .add(R.id.container, new SQLFragment())
+                    .commit();
+        }
+    }
+
+}
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java
new file mode 100644
index 0000000..0ba7079
--- /dev/null
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/SQLFragment.java
@@ -0,0 +1,72 @@
+package info.nerull7.mysqlbrowser;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+
+/**
+ * Created by nerull7 on 30.09.14.
+ */
+public class SQLFragment extends Fragment{
+    private EditText sqlEditText;
+    private InputMethodManager inputMethodManager;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        View rootView = inflater.inflate(R.layout.fragment_sql, container, false);
+        sqlEditText = (EditText) rootView.findViewById(R.id.sqlQueryText);
+        setHasOptionsMenu(true);
+        return rootView;
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        inputMethodManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+        inputMethodManager.showSoftInput(sqlEditText, InputMethodManager.SHOW_FORCED);
+        sqlEditText.requestFocus();
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()){
+            case R.id.action_execute:
+                actionExecute();
+                break;
+            case R.id.action_cancel:
+                actionCancel();
+                break;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        inflater.inflate(R.menu.sql, menu);
+        super.onCreateOptionsMenu(menu, inflater);
+    }
+
+    private void actionCancel(){
+        inputMethodManager.hideSoftInputFromWindow(sqlEditText.getWindowToken(), 0);
+        getActivity().finish();
+    }
+
+    private void actionExecute(){
+        String sqlQuery = String.valueOf(sqlEditText.getText());
+        Log.d("SQLQUERY", sqlQuery);
+
+        Static.asyncDatabaseConnector.setOnPostExecuteListener(null);
+        Static.asyncDatabaseConnector.executeSQL(null /*FIXME*/, sqlQuery);
+    }
+}
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
index 6e59148..01d7d35 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/Static.java
@@ -51,4 +51,9 @@ public class Static {
         builder.create();
         builder.show();
     }
+
+    public static void startSQL(Context context) {
+        Intent intent = new Intent(context, SQLActivity.class);
+        context.startActivity(intent);
+    }
 }
diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
index 277dbb7..42a8e04 100644
--- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
+++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java
@@ -2,6 +2,7 @@ package info.nerull7.mysqlbrowser.db;
 
 import android.content.res.Resources;
 import android.os.AsyncTask;
+import android.util.Log;
 
 import org.json.JSONArray;
 import org.json.JSONException;
@@ -37,6 +38,7 @@ public class AsyncDatabaseConnector {
     public static final String ACTION_ADD_ELEMENT = "addelement";
     public static final String ACTION_UPDATE_ELEMENT = "updateelement";
     public static final String ACTION_REMOVE_ELEMENT = "removeelement";
+    public static final String ACTION_SQL_QUERY = "query";
 
     private String login;
     private String password;
@@ -339,6 +341,44 @@ public class AsyncDatabaseConnector {
         downloader.execute(request);
     }
 
+    public void executeSQL(String database, String query){
+        ArrayList<String> args = new ArrayList();
+        ArrayList<String> values = new ArrayList();
+        final Request request;
+
+        if(database!=null){
+            args.add("d");
+            values.add(database);
+        }
+        args.add("q");
+        values.add(query);
+
+        request = actionUrlBuilder(ACTION_SQL_QUERY, args, values);
+
+        Downloader downloader = new Downloader(new Downloader.OnFinishedListener() {
+            @Override
+            public void onFinished(String data, String error) {
+                String []response = data.split("\n");
+
+                List<String>headerList = null;
+                try {
+                    headerList = parseListFromJSON(response[1]);
+                } catch (JSONException e) { e.printStackTrace(); }
+                if(listReturnListener!=null) {
+                    listReturnListener.onListReturn(headerList);
+                }
+
+                List<List<String>> dataMatrix = null;
+                try {
+                    dataMatrix = parseMatrixFromJSON(response[2]);
+                } catch (JSONException e) { e.printStackTrace(); }
+                if(matrixReturnListener!=null)
+                    matrixReturnListener.onMatrixReturn(dataMatrix);
+            }
+        }, onPostExecuteListener, resources);
+        downloader.execute(request);
+    }
+
     public void setBooleanReturnListener(BooleanReturnListener booleanReturnListener){
         this.booleanReturnListener = booleanReturnListener;
     }
@@ -468,14 +508,14 @@ public class AsyncDatabaseConnector {
                 reader = new BufferedReader(new InputStreamReader(in));
                 String line;
                 while ((line = reader.readLine()) != null) {
-                    streamOutput += line;
+                    streamOutput += line + '\n';
                 }
             } finally {
                 if (reader != null) {
                     reader.close();
                 }
             }
-            return streamOutput;
+            return streamOutput.substring(0, streamOutput.length()-1); // Remove last \n
         }
 
         @Override
diff --git a/app/src/main/res/drawable-hdpi/ic_action_file_upload.png b/app/src/main/res/drawable-hdpi/ic_action_file_upload.png
new file mode 100644
index 0000000000000000000000000000000000000000..4910c3a51ea2c2c6cacf5c1bf24b4022ae8d48bf
GIT binary patch
literal 380
zcmV-?0fYXDP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm0003)Nkl<ZXhZFn
zO$x$5424@k&*efqlDH5NaUmW_TzD=8aRw@krEPvD&#@(i(nZtE`;s>_Q&%Iu>XGZO
z9H4Xuy#rJ4z`6mvqCk-risDy|@LPC7AW#6Q_)qa65D0)S@h}K$fFbb^2ulEtcykCV
z0Eu{02nzs>cr%DxfE@8A5IF!A;<F*N0G8sjAT$67@oESu08+dPLISW%W}B|rY#|)j
z9s}`l?6`CCNdRU<!ZT;VBxXy*zc~3M093vU70`OW5yp3hJ3vwv?|{ZqZXvgj#y80~
zZXvhOA6e)m)Up%C!~ew8tkf33nsq2h%S}wJ1$plPkg^Jrayt<HeGIqs&?1oX6&epa
z`*4%{!~wJ=CccAo;P7J$#r4cA6bm*7Rl6_kld~Ro4{&l7iE)4;We1%Him<qaij;jy
a7J35@$Tu-sra*rH0000<MNUMnLSTX+yOps3

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-mdpi/ic_action_file_upload.png b/app/src/main/res/drawable-mdpi/ic_action_file_upload.png
new file mode 100644
index 0000000000000000000000000000000000000000..8374b8d217e64cd212b5d2498b40d8e3cb36fe8f
GIT binary patch
literal 271
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJYo0ESArbD$DG~_>EDn4#?y+jP
zBv8=o_E4{A@gyPk2A%T8s6Ff+lb>=F$u{Izp81?&*(AfBuz607`-E2vHPe6+K{5_K
zPgSg&BG@M+S$g&<9AkVE;kQMZ!?Ho>bY~HZ9s34m-+;qG2aX77l!zry+|MfVyVF;G
zp}>J<%exzxPkCsHy2~0!F)dbf@Z)$PbRunf=3HJ+!}$xMikuo2EL@^-;5kD;fUs6s
z=T`0zo8;bEj&B((7p#8U@l}bjw7ua||B6t_z>~fL$!w)cOIG<8N}5SAG3@@Nq?nw$
Rc@@xy44$rjF6*2UngADGVh8{L

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xhdpi/ic_action_file_upload.png b/app/src/main/res/drawable-xhdpi/ic_action_file_upload.png
new file mode 100644
index 0000000000000000000000000000000000000000..702ea4ef6c6b2c1202ca33a99c04527077a7bfc2
GIT binary patch
literal 466
zcmV;@0WJQCP)<h;3K|Lk000e1NJLTq002M$002M;1^@s6s%dfF0004*Nkl<ZcwX(8
zy$!-J5QSj{Y6^Csqy(`7n=k~MumXaTk{u|hSpggoD54~?eRuDS{Ag&-f8YCjmNK1G
z{+m{Q{s{rlfXWH*3RErto1pg<*tQ0qyiD{2&>Vi<9{dviT_AV?Xb!*Wq<;2*-~r&9
ze0S|v001`u4WKXi?)8V7fCMm<d=~)J1QdXn<Xuca0EkWA#RO{rImts!umq5sJk$g$
z02;|dOt1i;l{~}*Z2%U@o0^~rz$$rD6SM#zk~c9y0{|*{6BDEWJd#&6K?1-lc~ui~
z0nEcLR*_$EmXUQsWw*%j*HHI}to@bc0!UfskW$=JyBCfh9Zmq2blbUUfDkgTfDj;i
zz!(8GK})^Z1V04$3J5LZD<A~OSAeg;2mwBWmiLR#;D^9Y2>B=+@7@G0_b;9s(F4Sr
zw48tdEb0Ek+%zCFrKYn>zxHM>JvglSdYt@X<QhN#G=Nv2?jEoRS74^y#f0-c!}xpZ
z9Jx&}b)91C382_$KpUe0Akf7wLj#J92DC9600Ld?GSwUK1{&5%L0@*GGXMYp07*qo
IM6N<$f@6WctN;K2

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_file_upload.png b/app/src/main/res/drawable-xxhdpi/ic_action_file_upload.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e78556a3584fd8d4870943c6a7e872c4dd5ad21
GIT binary patch
literal 832
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>U}pDpaSW-5dppO`i`h}YRrt=!
ziFa1M=yh=va17WpanU=QN$*_J4Hy^m*qi=cy;`eAk;SL<>yy3f&U190Zmo0T)NwAq
z{*0TG!;VErf$<<q)As8u9u5YL58j$G3JLfqR8;#mu&@Yo+=~-dVBE~v)Be0<>#xj;
zf3xmt79?Kfj5ur`wXs@up10Qutp_;_c8B8Q|5yBS=j?B6ue^5cD$5%Ge;<$Ru3c%y
zIhEy4-`th2<NTdwTC7rekpIS~w`QfqDg}n4=caTB6;6pgV79SYO|euaReVG48wJkH
z_kEkVW=LB<eWbCtVcHGH$rJSYjJPs-WmObIWm1I>^vwloa&2&bv%u3s&^?l+;waxF
z0Xg@JOjSqyZdr7RTre)Xpwe<Qa7n|xjm;`8M*>?KUfl2$b>GXH(jjZY8T)v}_68lG
zOiB0RIHpa<{3>L=3QVvB>e+ETke~5pGP`F%ud+Ym)g*P5zCA1<JwQErg-=u$WC7jw
z#p07dfyJKg$&vGeenpmC*ibfm>HFIvzE^Dc_t$4f{Lf$6-mv!=_nz#S{%P@xm_GbU
zfBdWWsT@<(`u7XBGDg(DyL10a9FxzEA4i1_q-VX-U{s6wlf?PJ*tB#CgRoxRMwSmV
zXIXhQaEkAbVEW<XE30~-r8{1Sv1Zw_KB0s|NA;&M*aZi>a~eE+B<{^Hf91->EHer|
zcB?j=zj7rIx3Pt8jMx8c-+A%lv7P%@*19pSov-c0uwwpe$Jq<78*@2a-xIvv+hKzr
z=Y)m?rh~V$nN$>JIDGgvt3g)S;NIbQUjFy`kuHhS`|lK5+ho*xZ%}t&>T!2w$~j=d
zXcqS+i*teUR?{gA()v|fSuRYxB{fZ;VB_QM3%}3IcRv1ki@nW_^6+iNuflErW&hz%
z`yI=AH08-HZ>E@!kDduNNbU^tXwZ(k6T@Vne4UH4;Ar=3Z-%rdQHqS~Dhi7^5A?)n
zs~iy3&(mX^F)_Q9WyhnVXH^-Di`GtH2;Z|~Crg6cI??<2W&Mdkc8ZgMIfKE|)z4*}
HQ$iB}zV&4+

literal 0
HcmV?d00001

diff --git a/app/src/main/res/layout/activity_sql.xml b/app/src/main/res/layout/activity_sql.xml
new file mode 100644
index 0000000..43ab1db
--- /dev/null
+++ b/app/src/main/res/layout/activity_sql.xml
@@ -0,0 +1,7 @@
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="info.nerull7.mysqlbrowser.ListActivity"
+    tools:ignore="MergeRootFrame" />
diff --git a/app/src/main/res/layout/fragment_sql.xml b/app/src/main/res/layout/fragment_sql.xml
new file mode 100644
index 0000000..1298338
--- /dev/null
+++ b/app/src/main/res/layout/fragment_sql.xml
@@ -0,0 +1,24 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context="info.nerull7.mysqlbrowser.DatabaseFragment">
+
+
+    <EditText
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:inputType="textMultiLine"
+        android:ems="10"
+        android:id="@+id/sqlQueryText"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentStart="true"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentEnd="true"
+        android:gravity="left|top"
+        android:hint="@string/hint_sql_query" >
+        <requestFocus/>
+    </EditText>
+</RelativeLayout>
diff --git a/app/src/main/res/menu/logged.xml b/app/src/main/res/menu/logged.xml
new file mode 100644
index 0000000..5d31f08
--- /dev/null
+++ b/app/src/main/res/menu/logged.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/action_settings"
+        android:title="@string/action_settings"
+        android:orderInCategory="100"
+        android:showAsAction="never" />
+    <item android:id="@+id/action_sql"
+        android:title="@string/sql_query"
+        android:orderInCategory="200"
+        android:showAsAction="never" />
+</menu>
\ No newline at end of file
diff --git a/app/src/main/res/menu/sql.xml b/app/src/main/res/menu/sql.xml
new file mode 100644
index 0000000..5bc3b39
--- /dev/null
+++ b/app/src/main/res/menu/sql.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item android:id="@+id/action_execute"
+        android:title="@string/action_execute"
+        android:showAsAction="always"
+        android:icon="@drawable/ic_action_file_upload"/>
+
+    <item android:id="@+id/action_cancel"
+        android:title="@string/action_cancel"
+        android:showAsAction="always"
+        android:icon="@drawable/ic_action_delete"/>
+
+</menu>
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ec32bc1..d4c83cb 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -53,5 +53,10 @@
     <string name="save_credentials">Save credentials</string>
     <string name="connector_url">Connector URL</string>
     <string name="no_connection">No Internet Connection</string>
+    <string name="sql_query">SQL Query</string>
+    <string name="title_activity_sql">SQL Query</string>
+    <string name="hint_sql_query">SQL Query</string>
+    <string name="action_cancel">Cancel</string>
+    <string name="action_execute">Execute</string>
 
 </resources>