Proper connection

- Removed bad synced connection which would freeze UI
- New async connector which doesn't do that
This commit is contained in:
Przemek Grondek 2014-07-22 14:25:14 +02:00
parent e396cb7b65
commit 00728eb117
9 changed files with 138 additions and 391 deletions

View file

@ -16,10 +16,12 @@ import android.widget.TextView;
import java.util.List;
import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
/**
* Created by nerull7 on 14.07.14.
*/
public class DatabaseFragment extends Fragment implements AdapterView.OnItemClickListener {
public class DatabaseFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener {
private ListView databasesListView;
private ListAdapter listAdapter;
private RelativeLayout rootView;
@ -31,12 +33,23 @@ public class DatabaseFragment extends Fragment implements AdapterView.OnItemClic
databasesListView = (ListView) rootView.findViewById(R.id.databaseList);
this.rootView = (RelativeLayout) rootView;
setupListViewDatabase();
Static.asyncDatabaseConnector.setListReturnListener(this);
Static.asyncDatabaseConnector.getDatabases();
return rootView;
}
private void setupListViewDatabase(){
List<String> databases = Static.databaseConnector.getDatabases();
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String chosenDatabase = (String) listAdapter.getItem(position);
listAdapter.getItem(position);
Intent intent = new Intent(getActivity(), TableActivity.class);
intent.putExtra("DatabaseName",chosenDatabase);
Static.asyncDatabaseConnector.setDatabaseInUse(chosenDatabase);
startActivity(intent);
}
@Override
public void onListReturn(List<String> databases) {
if(databases!= null) {
listAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, databases);
databasesListView.setAdapter(listAdapter);
@ -50,14 +63,4 @@ public class DatabaseFragment extends Fragment implements AdapterView.OnItemClic
rootView.removeView(databasesListView);
}
}
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String chosenDatabase = (String) listAdapter.getItem(position);
listAdapter.getItem(position);
Intent intent = new Intent(getActivity(), TableActivity.class);
intent.putExtra("DatabaseName",chosenDatabase);
Static.databaseConnector.setDatabaseInUse(chosenDatabase);
startActivity(intent);
}
}

View file

@ -18,14 +18,18 @@ import android.widget.TextView;
import java.util.List;
import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
/**
* Created by nerull7 on 15.07.14.
*/
public class EntriesFragment extends Fragment {
public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.MatrixReturnListener, AsyncDatabaseConnector.ListReturnListener{
private TableLayout entriesTable;
private ScrollView entriesScrollView;
private FrameLayout headerFrame;
private RelativeLayout rootView;
private TableRow.LayoutParams layoutParams;
private TableRow headerRow;
private String databaseName;
private String tableName;
@ -44,8 +48,14 @@ public class EntriesFragment extends Fragment {
entriesLimit = getActivity().getSharedPreferences(SettingsFragment.PREFERENCE_FILE, Context.MODE_PRIVATE).getInt(SettingsFragment.ENTRIES_PAGE_LIMIT, SettingsFragment.ENTRIES_PAGE_LIMIT_DEF);
this.rootView = (RelativeLayout) rootView;
page = getArguments().getInt("Page");
setupTable();
// setupActionBar();
headerRow = new TableRow(getActivity());
layoutParams = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT);
Static.asyncDatabaseConnector.setListReturnListener(this);
Static.asyncDatabaseConnector.getFields(tableName);
return rootView;
}
@ -54,13 +64,37 @@ public class EntriesFragment extends Fragment {
// actionBar.
// }
private void setupTable(){
List<String> fieldList = Static.databaseConnector.getFields(tableName);
TableRow.LayoutParams layoutParams = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT);
@Override
public void onMatrixReturn(List<List<String>> rows) {
// Now we get Rows
if(rows!=null) {
for (int i = 0; i < rows.size(); i++) {
List<String> elements = rows.get(i);
TableRow newRow = new TableRow(getActivity());
for (int j = 0; j < elements.size(); j++) { // elements.size can be the same as in header so maybe some one number or not
TextView textView = new TextView(getActivity());
textView.setText(elements.get(j));
textView.setLayoutParams(layoutParams);
newRow.addView(textView);
}
entriesTable.addView(newRow);
}
entriesTable.addView(headerRow);
} else {
TextView errorMessage = new TextView(getActivity());
errorMessage.setText(R.string.error_no_entries);
errorMessage.setTypeface(null, Typeface.ITALIC);
errorMessage.setClickable(false);
entriesScrollView.removeView(entriesTable);
rootView.addView(errorMessage);
headerFrame.addView(headerRow);
headerRow.setVisibility(View.VISIBLE);
}
}
@Override
public void onListReturn(List<String> fieldList) { // TODO: Fix bug not showing header
// First we need header
final TableRow headerRow = new TableRow(getActivity());
headerRow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
for(int i =0;i<fieldList.size();i++){
TextView textView = new TextView(getActivity());
@ -90,30 +124,7 @@ public class EntriesFragment extends Fragment {
};
headerFrame.addView(fakeHeaderView);
// Now we get Rows
List<List<String>> rows = Static.databaseConnector.getRows(tableName, entriesLimit, page);
if(rows!=null) {
for (int i = 0; i < rows.size(); i++) {
List<String> elements = rows.get(i);
TableRow newRow = new TableRow(getActivity());
for (int j = 0; j < elements.size(); j++) { // elements.size can be the same as in header so maybe some one number or not
TextView textView = new TextView(getActivity());
textView.setText(elements.get(j));
textView.setLayoutParams(layoutParams);
newRow.addView(textView);
}
entriesTable.addView(newRow);
}
entriesTable.addView(headerRow);
} else {
TextView errorMessage = new TextView(getActivity());
errorMessage.setText(R.string.error_no_entries);
errorMessage.setTypeface(null, Typeface.ITALIC);
errorMessage.setClickable(false);
entriesScrollView.removeView(entriesTable);
rootView.addView(errorMessage);
headerFrame.addView(headerRow);
headerRow.setVisibility(View.VISIBLE);
}
Static.asyncDatabaseConnector.setMatrixReturnListener(this);
Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page);
}
}

View file

@ -10,20 +10,19 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import info.nerull7.mysqlbrowser.db.FakeDatabaseConnector;
import info.nerull7.mysqlbrowser.db.RealDatabaseConnector;
import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
/**
* Created by nerull7 on 07.07.14.
*/
public class LoginFragment extends Fragment implements View.OnClickListener {
public class LoginFragment extends Fragment implements View.OnClickListener, AsyncDatabaseConnector.BooleanReturnListener {
private EditText urlTextbox;
private EditText loginTextbox;
private EditText passwordTextbox; // TODO: Mega super epic security (RSA/AES maybe?)
public LoginFragment(){
AsyncDatabaseConnector asyncDatabaseConnector;
}
public LoginFragment(){}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@ -40,29 +39,41 @@ public class LoginFragment extends Fragment implements View.OnClickListener {
@Override
public void onClick(View view) {
checkLogin();
checkAsycnLogin();
}
private void checkLogin(){
private void checkAsycnLogin(){
String login, password, url;
login = loginTextbox.getText().toString();
password = passwordTextbox.getText().toString();
url = urlTextbox.getText().toString();
if(RealDatabaseConnector.checkLogin(login, password, url)) {
Static.databaseConnector = new RealDatabaseConnector(login, password, url);
asyncDatabaseConnector = new AsyncDatabaseConnector(login, password, url);
asyncDatabaseConnector.setBooleanReturnListener(this);
asyncDatabaseConnector.checkLogin();
}
@Override
public void onBooleanReturn(boolean result) { //TODO: FIX that Strings
String login, password, url;
login = loginTextbox.getText().toString();
password = passwordTextbox.getText().toString();
url = urlTextbox.getText().toString();
if(result) {
Static.asyncDatabaseConnector = asyncDatabaseConnector;
Intent intent = new Intent(getActivity(), DatabaseActivity.class);
startActivity(intent);
}
else {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(RealDatabaseConnector.errorMsg);
builder.setMessage(Static.asyncDatabaseConnector.errorMsg);
builder.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// Nothing to do here
// Cleaning inputs is stupid
}
});
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// Nothing to do here
// Cleaning inputs is stupid
}
});
builder.setTitle(R.string.error);
builder.setIcon(R.drawable.ic_action_warning);
builder.create();

View file

@ -3,19 +3,13 @@ package info.nerull7.mysqlbrowser;
import android.content.Context;
import android.content.Intent;
import info.nerull7.mysqlbrowser.db.DatabaseConnector;
import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
/**
* Created by nerull7 on 14.07.14.
*/
public class Static {
public static DatabaseConnector databaseConnector = null;
public static boolean isDatabaseConnectorActive(){
if (databaseConnector==null)
return false;
return true;
}
public static AsyncDatabaseConnector asyncDatabaseConnector = null;
public static void startSettings(Context context){
Intent intent = new Intent(context, SettingsActivity.class);

View file

@ -17,10 +17,12 @@ import android.widget.TextView;
import java.util.List;
import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector;
/**
* Created by nerull7 on 14.07.14.
*/
public class TableFragment extends Fragment implements AdapterView.OnItemClickListener {
public class TableFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener{
private String databaseName;
private ListView tablesList;
private ListAdapter listAdapter;
@ -33,12 +35,23 @@ public class TableFragment extends Fragment implements AdapterView.OnItemClickLi
databaseName = getArguments().getString("DatabaseName");
tablesList = (ListView) rootView.findViewById(R.id.tableList);
this.rootView = (RelativeLayout) rootView;
setupList();
Static.asyncDatabaseConnector.setListReturnListener(this);
Static.asyncDatabaseConnector.getTables();
return rootView;
}
private void setupList(){
List<String> tables = Static.databaseConnector.getTables();
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String choosenTable = (String) listAdapter.getItem(position);
listAdapter.getItem(position);
Intent intent = new Intent(getActivity(), EntriesActivity.class);
intent.putExtra("DatabaseName",databaseName);
intent.putExtra("TableName",choosenTable);
startActivity(intent);
}
@Override
public void onListReturn(List<String> tables) {
if(tables != null) {
listAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1, tables);
tablesList.setAdapter(listAdapter);
@ -52,14 +65,4 @@ public class TableFragment extends Fragment implements AdapterView.OnItemClickLi
rootView.removeView(tablesList);
}
}
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String choosenTable = (String) listAdapter.getItem(position);
listAdapter.getItem(position);
Intent intent = new Intent(getActivity(), EntriesActivity.class);
intent.putExtra("DatabaseName",databaseName);
intent.putExtra("TableName",choosenTable);
startActivity(intent);
}
}

View file

@ -49,7 +49,7 @@ public class AsyncDatabaseConnector {
urlBuilder += "?u="+login;
urlBuilder += "&p="+password;
urlBuilder += "&a="+action;
Log.d("URLBuilder", urlBuilder);
Log.d("Async URLBuilder", urlBuilder);
return urlBuilder;
}
@ -60,29 +60,31 @@ public class AsyncDatabaseConnector {
private void getList(String urlQuery){
Downloader downloader = new Downloader(new Downloader.OnFinishedListener() {
@Override
public void onFinished(String data) {
public void onFinished(String data, String error) {
List<String>list = null;
try {
list = parseListFromJSON(data);
} catch (JSONException e) { e.printStackTrace(); }
if(listReturnListener!=null)
listReturnListener.onReturn(list);
listReturnListener.onListReturn(list);
}
});
downloader.execute(urlQuery);
}
private void getMatrix(String urlQuery){
Downloader downloader = new Downloader(new Downloader.OnFinishedListener() {
@Override
public void onFinished(String data) {
public void onFinished(String data, String error) {
List<List<String>> list = null;
try {
list = parseMatrixFromJSON(data);
} catch (JSONException e) { e.printStackTrace(); }
if(matrixReturnListener!=null)
matrixReturnListener.onReturn(list);
matrixReturnListener.onMatrixReturn(list);
}
});
downloader.execute(urlQuery);
}
private List<String> parseListFromJSON(String jsonListString) throws JSONException {
@ -111,12 +113,23 @@ public class AsyncDatabaseConnector {
public boolean checkLogin(){
Downloader downloader = new Downloader(new Downloader.OnFinishedListener() {
@Override
public void onFinished(String data) {
public void onFinished(String data, String error) {
List<String>list = null;
if(booleanReturnListener!=null)
booleanReturnListener.onReturn(data.compareTo("OK")==0);
boolean listenerData;
if(data==null) {
listenerData = false;
errorMsg = error;
}
else if(booleanReturnListener!=null)
listenerData = (data.compareTo("OK")==0);
else {
errorMsg = data;
listenerData = false;
}
booleanReturnListener.onBooleanReturn(listenerData);
}
});
downloader.execute(actionUrlBuilder("login"));
return false;
}
@ -154,26 +167,28 @@ public class AsyncDatabaseConnector {
}
public static interface BooleanReturnListener{
public void onReturn(boolean result);
public void onBooleanReturn(boolean result);
}
public static interface StringReturnListener{
public void onReturn(String data);
public void onStringReturn(String data);
}
public static interface ListReturnListener {
public void onReturn(List<String> data);
public void onListReturn(List<String> data);
}
public static interface MatrixReturnListener{
public void onReturn(List<List<String>> data);
public void onMatrixReturn(List<List<String>> data);
}
private static class Downloader extends AsyncTask<String, Void, String> {
OnFinishedListener onFinishedListener;
private OnFinishedListener onFinishedListener;
private String errorString;
Downloader(OnFinishedListener onFinishedListener){
this.onFinishedListener = onFinishedListener;
errorString = null;
}
private String httpRequest(String urlRequest) throws IOException {
@ -200,7 +215,7 @@ public class AsyncDatabaseConnector {
return response;
}
else {
errorMsg = "ERROR "+urlConnection.getResponseCode()+": "+urlConnection.getResponseMessage();
errorString = "ERROR "+urlConnection.getResponseCode()+": "+urlConnection.getResponseMessage();
return null;
}
}
@ -234,11 +249,12 @@ public class AsyncDatabaseConnector {
@Override
protected void onPostExecute(String data) {
onFinishedListener.onFinished(data); // Can't be null cos we demand listener in constructor
onFinishedListener.onFinished(data, errorMsg); // Can't be null cos we demand listener in constructor
Log.d("onPostExecute:",data);
}
private static interface OnFinishedListener {
void onFinished(String data);
void onFinished(String data, String error);
}
}
}

View file

@ -1,18 +0,0 @@
package info.nerull7.mysqlbrowser.db;
import java.util.List;
/**
* Created by nerull7 on 17.07.14.
*/
public interface DatabaseConnector {
void setDatabaseInUse(String database);
List<String> getDatabases();
List<String> getTables();
List<String> getFields(String table);
List<List<String>> getRows(String table, int count, int page);
}

View file

@ -1,85 +0,0 @@
package info.nerull7.mysqlbrowser.db;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by nerull7 on 07.07.14.
*/
public class FakeDatabaseConnector implements DatabaseConnector {
private String login;
private String password;
private String url;
private String database;
private String table;
public static String errorMsg;
public FakeDatabaseConnector(String login, String password, String url){
this.login = login;
this.password = password;
this.url = url;
}
public static boolean checkLogin(String login, String password, String url){
return true;
}
@Override
public void setDatabaseInUse(String database){
this.database = database;
}
@Override
public List<String> getDatabases(){
List<String> stringList = new ArrayList<String>();
stringList.add("Wordpress");
stringList.add("DB1");
stringList.add("owncloud");
Collections.sort(stringList);
return stringList;
}
@Override
public List<String> getTables(){
if(database==null) return null; // if database is not chosen return null
List<String> stringList = new ArrayList<String>();
stringList.add(database + ".Table1");
stringList.add(database + ".Table2");
stringList.add(database + ".Table3");
return stringList;
}
@Override
public List<String> getFields(String table){
if(database==null) return null; // if database is not chosen return null
List<String> stringList = new ArrayList<String>();
stringList.add("Field 1");
stringList.add("Field 2");
stringList.add("Field 3");
stringList.add("Field 4");
stringList.add("Field 5");
return stringList;
}
@Override
public List<List<String>> getRows(String table, int count, int page){
if(database==null) return null; // if database is not chosen return null
List<List<String>> stringListList = new ArrayList<List<String>>();
for(int i=0;i<count;i++) {
List<String> stringList = new ArrayList<String>();
stringList.add("Data 1"+i);
stringList.add("Data 2"+i);
stringList.add("Data 3"+i);
stringList.add("Data 4"+i);
stringList.add("Field aaa aaaaaaaa aaaaaa aaaaa4"+i);
stringListList.add(stringList);
}
return stringListList;
}
}

View file

@ -1,188 +0,0 @@
package info.nerull7.mysqlbrowser.db;
import android.os.StrictMode;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by nerull7 on 07.07.14.
*/
public class RealDatabaseConnector implements DatabaseConnector {
private String login;
private String password;
private String url;
private String database;
private String table;
public static String errorMsg;
public RealDatabaseConnector(String login, String password, String url){
this.login = login;
this.password = password;
this.url = url;
}
private static void disableStrictMode(){ // TODO THIS NEEDS TO NOT BE USED, WE CAN GET
StrictMode.ThreadPolicy policy = new StrictMode.
ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
private static String httpRequest(String urlRequest) throws IOException {
disableStrictMode(); // FIXME
URL url = new URL(urlRequest);
InputStream inputStream = null;
String response;
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); // TODO Handling no connection
urlConnection.setReadTimeout(10000 /* miliseconds FIXME*/);
urlConnection.setConnectTimeout(15000 /* miliseconds FIXME */);
urlConnection.setRequestMethod("GET");
urlConnection.setDoInput(true); // TODO what it does?
urlConnection.connect();
if(urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
try {
inputStream = urlConnection.getInputStream();
response = readStream(inputStream);
} finally {
if(inputStream!=null)
inputStream.close();
urlConnection.disconnect();
}
return response;
}
else {
errorMsg = "ERROR "+urlConnection.getResponseCode()+": "+urlConnection.getResponseMessage();
return null;
}
}
private static String readStream(InputStream in) throws IOException {
String streamOutput = "";
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
streamOutput += line;
}
} finally {
if (reader != null) {
reader.close();
}
}
return streamOutput;
}
private static String actionUrlBuilder(String login, String password, String url, String action){
String urlBuilder = url;
urlBuilder += "?u="+login;
urlBuilder += "&p="+password;
urlBuilder += "&a="+action;
Log.d("URLBuilder", urlBuilder);
return urlBuilder;
}
private String actionUrlBuilder(String action){
String urlBuilder = actionUrlBuilder(login, password, url, action);
return urlBuilder;
}
public static boolean checkLogin(String login, String password, String url){
errorMsg = null;
try {
String response = httpRequest(actionUrlBuilder(login,password,url,"login")); // TODO Redefine as public static final
if(response==null)
return false;
if(response.compareTo("OK")==0){
return true;
}
else {
errorMsg = response;
return false;
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public void setDatabaseInUse(String database){
this.database = database;
}
private List<String> getList(String urlQuery){
try {
String response = httpRequest(urlQuery);
if(response==null)
return null;
JSONArray jsonArray = new JSONArray(response);
List<String> databaseStringList = new ArrayList<String>();
for(int i=0;i<jsonArray.length();i++){
databaseStringList.add(jsonArray.getString(i));
}
return databaseStringList;
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
public List<String> getDatabases(){
return getList(actionUrlBuilder("dblist")); // TODO Redefine as public static final
}
public List<String> getTables(){
return getList(actionUrlBuilder("tablelist")+"&d="+database); // TODO Redefine as public static final
}
public List<String> getFields(String table){
return getList(actionUrlBuilder("fieldlist")+"&d="+database+"&t="+table); // TODO Redefine as public static final
}
private List<List<String>> getMatrix(String urlQuery){
try {
String response = httpRequest(urlQuery);
if(response==null)
return null;
JSONArray jsonMatrix = new JSONArray(response);
List<List<String>> matrix = new ArrayList<List<String>>();
for(int i=0;i<jsonMatrix.length();i++){
JSONArray jsonArray = jsonMatrix.getJSONArray(i);
List<String> list = new ArrayList<String>();
for(int j=0;j<jsonArray.length();j++){
list.add(jsonArray.getString(j));
}
matrix.add(list);
}
return matrix;
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
public List<List<String>> getRows(String table, int count, int page){
int limitStart = page * count;
return getMatrix(actionUrlBuilder("getrows")+"&d="+database+"&t="+table+"&s="+limitStart+"&l="+count); //FIXME
}
}