With the database initialized, let's make sure we can store data in there.
So back in the db.js file in the helpers folder, we can add a new constant, insert place for example
which I export
and now here I want to get the title of the place, I want to get the imageUri, I want to get the address
and also a latitude and longitude, so I want to get all the data that makes up a place and in there,
now I want to insert the place into the database. For that, we'll use the same syntax as here so
I can just copy this because I also want to have a promise as a wrapper here so that I can conveniently
use then and catch or async await in the place where I call insert place
but of course the query I execute now is different.
Instead of creating a table, I now want to insert data into the table and
that's done with the insert into command.
Now you need to specify the table and that's places and then between parentheses, the fields you want to
target in there and
of course I want to target all fields except for the ID because as I mentioned, that will be autogenerated
which is very convenient of course
but I want to target my title field and now you need to make sure you match the names which you set
up there for your columns,
you need to match these names here now.
The order does not have to be the same but the naming is important,
so I want to target title, the imageUri, that's
also a name I chose up there, right?
So imageUri, address,
latitude and longitude
and now we need to specify what values should go in there.
You do that by adding the values keyword here after this list of columns you want to target
and now you have another pair of parentheses here where you specify the values that should go into each
of these columns.
Now the order of values here of course has to match the order of column identifiers you have here,
so the first value you enter here will go into the title, imageUri is the second value and so on.
Now what you could do here is you could use of course back ticks instead of single quotes and then for
example inject title here and then have a comma and then the imageUri and so on.
You could do that and it would work but this wouldn't be good,
this is insecure,
it opens a door for an attack pattern called SQL injection, where users could kind of maybe insert malicious
code in there and run other queries which could break the database.
Of course in this app where it's a local database just on this user's device, that might not be super
bad but still we want to defend against this and therefore here, you actually use a couple of placeholders,
you add question marks here and you need to add as many question marks as you need to enter values.
So here I'm entering five values, hence here I have five question marks separated by commas.
Now the concrete values for the question marks are provided in the second argument you pass to execute
SQL, this array of arguments. Previously it was empty,
now we fill in the arguments in the order we need them,
so title first, then imageUri and so on and the SQL package will then swap these question marks
for our values but not before validating them to ensure that such an injection attack can't happen.
So we get some extra automatic validation by using this approach and then we can enter the title here,
then the second piece of data was the imageUri,
then we need the address,
then we need the latitude and then we need the longitude,
so this is how we now pass our data into this query. Now in these success functions,
as I mentioned the first argument always is like the repetition of your query but the second argument
is then either the error or here the result of this query
and here I want to resolve this result so that in the place where we call insert place, we can actually
then listen to the resolving of the promise and get our result of this query which should be some
information about the record that was created.
So now we can call insert place and of course the place where I want to call it again is my places actions
file.
There we move the image, there
I now also want to reach out to my database and add an entry. To do that in here first of all, let's import
this insert place method from the helpers folder and there, from the db file and with that imported,
in add place after solving our filesystem and so on, here
I of course then also, still in the try catch block, want to try inserting data into the database.
This also can fail,
so having it in a try block isn't the worst idea.
So here I can call insert place and that returns a promise because we have our own promise in there, so
we can awaits this
and I get back my DB result thereafter, so I'll store this in a constant and now insert place of course
needs a title, an imageUri, an address, a latitude and longitude.
Now therefore I will forward my title which I already have,
I will forward the new path which is my imageUri and now for address, I'll use a dummy address because
we have no real address yet. For latitude,
I'll use a dummy number of 15.6 and for longitude, let's say 12.3.
Now this might be in the middle of the ocean, I don't know but at least we have some coordinates here
which we can use for now until we're able to fetch a real location.
Now this db result of course is interesting, so let's console log it and let's also by the way make
sure that we only dispatch this action and therefore touch our Redux store if we succeeded with both
the filesystem and the database action,
so inside of the try block and now, let's have a look at this. Now we should be able to store data in
the database,
so let's test this on Android where we can take an image,
this is a test.
Let's take an image here and see whether all of that works by now cropping that image and saving this place.
This works
and here we see some output, we see this is the result of our database action
and we see that one row was affected because one row was inserted and we also get back the ID that
was automatically created.
It's a numeric ID here but that's of course no problem,
so now we can also use this ID in our reducer instead of manually creating this state snapshot ID
here.
So that's a tiny improvement,
when we dispatch our action here in the place data, I now also want to provide the ID and that
ID can be fetched from the DB result constant and there, it's in the insert ID field here as you
can see,
so let's access insert ID here. Now in the reducer therefore, we no longer need to generate it like this,
instead here we can simply refer to action.placeData.id.
Now keep in mind there it's a number, here I actually want to have a string though you could also keep
a number but I will convert it to a string here and with that, we're now also using that ID, we're storing
it in the database. Of course now it would be nice to load all our data whenever our app restarts because
right now when it restarts, the data still is lost,
it's not really lost, it isn't a database
but we don't see it here because we don't load this into our Redux store which then of course is the
data we use in the running app.
So we need to make sure we do load the data into the Redux store when this app starts.