sqlite> CREATE TABLE pets ( ...> _id INTEGER PRIMARY KEY AUTOINCREMENT, ...> name TEXT NOT NULL, ...> breed TEXT, ...> gender INTEGER NOT NULL, ...> weight INTEGER NOT NULL DEFAULT 0); sqlite> INSERT INTO pets ( name, breed, gender, weight) VALUES ( "Tommy", "Pomeranian", 1, 4); sqlite> INSERT INTO pets (name, breed, gender, weight) VALUES ("Garfield", "Tabby", 1, 14); sqlite> INSERT INTO pets (name, breed, gender, weight) VALUES ("Binx", "Bombay", 1, 6); sqlite> INSERT INTO pets (name, breed, gender, weight) VALUES ( "Lady", "Cocker Spaniel", 2, 14); sqlite> INSERT INTO pets (name, breed, gender, weight) VALUES ("Duke", "Unknown", 1, 70); sqlite> INSERT INTO pets (name, breed, gender, weight) VALUES ("Cat", "Tabby", 0, 7); sqlite> INSERT INTO pets (name, breed, gender, weight) VALUES ("Baxter", "Border Terrier", 1, 8); sqlite> INSERT INTO pets (name, gender, weight) VALUES ("Arlene", 2, 5); sqlite> UPDATE pets SET weight = 20 WHERE _id == 2; sqlite> SELECT _id, name, weight FROM pets; _id name weight ---------- ---------- ---------- 1 Tommy 4 2 Garfield 20 3 Binx 6 4 Lady 14 5 Duke 70 6 Cat 7 7 Baxter 8 8 Arlene 5 sqlite> UPDATE pets SET breed = "Pomeranian Terrier" WHERE id==1; Error: no such column: id sqlite> UPDATE pets SET weight = 0;
Category: Android
TABLE CONSTRAINTS
PRIMARY KEY, AUTO INCREMENT, NOT NULL, DEFAULT
CREATE TABLE headphones (_id INTEGER, name TEXT, price INTEGER, style INTEGER, in_stock INTEGER, description TEXT);
PRIMARY KEY: Ensure uniqueness. There can only be one primary key per table
AUTO INCREMENT: Automatically calculates new integer when row is added. Useful for IDs
CREATE TABLE headphones (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, price INTEGER, style INTEGER, in_stock INTEGER, description TEXT);
CREATE TABLE headphones (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, price INTEGER, style INTEGER, in_stock INTEGER, description TEXT);
DEFAULT
[slq]
CREATE TABLE headphones (_id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
price INTEGER,
style INTEGER,
in_stock INTEGER NOT NULL DEFAULT 0,
description TEXT);
[/sql]
SQL COMMANDS FOR APP
SELECT
->
SELECT * FROM pets;
* indicates “all rows and all columns”
“pets” specifies we want data from the pets table
INSERT INTO pets (_id, name, bread, gender, weight) VALUES(1, "TOMMY", "Pomeranian", 1, 4);
sqlite> .tables pets pets2 sqlite> SELECT * FROM pets; sqlite> INSERT INTO pets (_id, name, breed, gender, weight) ...> VALUES(1, "TOMMY", "Pomeranian", 1, 4); Error: table pets has no column named breed sqlite> INSERT INTO pets (_id, name, bread, gender, weight) ...> VALUES(1, "TOMMY", "Pomeranian", 1, 4); sqlite> INSERT INTO pets (_id, name, bread, gender, weight) ...> VALUES(2, "Garfield", "Tabby", 1, 8); sqlite> SELECT * FROM pets; 1|TOMMY|Pomeranian|1|4 2|Garfield|Tabby|1|8
CRUD
Create, Read, Update, Delete
In order to open and see the list of all the pets in the shelter taking read actions on the table.
Tapping on the entry in the CatalogActivity in order to see information about specific pet require Read.
From the EditorActivity, changing the weight of a specific pet requires taking Update actions on the table.
Using the option from the overflow menu that removes incorrectly entered pets requires Delete.
Selecting the “Insert Pet” option from the overflow menu to insert a list of default information requires taking Create actions on the table.
Types in SQLite
storage class, data types
NULL, INTEGER, REAL, TEXT, BLOB
No booleans, use INTEGER instead
Ex:
false = 0
true = 1
attribute
Name TEXT
Price INTEGER
Style INTEGER
In Stock INTEGER
Description TEXT
CREATE TABLE headphones (_id INTEGER, name TEXT, price INTEGER, style INTEGER, in_stock INTEGER, description TEXT);
CREATE TABLE pets (_id INTEGER, name TEXT, bread TEXT, gender INTEGER, weight INTEGER);
Computer Memory
Temporary Storage:Short term
-can be used for calculations or displaying data on screen
-quick to access
-short-lived
e.g.
-computer RAM
Permanent Storage:Long term
-can be used for storing user data
-slower to save and access data
-stick around forever(until deleted)
e.g.
-Hard disk, Flash drives
Different Data Storage Options
Files: good for saving large media files
SharedPreferences: Good for in-app user preferences, key and value, Unique String and primitive types and strings
SQLight Databases: Good for organizing a lot of related and structured data for easy access: Row, Column
commonly used for text data, easily grows in size and easily searchable
PS C:\Users\xxx> sqlite3 -version 3.15.0 2016-10-14 10:20:30 707875582fcba352b4906a595ad89198d84711d8 PS C:\Users\xxx> sqlite3 SQLite version 3.15.0 2016-10-14 10:20:30 Enter ".help" for usage hints. Connected to a transient in-memory database. Use ".open FILENAME" to reopen on a persistent database. sqlite> .open pets.db sqlite>
Verify Loader Behavior
add log message to
initLoader(), onCreateLoader() callback, Loader startLoading()method
onLoadFinished() callback, Loader loadInBackground() method
onLoaderReset() callback, queryUtils fetchEarthquakeData() method
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/list" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:divider="@null" android:dividerHeight="0dp"/> <TextView android:id="@+id/empty_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:textAppearance="?android:textAppearanceMedium"/> </RelativeLayout>
private TextView mEmptyStateTextView; @Override protected void onCreate(Bundle savedInstanceState){ mEmptyStateTextView = (TextView) findViewById(R.id.empty_view); earthquakeListView.setEmptyView(mEmptyStateTextView); } @Override public void onLoadFinished(Loader<List<Earthquake>> loader, List<Earthquake> earthquakes){ mEmptyStateTextView.setText(R.string.no_earthquakes); }
Async Task In Quake Report App
private class EarthquakeAsyncTask extends AsyncTask<String, Void, List<Earthquake>>{ ... }
https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&eventtype=earthquake&orderby=time&minmag=6&limit=10
Loader
https://developer.android.com/guide/components/loaders.html?utm_source=udacity&utm_medium=course&utm_campaign=android_basics
Loader manager
https://developer.android.com/reference/android/app/LoaderManager.html?utm_source=udacity&utm_medium=course&utm_campaign=android_basics
Loader callback
https://developer.android.com/reference/android/app/LoaderManager.LoaderCallbacks.html?utm_source=udacity&utm_medium=course&utm_campaign=android_basics
package com.example.android.quakereport; import android.content.AsyncTaskLoader; import android.content.Context; import java.util.List; public class EarthquakeLoader extends AsyncTaskLoader<List<Earthquake>>{ private static final String LOG_TAG = EarthquakeLoader.class.getName(); private String mUrl; public EarthquakeLoader(Context context, String url){ super(context); mUrl = url; } @Override protected void onStartLoading(){ forceLoad(); } @Override public List<Earthquake> loadInBackground(){ if (mUrl == null){ return null; } List<Earthquake> earthquakes = QueryUtils.fetchEarthquakeData(mUrl); return earthquakes; } }
Handle Empty or Null Cases
protected Event doInBackground(String... urls){ if (urls.length < 1 || urls[0] == null){ return null; } Event result = Utils.fetchEarthquakeData(urls[0]); return result; }
protected void onPostExecute(Event result){ if (result == null){ return; } updateUi(result); }
private class EarthquakeAsyncTask extends AsyncTask{ protected Event doInBackground(String... urls){ if (urls.length < 1 || urls[0] == null){ return null; } Event result = Utils.fetchEarthquakeData(urls[0]); return result; } protected void onPostExecute(Event result){ if (result == null){ return; } updateUi(result); } }
Asynctask callback methods
onPreExecute(): before the task is executed, Main
doInBackground(Params…): After onPreExecute, Background
onProgressUpdate(Progress…): After publishProgress() is called, while doInBackground is executing, Main
OnPostExecute(Result): After doInBackground() finishes, Main
Review of generics
ArrayList
add(E e)->requires object of type E as input
get(int index)->returns object of type E
ArrayAdapter
private class DownloadFileTask extends AsyncTask{ protected Long doInBackground(RUL... urls){ int count = urls.length; long totalSize = 0; for(int i = 0; i < count; i++){ totalSize += Downloader.downloadFile(url[i]); publishProgress((int)((i/(float) count)* 100)); if(isCancelled()) break; } return totalSize; } protected void onProgressUpdate(Integer... progress){ setProgressPercent(progress[0]); } protected void onPostExecute(long result){ showDialog("Downloaded " + result + " bytes"); } }
private class DownloadWebpageTask extends AsyncTask<String, Void, String>{ @Override protected String doInBackground(String... urls){ try { return downloadUrl(urls[0]); } catch (IOException e){ return "Unable to retrieve web page. URL may be invalid."; } } @Override protected void onPostExecute(String result){ textView.setText(result); } }