Prechádzať zdrojové kódy

DB tables now recreate when the app syncs.

seavenois 10 rokov pred
rodič
commit
e499c82524

+ 85 - 6
app/src/main/java/com/ivalentin/margolariak/GM.java

@@ -18,15 +18,94 @@ import java.util.Locale;
  */
 final class GM {
 
-	final class QUERY {
-
-		final class CREATE{
+	final class DB {
+
+		final class QUERY {
+
+			final class CREATE {
+				static final String ACTIVITY = "CREATE TABLE IF NOT EXISTS activity (id INT, permalink VARCHAR, date DATETIME, city VARCHAR, title_es VARCHAR, title_en VARCHAR, title_eu VARCHAR, text_es VARCHAR, text_en VARCHAR, text_eu VARCHAR, after_es VARCHAR, after_en VARCHAR, after_eu VARCHAR, price INT, inscription INT, max_people INT, album INT, dtime DATETIME, comments INT);";
+				static final String ACTIVITY_COMMENT = "CREATE TABLE IF NOT EXISTS activity_comment (id INT, activity INT, text VARCHAR, dtime DATETIME, username VARCHAR, lang VARCHAR);";
+				static final String ACTIVITY_IMAGE = "CREATE TABLE IF NOT EXISTS activity_image (id INT, activity INT, image VARCHAR, idx INT);";
+				static final String ACTIVITY_ITINERARY = "CREATE TABLE IF NOT EXISTS activity_itinerary (id INT, activity INT, name_es VARCHAR, name_en VARCHAR, name_eu VARCHAR, description_es VARCHAR, description_en VARCHAR, description_eu VARCHAR, start DATETIME, end DATETIME, place INT);";
+				static final String ACTIVITY_TAG = "CREATE TABLE IF NOT EXISTS activity_tag (activity INT, tag VARCHAR);";
+				static final String ALBUM = "CREATE TABLE IF NOT EXISTS album (id INT, permalink VARCHAR, title_es VARCHAR, title_en VARCHAR, title_eu VARCHAR, description_es VARCHAR, description_en VARCHAR, description_eu VARCHAR, open INT, time DATETIME);";
+				static final String FESTIVAL = "CREATE TABLE IF NOT EXISTS festival (id INT, year INT, text_es VARCHAR, text_en VARCHAR, text_eu VARCHAR, summary_es VARCHAR, summary_en VARCHAR, summary_eu VARCHAR, img VARCHAR);";
+				static final String FESTIVAL_DAY = "CREATE TABLE IF NOT EXISTS festival_day (id INT, date DATETIME, name_es VARCHAR, name_en VARCHAR, name_eu VARCHAR, price INT);";
+				static final String FESTIVAL_EVENT = "CREATE TABLE IF NOT EXISTS festival_event (id INT, gm INT, title_es VARCHAR, title_en VARCHAR, title_eu VARCHAR, description_es VARCHAR, description_en VARCHAR, description_eu VARCHAR, host INT, place INT, start DATETIME, end DATETIME);";
+				static final String FESTIVAL_EVENT_IMAGE = "CREATE TABLE IF NOT EXISTS festival_event_image (id INT, event INT, image VARCHAR, idx INT);";
+				static final String FESTIVAL_OFFER = "CREATE TABLE IF NOT EXISTS festival_offer (id INT, year INT, name_es VARCHAR, name_en VARCHAR, name_eu VARCHAR, description_es VARCHAR, description_en VARCHAR, description_eu VARCHAR, days INT, price INT);";
+				static final String LOCATION = "CREATE TABLE IF NOT EXISTS location (id INT, dtime DATETIME, lat FLOAT, lon FLOAT, manual INT);";
+				static final String NOTIFICATION = "CREATE TABLE IF NOT EXISTS notification (id INT, dtime DATETIME, duration INT, action VARCHAR, title_es VARCHAR, title_en VARCHAR, title_eu VARCHAR, text_es VARCHAR, text_en VARCHAR, text_eu VARCHAR, internal INT);";
+				static final String PEOPLE = "CREATE TABLE IF NOT EXISTS people (id INT, name_es VARCHAR, name_en VARCHAR, name_eu VARCHAR, link VARCHAR);";
+				static final String PHOTO = "CREATE TABLE IF NOT EXISTS photo (id INT, file VARCHAR, permalink VARCHAR, title_es VARCHAR, title_en VARCHAR, title_eu VARCHAR, description_es VARCHAR, description_en VARCHAR, description_eu VARCHAR, dtime DATETIME, uploaded DATETIME, place INT, width INT, height INT, size INT, username VARCHAR);";
+				static final String PHOTO_ALBUM = "CREATE TABLE IF NOT EXISTS photo_album (photo INT, album INT);";
+				static final String PHOTO_COMMENT = "CREATE TABLE IF NOT EXISTS photo_comment (id INT, photo INT, text VARCHAR, dtime DATETIME, username VARCHAR, lang VARCHAR);";
+				static final String PLACE = "CREATE TABLE IF NOT EXISTS place (id INT, name_es VARCHAR, name_en VARCHAR, name_eu VARCHAR, address_es VARCHAR, address_en VARCHAR, address_eu VARCHAR, cp VARCHAR, lat FLOAT, lon FLOAT);";
+				static final String POST = "CREATE TABLE IF NOT EXISTS post (id INT, permalink VARCHAR, title_es VARCHAR, title_en VARCHAR, title_eu VARCHAR, text_es VARCHAR, text_en VARCHAR, text_eu VARCHAR, dtime DATETIME, comments INT, username VARCHAR);";
+				static final String POST_COMMENT = "CREATE TABLE IF NOT EXISTS post_comment (id INT, post INT, text VARCHAR, dtime DATETIME, username VARCHAR, lang VARCHAR);";
+				static final String POST_IMAGE = "CREATE TABLE IF NOT EXISTS post_image (id INT, post INT, image VARCHAR, idx INT);";
+				static final String POST_TAG = "CREATE TABLE IF NOT EXISTS post_tag (post INT, tag VARCHAR);";
+				static final String SETTINGS = "CREATE TABLE IF NOT EXISTS settings (name VARCHAR, value VARCHAR);";
+				static final String SPONSOR = "CREATE TABLE IF NOT EXISTS sponsor (id INT, name_es VARCHAR, name_en VARCHAR, name_eu VARCHAR, text_es VARCHAR, text_en VARCHAR, text_eu VARCHAR, image VARCHAR, address_es VARCHAR, address_en VARCHAR, address_eu VARCHAR, link VARCHAR, lat FLOAT, lon FLOAT);";
+				static final String VERSION = "CREATE TABLE IF NOT EXISTS version (section VARCHAR, version INT);";
+			}
 
-			//static final String
-		}
+			final class DROP {
+				static final String ACTIVITY = "DROP TABLE activity;";
+				static final String ACTIVITY_COMMENT = "DROP TABLE activity_comment;";
+				static final String ACTIVITY_IMAGE = "DROP TABLE activity_image;";
+				static final String ACTIVITY_ITINERARY = "DROP TABLE activity_itinerary;";
+				static final String ACTIVITY_TAG = "DROP TABLE activity_tag;";
+				static final String ALBUM = "DROP TABLE album;";
+				static final String FESTIVAL = "DROP TABLE festival;";
+				static final String FESTIVAL_DAY = "DROP TABLE festival_day;";
+				static final String FESTIVAL_EVENT = "DROP TABLE festival_event;";
+				static final String FESTIVAL_EVENT_IMAGE = "DROP TABLE festival_event_image;";
+				static final String FESTIVAL_OFFER = "DROP TABLE festival_offer;";
+				static final String LOCATION = "DROP TABLE location;";
+				static final String NOTIFICATION = "DROP TABLE notification;";
+				static final String PEOPLE = "DROP TABLE people;";
+				static final String PHOTO = "DROP TABLE photo;";
+				static final String PHOTO_ALBUM = "DROP TABLE photo_album;";
+				static final String PHOTO_COMMENT = "DROP TABLE photo_comment;";
+				static final String PLACE = "DROP TABLE place;";
+				static final String POST = "DROP TABLE post;";
+				static final String POST_COMMENT = "DROP TABLE post_comment;";
+				static final String POST_IMAGE = "DROP TABLE post_image;";
+				static final String POST_TAG = "DROP TABLE post_tag;";
+				static final String SETTINGS = "DROP TABLE settings;";
+				static final String SPONSOR = "DROP TABLE sponsor;";
+				static final String VERSION = "DROP TABLE version;";
 
-		final class DELETE{
+			}
 
+			final class RECREATE {
+				static final String ACTIVITY = GM.DB.QUERY.DROP.ACTIVITY + GM.DB.QUERY.CREATE.ACTIVITY;
+				static final String ACTIVITY_COMMENT = GM.DB.QUERY.DROP.ACTIVITY_COMMENT + GM.DB.QUERY.CREATE.ACTIVITY_COMMENT;
+				static final String ACTIVITY_IMAGE = GM.DB.QUERY.DROP.ACTIVITY_IMAGE + GM.DB.QUERY.CREATE.ACTIVITY_IMAGE;
+				static final String ACTIVITY_ITINERARY = GM.DB.QUERY.DROP.ACTIVITY_ITINERARY + GM.DB.QUERY.CREATE.ACTIVITY_ITINERARY;
+				static final String ACTIVITY_TAG = GM.DB.QUERY.DROP.ACTIVITY_TAG + GM.DB.QUERY.CREATE.ACTIVITY_TAG;
+				static final String ALBUM = GM.DB.QUERY.DROP.ALBUM + GM.DB.QUERY.CREATE.ALBUM;
+				static final String FESTIVAL = GM.DB.QUERY.DROP.FESTIVAL + GM.DB.QUERY.CREATE.FESTIVAL;
+				static final String FESTIVAL_DAY = GM.DB.QUERY.DROP.FESTIVAL_DAY + GM.DB.QUERY.CREATE.FESTIVAL_DAY;
+				static final String FESTIVAL_EVENT = GM.DB.QUERY.DROP.FESTIVAL_EVENT + GM.DB.QUERY.CREATE.FESTIVAL_EVENT;
+				static final String FESTIVAL_EVENT_IMAGE = GM.DB.QUERY.DROP.FESTIVAL_EVENT_IMAGE + GM.DB.QUERY.CREATE.FESTIVAL_EVENT_IMAGE;
+				static final String FESTIVAL_OFFER = GM.DB.QUERY.DROP.FESTIVAL_OFFER + GM.DB.QUERY.CREATE.FESTIVAL_OFFER;
+				static final String LOCATION = GM.DB.QUERY.DROP.LOCATION + GM.DB.QUERY.CREATE.LOCATION;
+				static final String NOTIFICATION = GM.DB.QUERY.DROP.NOTIFICATION + GM.DB.QUERY.CREATE.NOTIFICATION;
+				static final String PEOPLE = GM.DB.QUERY.DROP.PEOPLE + GM.DB.QUERY.CREATE.PEOPLE;
+				static final String PHOTO = GM.DB.QUERY.DROP.PHOTO + GM.DB.QUERY.CREATE.PHOTO;
+				static final String PHOTO_ALBUM = GM.DB.QUERY.DROP.PHOTO_ALBUM + GM.DB.QUERY.CREATE.PHOTO_ALBUM;
+				static final String PHOTO_COMMENT = GM.DB.QUERY.DROP.PHOTO_COMMENT + GM.DB.QUERY.CREATE.PHOTO_COMMENT;
+				static final String PLACE = GM.DB.QUERY.DROP.PLACE + GM.DB.QUERY.CREATE.PLACE;
+				static final String POST = GM.DB.QUERY.DROP.POST + GM.DB.QUERY.CREATE.POST;
+				static final String POST_COMMENT = GM.DB.QUERY.DROP.POST_COMMENT + GM.DB.QUERY.CREATE.POST_COMMENT;
+				static final String POST_IMAGE = GM.DB.QUERY.DROP.POST_IMAGE + GM.DB.QUERY.CREATE.POST_IMAGE;
+				static final String POST_TAG = GM.DB.QUERY.DROP.POST_TAG + GM.DB.QUERY.CREATE.POST_TAG;
+				static final String SETTINGS = GM.DB.QUERY.DROP.SETTINGS + GM.DB.QUERY.CREATE.SETTINGS;
+				static final String SPONSOR = GM.DB.QUERY.DROP.SPONSOR + GM.DB.QUERY.CREATE.SPONSOR;
+				static final String VERSION = GM.DB.QUERY.DROP.VERSION + GM.DB.QUERY.CREATE.VERSION;
+			}
 		}
 	}
 

+ 175 - 121
app/src/main/java/com/ivalentin/margolariak/MainActivity.java

@@ -17,7 +17,9 @@ import android.content.SharedPreferences;
 import android.database.sqlite.SQLiteDatabase;
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
+import android.net.Uri;
 import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.KeyEvent;
@@ -36,13 +38,17 @@ import android.widget.RelativeLayout;
 import android.widget.TextView;
 import android.os.Handler;
 
+import com.google.android.gms.appindexing.Action;
+import com.google.android.gms.appindexing.AppIndex;
+import com.google.android.gms.appindexing.Thing;
+import com.google.android.gms.common.api.GoogleApiClient;
+
 /**
  * The main Activity of the app. It's actually the only activity, and it loads other fragments.
- * 
- * @author Iñigo Valentin
  *
+ * @author Iñigo Valentin
  */
-public class MainActivity extends Activity{
+public class MainActivity extends Activity {
 
 	//Alarm to get location and notifications.
 	private AlarmReceiver notificationAlarm;
@@ -69,7 +75,7 @@ public class MainActivity extends Activity{
 			Log.d("Location", "Fetched location page");
 			if (o.contains("<location>none</location>"))
 				result = false;
-			if (o.contains("<lat>") && o.contains("<lon>")){
+			if (o.contains("<lat>") && o.contains("<lon>")) {
 				lat = o.substring(o.indexOf("<lat>") + 5, o.indexOf("</lat>"));
 				lon = o.substring(o.indexOf("<lon>") + 5, o.indexOf("</lon>"));
 				result = true;
@@ -77,19 +83,18 @@ public class MainActivity extends Activity{
 
 			SharedPreferences settings = getSharedPreferences(GM.PREF, Context.MODE_PRIVATE);
 			SharedPreferences.Editor editor = settings.edit();
-			if (result){
+			if (result) {
 				editor.putLong(GM.PREF_GM_LATITUDE, Double.doubleToLongBits(Double.parseDouble(lat)));
 				editor.putLong(GM.PREF_GM_LONGITUDE, Double.doubleToLongBits(Double.parseDouble(lon)));
 				editor.putString(GM.PREF_GM_LOCATION, new SimpleDateFormat("yyyyMMddHHmmss", Locale.US).format(Calendar.getInstance().getTime()));
 
 				//Show menu entry
-				if (menuItem[1] != null){
+				if (menuItem[1] != null) {
 					menuItem[1].setVisibility(View.VISIBLE);
 				}
-			}
-			else{
+			} else {
 				editor.putString(GM.PREF_GM_LOCATION, GM.DEFAULT_PREF_GM_LOCATION);
-				if (menuItem[1] != null){
+				if (menuItem[1] != null) {
 					menuItem[1].setVisibility(View.GONE);
 				}
 			}
@@ -99,6 +104,11 @@ public class MainActivity extends Activity{
 			locationHandler.postDelayed(checkForLocation, GM.INTERVAL_LOCATION);
 		}
 	};
+	/**
+	 * ATTENTION: This was auto-generated to implement the App Indexing API.
+	 * See https://g.co/AppIndexing/AndroidStudio for more information.
+	 */
+	private GoogleApiClient client;
 
 	//Not referenced in code.
 	public void showMenu(View v) {
@@ -106,7 +116,7 @@ public class MainActivity extends Activity{
 		MenuInflater inflater = popup.getMenuInflater();
 		inflater.inflate(R.menu.menu, popup.getMenu());
 
-		popup.getMenu().getItem(0).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener(){
+		popup.getMenu().getItem(0).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
 			@Override
 			public boolean onMenuItemClick(MenuItem item) {
 				Intent intent = new Intent(MainActivity.this, AboutActivity.class);
@@ -115,7 +125,7 @@ public class MainActivity extends Activity{
 			}
 		});
 
-		popup.getMenu().getItem(1).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener(){
+		popup.getMenu().getItem(1).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
 			@Override
 			public boolean onMenuItemClick(MenuItem item) {
 				Intent intent = new Intent(MainActivity.this, SponsorActivity.class);
@@ -124,7 +134,7 @@ public class MainActivity extends Activity{
 			}
 		});
 
-		popup.getMenu().getItem(2).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener(){
+		popup.getMenu().getItem(2).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
 			@Override
 			public boolean onMenuItemClick(MenuItem item) {
 				Intent intent = new Intent(MainActivity.this, SettingsActivity.class);
@@ -137,13 +147,12 @@ public class MainActivity extends Activity{
 	}
 
 
-
 	/**
 	 * Loads a section in the main screen.
-	 * 
+	 *
 	 * @param section Section identifier {@see GM}
 	 */
-	public void loadSection (byte section){
+	public void loadSection(byte section) {
 		FragmentManager fm = MainActivity.this.getFragmentManager();
 		FragmentTransaction ft = fm.beginTransaction();
 		Fragment fragment = null;
@@ -151,13 +160,13 @@ public class MainActivity extends Activity{
 		Bundle bundle = new Bundle();
 
 		//Reset all tabs to it's original state
-		for (int i = 0; i < 6; i ++){
+		for (int i = 0; i < 6; i++) {
 			menuText[i].setTypeface(null, Typeface.NORMAL);
 			menuImage[i].requestLayout();
 			menuImage[i].getLayoutParams().height = 2;
 		}
 
-		switch (section){
+		switch (section) {
 			case GM.SECTION_HOME:
 				fragment = new HomeLayout();
 				title = getString(R.string.menu_home);
@@ -175,10 +184,9 @@ public class MainActivity extends Activity{
 			case GM.SECTION_LABLANCA:
 				//Get settings
 				SharedPreferences preferences = getSharedPreferences(GM.PREF, Context.MODE_PRIVATE);
-				if (preferences.getInt(GM.PREF_DB_FESTIVALS, 0) == 1){
+				if (preferences.getInt(GM.PREF_DB_FESTIVALS, 0) == 1) {
 					fragment = new LablancaLayout();
-				}
-				else{
+				} else {
 					fragment = new LablancaNoFestivalsLayout();
 				}
 				title = getString(R.string.menu_lablanca);
@@ -225,7 +233,7 @@ public class MainActivity extends Activity{
 				menuImage[5].getLayoutParams().height = 8;
 				break;
 		}
-		
+
 		//Replace the fragment.
 		ft.replace(R.id.activity_main_content_fragment, fragment);
 		//ft.addToBackStack(title);
@@ -235,29 +243,28 @@ public class MainActivity extends Activity{
 
 	/**
 	 * Sets the title of the current section.
-	 * 
+	 *
 	 * @param title The title of the current section.
 	 */
-	public void setSectionTitle(String title){
+	public void setSectionTitle(String title) {
 		TextView tvTitle = (TextView) findViewById(R.id.activity_main_content_title);
 		tvTitle.setText(title);
 	}
 
 	/**
-	 * Runs when the activity is created. 
-	 * 
+	 * Runs when the activity is created.
+	 *
 	 * @param savedInstanceState Saved state of the activity.
-	 * 
-	 * @see android.app.Activity#onCreate(android.os.Bundle)
+	 * @see Activity#onCreate(Bundle)
 	 */
 	@SuppressWarnings("deprecation, ConstantConditions")
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
 
-	    //Get intent extras
-	    String action = getIntent().getStringExtra(GM.EXTRA_ACTION);
-	    String actionText = getIntent().getStringExtra(GM.EXTRA_TEXT);
-	    String actionTitle = getIntent().getStringExtra(GM.EXTRA_TITLE);
+		//Get intent extras
+		String action = getIntent().getStringExtra(GM.EXTRA_ACTION);
+		String actionText = getIntent().getStringExtra(GM.EXTRA_TEXT);
+		String actionTitle = getIntent().getStringExtra(GM.EXTRA_TITLE);
 
 		//Set an alarm for notifications..
 		//Wait a little
@@ -287,10 +294,10 @@ public class MainActivity extends Activity{
 		t.start();
 
 		//Remove title bar.
-	    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
-	    super.onCreate(savedInstanceState);
+		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
+		super.onCreate(savedInstanceState);
 
-	    //Set layout.
+		//Set layout.
 		setContentView(R.layout.activity_main);
 
 		//Assign menu items
@@ -323,27 +330,39 @@ public class MainActivity extends Activity{
 		//Set click listers for menu items
 		menuItem[0].setOnClickListener(new OnClickListener() {
 			@Override
-			public void onClick(View v) { loadSection(GM.SECTION_HOME); }
+			public void onClick(View v) {
+				loadSection(GM.SECTION_HOME);
+			}
 		});
 		menuItem[1].setOnClickListener(new OnClickListener() {
 			@Override
-			public void onClick(View v) { loadSection(GM.SECTION_LOCATION); }
+			public void onClick(View v) {
+				loadSection(GM.SECTION_LOCATION);
+			}
 		});
 		menuItem[2].setOnClickListener(new OnClickListener() {
 			@Override
-			public void onClick(View v) { loadSection(GM.SECTION_LABLANCA); }
+			public void onClick(View v) {
+				loadSection(GM.SECTION_LABLANCA);
+			}
 		});
 		menuItem[3].setOnClickListener(new OnClickListener() {
 			@Override
-			public void onClick(View v) { loadSection(GM.SECTION_ACTIVITIES); }
+			public void onClick(View v) {
+				loadSection(GM.SECTION_ACTIVITIES);
+			}
 		});
 		menuItem[4].setOnClickListener(new OnClickListener() {
 			@Override
-			public void onClick(View v) { loadSection(GM.SECTION_BLOG); }
+			public void onClick(View v) {
+				loadSection(GM.SECTION_BLOG);
+			}
 		});
 		menuItem[5].setOnClickListener(new OnClickListener() {
 			@Override
-			public void onClick(View v) { loadSection(GM.SECTION_GALLERY); }
+			public void onClick(View v) {
+				loadSection(GM.SECTION_GALLERY);
+			}
 		});
 
 		//Get preferences
@@ -352,60 +371,60 @@ public class MainActivity extends Activity{
 		//TODO: Read preferences. If there is a recent location, show the menu entry
 
 		//If the user code is not set, generate one
-		if (preferences.getString(GM.USER_CODE, "").length() == 0){
+		if (preferences.getString(GM.USER_CODE, "").length() == 0) {
 			SecureRandom random = new SecureRandom();
 			String newCode = new BigInteger(130, random).toString(32).substring(0, 16);
 			SharedPreferences.Editor editor = preferences.edit();
 			editor.putString(GM.USER_CODE, newCode);
 			editor.apply();
 		}
-		
+
 		//Cerate database if it's not already created
 		createDatabase();
 
-		
+
 		//If its the first time
-		if (preferences.getInt(GM.PREF_DB_VERSION, GM.DEFAULT_PREF_DB_VERSION) == GM.DEFAULT_PREF_DB_VERSION){
+		if (preferences.getInt(GM.PREF_DB_VERSION, GM.DEFAULT_PREF_DB_VERSION) == GM.DEFAULT_PREF_DB_VERSION) {
 			initialSync();
 		}
 		//If t's not the first time
-		else{
+		else {
 			//Sync db
 			sync();
-			
+
 			//Load initial section
 			loadSection(GM.SECTION_HOME);
-			
+
 			//If the intent had extras (from notifications), do something
-			if (actionText != null){
+			if (actionText != null) {
 				TextView tvDialogTitle, tvDialogText;
 				Button btDialogClose, btDialogAction;
 				Drawable dialogIcon;
-				if (actionTitle != null){
-					
+				if (actionTitle != null) {
+
 					//Create a dialog
 					final Dialog dialog = new Dialog(this);
-					
+
 					//Set up dialog window
 					dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
 					dialog.setContentView(R.layout.dialog_notification);
-					
+
 					//Set title
 					tvDialogTitle = (TextView) dialog.findViewById(R.id.tv_dialog_notification_title);
 					tvDialogTitle.setText(actionTitle);
-					
+
 					//Set text
 					tvDialogText = (TextView) dialog.findViewById(R.id.tv_dialog_notification_text);
 					tvDialogText.setText(actionText);
-					
+
 					//Set close button
 					btDialogClose = (Button) dialog.findViewById(R.id.bt_dialog_notification_close);
 					btDialogClose.setOnClickListener(new OnClickListener() {
-		    			@Override
-		    			public void onClick(View v) {
-		    				dialog.dismiss();
-		    			}
-		    		});
+						@Override
+						public void onClick(View v) {
+							dialog.dismiss();
+						}
+					});
 
 					//Set the icon
 					dialogIcon = getResources().getDrawable(R.drawable.ic_launcher);
@@ -420,7 +439,7 @@ public class MainActivity extends Activity{
 
 					//Set the action button
 					btDialogAction = (Button) dialog.findViewById(R.id.bt_dialog_notification_action);
-					if (action != null){
+					if (action != null) {
 						switch (action) {
 
 							case GM.EXTRA_ACTION_LABLANCA:
@@ -532,8 +551,7 @@ public class MainActivity extends Activity{
 								//Hide action button
 								btDialogAction.setVisibility(View.GONE);
 						}
-					}
-					else{
+					} else {
 						btDialogAction.setVisibility(View.GONE);
 					}
 
@@ -551,70 +569,72 @@ public class MainActivity extends Activity{
 				}
 			}
 		}
+		// ATTENTION: This was auto-generated to implement the App Indexing API.
+		// See https://g.co/AppIndexing/AndroidStudio for more information.
+		client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
 	}
-    
-    /**
-     * Creates the app database and fills it with the hard coded, default data.
-     */
-    private void createDatabase(){
-    	SQLiteDatabase db;
-    	try {
-    		//Create database
-    		db = openOrCreateDatabase(GM.DB_NAME, Activity.MODE_PRIVATE, null);
+
+	/**
+	 * Creates the app database and fills it with the hard coded, default data.
+	 */
+	private void createDatabase() {
+		SQLiteDatabase db;
+		try {
+			//Create database
+			db = openOrCreateDatabase(GM.DB_NAME, Activity.MODE_PRIVATE, null);
 
 			//TODO: Predefine these queries as static strings in GM.java, so they can be used also in Sync.java
-			db.execSQL("CREATE TABLE IF NOT EXISTS activity (id INT, permalink VARCHAR, date DATETIME, city VARCHAR, title_es VARCHAR, title_en VARCHAR, title_eu VARCHAR, text_es VARCHAR, text_en VARCHAR, text_eu VARCHAR, after_es VARCHAR, after_en VARCHAR, after_eu VARCHAR, price INT, inscription INT, max_people INT, album INT, dtime DATETIME, comments INT);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS activity_comment (id INT, activity INT, text VARCHAR, dtime DATETIME, username VARCHAR, lang VARCHAR);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS activity_image (id INT, activity INT, image VARCHAR, idx INT);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS activity_itinerary (id INT, activity INT, name_es VARCHAR, name_en VARCHAR, name_eu VARCHAR, description_es VARCHAR, description_en VARCHAR, description_eu VARCHAR, start DATETIME, end DATETIME, place INT);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS activity_tag (activity INT, tag VARCHAR);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS album (id INT, permalink VARCHAR, title_es VARCHAR, title_en VARCHAR, title_eu VARCHAR, description_es VARCHAR, description_en VARCHAR, description_eu VARCHAR, open INT, time DATETIME);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS festival (id INT, year INT, text_es VARCHAR, text_en VARCHAR, text_eu VARCHAR, summary_es VARCHAR, summary_en VARCHAR, summary_eu VARCHAR, img VARCHAR);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS festival_day (id INT, date DATETIME, name_es VARCHAR, name_en VARCHAR, name_eu VARCHAR, price INT);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS festival_event (id INT, gm INT, title_es VARCHAR, title_en VARCHAR, title_eu VARCHAR, description_es VARCHAR, description_en VARCHAR, description_eu VARCHAR, host INT, place INT, start DATETIME, end DATETIME);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS festival_event_image (id INT, event INT, image VARCHAR, idx INT);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS festival_offer (id INT, year INT, name_es VARCHAR, name_en VARCHAR, name_eu VARCHAR, description_es VARCHAR, description_en VARCHAR, description_eu VARCHAR, days INT, price INT);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS location (id INT, dtime DATETIME, lat FLOAT, lon FLOAT, manual INT);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS notification (id INT, dtime DATETIME, duration INT, action VARCHAR, title_es VARCHAR, title_en VARCHAR, title_eu VARCHAR, text_es VARCHAR, text_en VARCHAR, text_eu VARCHAR, internal INT);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS people (id INT, name_es VARCHAR, name_en VARCHAR, name_eu VARCHAR, link VARCHAR);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS photo (id INT, file VARCHAR, permalink VARCHAR, title_es VARCHAR, title_en VARCHAR, title_eu VARCHAR, description_es VARCHAR, description_en VARCHAR, description_eu VARCHAR, dtime DATETIME, uploaded DATETIME, place INT, width INT, height INT, size INT, username VARCHAR);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS photo_album (photo INT, album INT);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS photo_comment (id INT, photo INT, text VARCHAR, dtime DATETIME, username VARCHAR, lang VARCHAR);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS place (id INT, name_es VARCHAR, name_en VARCHAR, name_eu VARCHAR, address_es VARCHAR, address_en VARCHAR, address_eu VARCHAR, cp VARCHAR, lat FLOAT, lon FLOAT);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS post (id INT, permalink VARCHAR, title_es VARCHAR, title_en VARCHAR, title_eu VARCHAR, text_es VARCHAR, text_en VARCHAR, text_eu VARCHAR, dtime DATETIME, comments INT, username VARCHAR);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS post_comment (id INT, post INT, text VARCHAR, dtime DATETIME, username VARCHAR, lang VARCHAR);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS post_image (id INT, post INT, image VARCHAR, idx INT);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS post_tag (post INT, tag VARCHAR);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS settings (name VARCHAR, value VARCHAR);");
-			db.execSQL("CREATE TABLE IF NOT EXISTS sponsor (id INT, name_es VARCHAR, name_en VARCHAR, name_eu VARCHAR, text_es VARCHAR, text_en VARCHAR, text_eu VARCHAR, image VARCHAR, address_es VARCHAR, address_en VARCHAR, address_eu VARCHAR, link VARCHAR, lat FLOAT, lon FLOAT)");
-			db.execSQL("CREATE TABLE IF NOT EXISTS version (section VARCHAR, version INT);");
+			db.execSQL(GM.DB.QUERY.CREATE.ACTIVITY);
+			db.execSQL(GM.DB.QUERY.CREATE.ACTIVITY_COMMENT);
+			db.execSQL(GM.DB.QUERY.CREATE.ACTIVITY_IMAGE);
+			db.execSQL(GM.DB.QUERY.CREATE.ACTIVITY_ITINERARY);
+			db.execSQL(GM.DB.QUERY.CREATE.ACTIVITY_TAG);
+			db.execSQL(GM.DB.QUERY.CREATE.ALBUM);
+			db.execSQL(GM.DB.QUERY.CREATE.FESTIVAL);
+			db.execSQL(GM.DB.QUERY.CREATE.FESTIVAL_DAY);
+			db.execSQL(GM.DB.QUERY.CREATE.FESTIVAL_EVENT);
+			db.execSQL(GM.DB.QUERY.CREATE.FESTIVAL_EVENT_IMAGE);
+			db.execSQL(GM.DB.QUERY.CREATE.FESTIVAL_OFFER);
+			db.execSQL(GM.DB.QUERY.CREATE.LOCATION);
+			db.execSQL(GM.DB.QUERY.CREATE.NOTIFICATION);
+			db.execSQL(GM.DB.QUERY.CREATE.PEOPLE);
+			db.execSQL(GM.DB.QUERY.CREATE.PHOTO);
+			db.execSQL(GM.DB.QUERY.CREATE.PHOTO_ALBUM);
+			db.execSQL(GM.DB.QUERY.CREATE.PHOTO_COMMENT);
+			db.execSQL(GM.DB.QUERY.CREATE.PLACE);
+			db.execSQL(GM.DB.QUERY.CREATE.POST);
+			db.execSQL(GM.DB.QUERY.CREATE.POST_COMMENT);
+			db.execSQL(GM.DB.QUERY.CREATE.POST_IMAGE);
+			db.execSQL(GM.DB.QUERY.CREATE.POST_TAG);
+			db.execSQL(GM.DB.QUERY.CREATE.SETTINGS);
+			db.execSQL(GM.DB.QUERY.CREATE.SPONSOR);
+			db.execSQL(GM.DB.QUERY.CREATE.VERSION);
 			db.close();
-    	}
-    	catch (Exception ex){
-    		Log.e("Error creating database", ex.toString());
-    	}
-    }
+		} catch (Exception ex) {
+			Log.e("Error creating database", ex.toString());
+		}
+	}
 
 	/**
 	 * Performs a full sync against the remote database.
 	 */
-	private void sync(){
+	private void sync() {
 		ProgressBar pbSync = (ProgressBar) findViewById(R.id.pb_sync);
 		ImageView ivSync = (ImageView) findViewById(R.id.iv_logo);
 		new Sync(this, pbSync, ivSync).execute();
 	}
-	
+
 	/**
-	 * Perform an initial sync before the app can be used. 
-	 * A dialog will block the UI. 
+	 * Perform an initial sync before the app can be used.
+	 * A dialog will block the UI.
 	 * It is intended to be used only when the database is empty.
 	 */
 	@SuppressWarnings("ConstantConditions")
-	private void initialSync(){
+	private void initialSync() {
 		//Create a dialog
 		Dialog dialog = new Dialog(this);
 		dialog.setCancelable(false);
-		
+
 		//Set up the window
 		dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
 		dialog.setContentView(R.layout.dialog_sync);
@@ -627,21 +647,21 @@ public class MainActivity extends Activity{
 		lp.gravity = Gravity.CENTER;
 		lp.dimAmount = 0.4f;
 		dialog.getWindow().setAttributes(lp);
-		
+
 		//Sync
 		ProgressBar pbSync = (ProgressBar) findViewById(R.id.pb_sync);
 		ImageView ivSync = (ImageView) findViewById(R.id.iv_logo);
 		new Sync(this, pbSync, ivSync, dialog, this).execute();
 	}
-	
+
 	/**
-	 * Overrides onBackPressed(). 
+	 * Overrides onBackPressed().
 	 * Used to show the previous fragment instead of finishing the app.
-	 * 
-	 * @see android.support.v7.app.AppCompatActivity#onBackPressed()
+	 *
+	 * @see AppCompatActivity#onBackPressed()
 	 */
 	@Override
-	public void onBackPressed(){
+	public void onBackPressed() {
 		try {
 			FragmentManager fm = getFragmentManager();
 			if (fm.getBackStackEntryCount() > 1) {
@@ -650,22 +670,21 @@ public class MainActivity extends Activity{
 				finish();
 				super.onBackPressed();
 			}
-		}
-		catch (Exception ex){
+		} catch (Exception ex) {
 			Log.e("Error going back", "Finishing activity: " + ex.toString());
 			Log.e("RUNNABLE", "Finishing callback for location");
 			locationHandler.removeCallbacks(checkForLocation);
 			finish();
 			//super.onBackPressed();
 		}
-		
+
 	}
 
 	/**
 	 * Overrides onKeyUp().
 	 * Used to toggle the menu whent the key is pressed.
 	 *
-	 * @see android.app.Activity#onKeyUp(int, KeyEvent)
+	 * @see Activity#onKeyUp(int, KeyEvent)
 	 */
 	@Override
 	public boolean onKeyUp(int keyCode, KeyEvent event) {
@@ -677,21 +696,56 @@ public class MainActivity extends Activity{
 	}
 
 	@Override
-	public void onResume(){
+	public void onResume() {
 		locationHandler.post(checkForLocation);
 		super.onResume();
 	}
 
 	@Override
-	public void onPause(){
+	public void onPause() {
 		locationHandler.removeCallbacks(checkForLocation);
 		super.onPause();
 	}
 
 	@Override
-	public void onDestroy(){
+	public void onDestroy() {
 		locationHandler.removeCallbacks(checkForLocation);
 		super.onDestroy();
 	}
-	
+
+	/**
+	 * ATTENTION: This was auto-generated to implement the App Indexing API.
+	 * See https://g.co/AppIndexing/AndroidStudio for more information.
+	 */
+	public Action getIndexApiAction() {
+		Thing object = new Thing.Builder()
+				.setName("Main Page") // TODO: Define a title for the content shown.
+				// TODO: Make sure this auto-generated URL is correct.
+				.setUrl(Uri.parse("http://[ENTER-YOUR-URL-HERE]"))
+				.build();
+		return new Action.Builder(Action.TYPE_VIEW)
+				.setObject(object)
+				.setActionStatus(Action.STATUS_TYPE_COMPLETED)
+				.build();
+	}
+
+	@Override
+	public void onStart() {
+		super.onStart();
+
+		// ATTENTION: This was auto-generated to implement the App Indexing API.
+		// See https://g.co/AppIndexing/AndroidStudio for more information.
+		client.connect();
+		AppIndex.AppIndexApi.start(client, getIndexApiAction());
+	}
+
+	@Override
+	public void onStop() {
+		super.onStop();
+
+		// ATTENTION: This was auto-generated to implement the App Indexing API.
+		// See https://g.co/AppIndexing/AndroidStudio for more information.
+		AppIndex.AppIndexApi.end(client, getIndexApiAction());
+		client.disconnect();
+	}
 }

+ 47 - 12
app/src/main/java/com/ivalentin/margolariak/Sync.java

@@ -235,6 +235,40 @@ class Sync extends AsyncTask<Void, Void, Void> {
 		return url;
 	}
 
+	private boolean recreateDb(SQLiteDatabase db) {
+		boolean result = true;
+		try {
+			db.execSQL(GM.DB.QUERY.RECREATE.ACTIVITY);
+			db.execSQL(GM.DB.QUERY.RECREATE.ACTIVITY_COMMENT);
+			db.execSQL(GM.DB.QUERY.RECREATE.ACTIVITY_IMAGE);
+			db.execSQL(GM.DB.QUERY.RECREATE.ACTIVITY_ITINERARY);
+			db.execSQL(GM.DB.QUERY.RECREATE.ACTIVITY_TAG);
+			db.execSQL(GM.DB.QUERY.RECREATE.ALBUM);
+			db.execSQL(GM.DB.QUERY.RECREATE.FESTIVAL);
+			db.execSQL(GM.DB.QUERY.RECREATE.FESTIVAL_DAY);
+			db.execSQL(GM.DB.QUERY.RECREATE.FESTIVAL_EVENT);
+			db.execSQL(GM.DB.QUERY.RECREATE.FESTIVAL_EVENT_IMAGE);
+			db.execSQL(GM.DB.QUERY.RECREATE.FESTIVAL_OFFER);
+			db.execSQL(GM.DB.QUERY.RECREATE.PEOPLE);
+			db.execSQL(GM.DB.QUERY.RECREATE.PHOTO);
+			db.execSQL(GM.DB.QUERY.RECREATE.PHOTO_ALBUM);
+			db.execSQL(GM.DB.QUERY.RECREATE.PHOTO_COMMENT);
+			db.execSQL(GM.DB.QUERY.RECREATE.PLACE);
+			db.execSQL(GM.DB.QUERY.RECREATE.POST);
+			db.execSQL(GM.DB.QUERY.RECREATE.POST_COMMENT);
+			db.execSQL(GM.DB.QUERY.RECREATE.POST_IMAGE);
+			db.execSQL(GM.DB.QUERY.RECREATE.POST_TAG);
+			db.execSQL(GM.DB.QUERY.RECREATE.SETTINGS);
+			db.execSQL(GM.DB.QUERY.RECREATE.SPONSOR);
+			db.execSQL(GM.DB.QUERY.RECREATE.VERSION);
+		}
+		catch (Exception ex){
+			result = false;
+			Log.e("SYNC", "Error recreating the database: " + ex.toString());
+		}
+		return result;
+	}
+
 	/**
 	 * Stores version data for each section in the database.
 	 * Uses a custom JSON parser.
@@ -277,7 +311,7 @@ class Sync extends AsyncTask<Void, Void, Void> {
 		}
 		catch (Exception ex){
 			result = false;
-			Log.e("saveVersions", "Error saving the remote db versions: " + ex.toString());
+			Log.e("SYNC", "Error saving the remote db versions: " + ex.toString());
 		}
 		return result;
 	}
@@ -295,7 +329,7 @@ class Sync extends AsyncTask<Void, Void, Void> {
 		String key;
 		String value;
 		boolean result = true;
-		//try{
+		try{
 			str = data.substring(data.indexOf("[") + 1, data.lastIndexOf("]"));
 			while (str.indexOf("}") > 0){
 				try {
@@ -311,15 +345,15 @@ class Sync extends AsyncTask<Void, Void, Void> {
 				}
 				catch (Exception ex){
 					//End of string
-					Log.d("SAVEDATA", "End of string");
+					Log.d("SYNC", "End of string");
 					str = "";
 				}
 			}
-		//}
-		//catch (Exception ex){
-		//	Log.e("saveData", "Error saving the remote db data: " + ex.toString());
-		//	result = false;
-		//}
+		}
+		catch (Exception ex){
+			Log.e("saveData", "Error saving the remote db data: " + ex.toString());
+			result = false;
+		}
 
 		return result;
 	}
@@ -344,7 +378,6 @@ class Sync extends AsyncTask<Void, Void, Void> {
 		String[] keys = new String[99];
 
 		List<String> queries = new ArrayList<>();
-		//TODO: Add a query deleting the table and another recreating it, so its compatible with older installs.
 		queries.add("DELETE FROM " + table + ";");
 
 		int i = 0;
@@ -355,10 +388,12 @@ class Sync extends AsyncTask<Void, Void, Void> {
 				totalFields = 0;
 				values = new String[99];
 				keys = new String[99];
+
 				while (row.indexOf("\",") > 0) {
 					key = row.substring(row.indexOf("\"") + 1, row.indexOf("\":"));
 					value = row.substring(row.indexOf("\"", row.indexOf(":")), row.indexOf("\"", row.indexOf(":") + 2) + 1);
-					//Log.e("FIELD", key + ": " + value);
+					//TODO: Get data type
+					//TODO: Reencode
 
 					keys[totalFields] = key;
 					values[totalFields] = value;
@@ -366,7 +401,7 @@ class Sync extends AsyncTask<Void, Void, Void> {
 
 					row = row.substring(row.indexOf(value) + value.length() + 1);
 				}
-				//TODO: Last column
+				//Do last column
 				row = row.substring(row.indexOf("\"") + 1, row.indexOf("}"));
 				key = row.substring(0, row.indexOf("\""));
 				value = row.substring(row.indexOf(":") + 1);
@@ -483,7 +518,7 @@ class Sync extends AsyncTask<Void, Void, Void> {
 
 					//If the data is correctly parsed and stored, commit changes to the database.
 					db.beginTransaction();
-					if (saveVersions(db, strVersion) && saveData(db, strData)){
+					if (recreateDb(db) && saveVersions(db, strVersion) && saveData(db, strData)){
 						db.setTransactionSuccessful();
 						Log.d("SYNC", "The sync process finished correctly. Changes to the database will be commited");
 					}