Android Studio Sqlite same name only 1 time listing - android

Trying to learn Android studio. And I expect your help on this.I am adding and listing data with sqlite.
for example;
id - name - value
1 - john - 100
2 - mark - 200
3 - john - 150
4 - john - 200
5 - adam - 400
what I want to do, list only names one time.
1 - john
2 - mark
3 - adam
private void showlist() {
ArrayList<DataListItems> contactList = new ArrayList<DataListItems>();
contactList.clear();
String query = "SELECT * FROM data ";
Cursor c1 = sqlHandler.selectQuery(query);
if (c1 != null && c1.getCount() != 0) {
if (c1.moveToFirst()) {
do {
DataListItems contactListItems = new DataListItems();
contactListItems.setid(c1.getString(c1
.getColumnIndex("id")));
contactListItems.setName(c1.getString(c1
.getColumnIndex("name")));
contactListItems.setValue(c1.getString(c1
.getColumnIndex("value")));
contactList.add(contactListItems);
} while (c1.moveToNext());
}
}
c1.close();
DataListAdapter contactListAdapter = new DataListAdapter(
SiteList.this, contactList);
lvCustomList.setAdapter(contactListAdapter);
}

You can use the GROUP BY name to select only one name. However, the id selected would be an arbitrary id for each group (name).
your code could use String query = "SELECT * FROM data GROUP BY name";
If you wanted the first/lowest id per name then you could use min(id) in conjunction with GROUP BY NAME.
your code could use String query = "SELECT min(id) AS id, name, value FROM data GROUP BY name";
You say that your expected result should be
1 - john
2 - mark
3 - adam
That would be more complicated (and perhaps of little use) as the id for adam is 5 not 3 (I assume that is simply a typing error).

Related

Sqlite Trigger to Update table 1 when certain rows of table 2 is updated

I have two tables in sqlite in android:
Table1: Outlets
id pid OutletName Status
1 1 Tesco 1
2 1 Coors 1
3 2 Coors 1
Table2: projectparams
ppid projectname outletname param projStatus
1 RA_Pepsi Tesco shelfstrip 2
2 RA_Pepsi Tesco shelfleft 2
3 RA_Cocola Coors shelfstrip 1
Table1: For every PID (ProjectID) there are multiple Outlets stored in OutletName.
Table2: For each outlet there are multiple params stored in project params.
Whenever the user completes a task the param in Table2 is updated to 2. In the above example, when the user completes two tasks in Tesco, the status would be updated to 2 upon completion.
I am trying to set the outlets status to 2 based on completion of tasks for every outlet. In this example, when the status is updated to 2 in projectparam table, I want the Status in Outlets to be updated to 2 for the outlet Tesco.
I am using the following codes:
triggered when the task gets completed.
private void updateTaskStatus() {
SQLiteDatabase db = sqLiteHelper.getWritableDatabase();
String spinTextRecovered = spnTxt.getString("spinText", null);
String updateTable = "update projectparams set projStatus=2 where param='"+spinTextRecovered+"' and projectName='"+projectName+"' and OutletName='"+outletName+"'";
db.execSQL(updateTable);
takePicButton.setEnabled( false );
}
Triggered every time when the task gets completed and updates the outlet status when all the tasks for an outlet is completed.
private void updateOutletStatus() {
String query = "select OutletName from projectparams where projectName= '"+projectName+"' and OutletName= '"+outletName+"' group by projStatus";
if (sqLiteHelper.getData(query).getCount()==1) {
Toast.makeText( getApplicationContext(), "No more tasks in this outlet!", Toast.LENGTH_SHORT ).show();
SQLiteDatabase db = sqLiteHelper.getWritableDatabase();
String outletUpdate = "update outlets set Status=2 where OutletName='"+outletName+"' and pid = (select id from projects where ProjectName = '"+projectName+"' ) ";
db.execSQL(outletUpdate);
}
}
The above code works...however since I am using an intent to display the projects, outlets and task parameters, many times i find the updation of outlet not happening.
Can i write this better? Can someone guide me to use triggers?
I believe your core issue is that the query
String query = "select OutletName from projectparams where projectName= '"+projectName+"' and OutletName= '"+outletName+"' group by projStatus";
Will return 1 not only if all the projects have completed but also if none have been completed (i.e. all the projStatus values are 1).
Additionally, as it stands if very much appears that the Outlets table is superfluous. That is all columns (bar the id, which serves no purpose) are duplicated in the projectparams table.
You can ascertain is all the tasks for a project by multiplying the number of params by 2 (the status completion value) against the sum of all of the projstatus values. If they match then all params have been set to 2.
Consider the following which is your data (but status 1 for RA_Perpsi/Tesco rows) plus some additional data where the only fully completed is for the Completed Example project (highlighted) as per :-
The using (to process all results)
-- WHERE clause removed group by projectname added (to show all results)
SELECT OutletName FROM projectparams GROUP BY projectname,projStatus;
The result is :-
That is Ra_Pepsi/Tesco has no params completed (nothing done) but there is only one row so the project is detected as being completed. Likewise for RA_Cocola and for Some other outlet.
Completed Example produces 1 row so is complete as it should be. Incomplete example (where it is part way through) is the only one that comes up as incomplete.
Using the above data consider the following (noting that no reference is needed to the Outlets table AND that the WHERE clause has been omitted and the GROUP BY according to projectname to show all projects) :-
SELECT
OutletName,
CASE
WHEN (count() * 2 - sum(projStatus)) = 0 THEN 2 ELSE 1
END AS Status,
(count() * 2 - sum(projStatus)) ||' of '||count() AS outstanding
FROM projectparams
GROUP BY projectname
This results in :-
As such there is no need for the Outlet Table the projectparams table, at least according to your example, is sufficient and as such there is no need for a trigger. Whenever an update is made you simply refresh the display using the one table and a query such as the last example.
To demonstrate your scenario step by step consider the following code (based upon the data above i.e. the RA_Pepsi has been added but nothing done) :-
-- First Query
SELECT
OutletName,
CASE
WHEN (count() * 2 - sum(projStatus)) = 0 THEN 2 ELSE 1
END AS Status,
(count() * 2 - sum(projStatus)) ||' of '||count() AS outstanding
FROM projectparams
WHERE projectname = 'RA_Pepsi'AND outletName = 'Tesco'
GROUP BY projectname
;
-- First Update
UPDATE projectparams SET projStatus = 2 WHERE param = 'shelfstrip' AND projectname = 'RA_Pepsi' AND outletName = 'Tesco';
-- 2nd Query
SELECT
OutletName,
CASE
WHEN (count() * 2 - sum(projStatus)) = 0 THEN 2 ELSE 1
END AS Status,
(count() * 2 - sum(projStatus)) ||' of '||count() AS outstanding
FROM projectparams
WHERE projectname = 'RA_Pepsi'AND outletName = 'Tesco'
GROUP BY projectname
;
-- 2nd Update (all completed)
UPDATE projectparams SET projStatus = 2 WHERE param = 'shelfleft' AND projectname = 'RA_Pepsi' AND outletName = 'Tesco';
-- 3rd Query
SELECT
OutletName,
CASE
WHEN (count() * 2 - sum(projStatus)) = 0 THEN 2 ELSE 1
END AS Status,
(count() * 2 - sum(projStatus)) ||' of '||count() AS outstanding
FROM projectparams
WHERE projectname = 'RA_Pepsi'AND outletName = 'Tesco'
GROUP BY projectname
;
The first query shows the project with nothing done as per :-
The 2nd query (after changing the status of the shelfstrip to 2) shows :-
The 3rd query (after changing the status of the shelfleft to 2) shows :-
For Android
The foloowing code demonstrates applying the above on Android and additional uses the recommended convenience methods (they build much of the SQL, off protection against SQL injection and add additional functionality e.g. update returns the number of rows updated) :-
Two methods (the first using the query above, the second updating as per yours but using the update convenience method :-
public String getOutletStatus(String projectname, String outletname) {
String rv = "Ooops nothing found!"; // default if nothing found
String[] columns = new String[]{"outletname",
"CASE " +
"WHEN (count() * 2 - sum(projStatus)) = 0 THEN 2 ELSE 1 " +
"END AS Status", //<<<<<<<<< the column name will be Status
"(count() * 2 - sum(projStatus)) ||' of '||count() AS outstanding" // The column name will be outstanding
};
String whereclause = "projectname=? AND outletName=?";
String[] whereargs = new String[]{projectname,outletname};
String groupby = "projectname"; // not needed
Cursor csr = sqliteHelper.getWritableDatabase().query("projectparams",columns,whereclause,whereargs,null,null,null);
if (csr.moveToFirst()) {
int statuscode = csr.getInt(csr.getColumnIndex("Status"));
String outstanding = csr.getString(csr.getColumnIndex("outstanding"));
String outlet = csr.getColumnName(csr.getColumnIndex("outletname"));
String statusdescription = "incomplete";
if (statuscode == 2) {
statusdescription = "complete";
}
rv = "The status of project " + projectname + " for outlet " + outlet + " is " + statusdescription + ". With " + outstanding + ".";
}
csr.close();
return rv;
}
public void updateStatus(String projectname, String outletname, String param) {
String whereclause = "projectname=? AND outletname=? AND param=?";
String[] whereargs = new String[]{projectname,outletname,param};
ContentValues cv = new ContentValues();
cv.put("projStatus",2);
int number_of_rows_updated = sqliteHelper.getWritableDatabase().update("projectparams",cv,whereclause,whereargs);
}
They have been tested (using the base data show above) and reflect the final 3 queries with updates between them :-
String status = getOutletStatus("RA_Pepsi","Tesco"); // Before anything
Log.d("RESULT",status);
updateStatus("RA_Pepsi","Tesco","shelfstrip"); //shelfstrip completed
status = getOutletStatus("RA_Pepsi","Tesco");
Log.d("RESULT",status);
updateStatus("RA_Pepsi","Tesco","shelfleft"); //shelfleft completed
status = getOutletStatus("RA_Pepsi","Tesco");
Log.d("RESULT",status);
Result in the Log :-
04-29 12:46:09.615 20471-20471/? D/RESULT: The status of project RA_Pepsi for outlet outletname is incomplete. With 2 of 2.
04-29 12:46:09.621 20471-20471/? D/RESULT: The status of project RA_Pepsi for outlet outletname is incomplete. With 1 of 2.
04-29 12:46:09.625 20471-20471/? D/RESULT: The status of project RA_Pepsi for outlet outletname is complete. With 0 of 2.

SQLite query works on android 4.4, but crashes on android 5.0

The following SQLite query works fine on android 4.4 and below, but it causes an exception: "android.database.sqlite.SQLiteException: ambiguous column name: number (code 1):......" on android 5.0 and later. I checked the SQLite release documents, but did not see any changes that can effect my work. Is there any thing that I missing?
select * from
(
select
'0' as queryid,
CNCT._id,
coalesce(case when length(C.abId)=0 then null else C.abId end,
(
select
addrBkId from numbers as nm,
contacts as cot
where nm.number=coalesce(C.number,S.Number) and nm.contactID = cot._id
order by cot.lastMod desc limit 1)) as addrBkId,
coalesce(
case when length(C.abId)=0 then null else C.abId end,
(
select
addrBkId from numbers as nm,
contacts as cot
where nm.number=coalesce(C.number,S.Number) and nm.contactID = cot._id
order by cot.lastMod desc
limit 1
)
) as uqAddrBkId,
CNCT.displayName,
CNCT.firstName,
CNCT.lastName,
CNCT.favorite,
coalesce(C.location,
(
select
location from calls as css
where css.number = S.Number
)) as location,
0 as numberType,
coalesce(C.number,S.Number) number,
N.txt,A.type,
coalesce(A.callID,A.smsId) actId,
max(A.startEpoch) as maa,
max(A.startTime),
strftime('%w',datetime(A.startEpoch,'unixepoch','localtime'))+0 dayOfWeek,
strftime('%W',datetime(A.startEpoch,'unixepoch','localtime'))+0 weekOfYear,C.duration,
case
when C.callResult='vmail' then 'vmail'||C._id
when C.callType='callin' and C.callResult='missed' then 'missed'
else C.callType end as newCallType,
C.callResult,
C.extension,
C.msgId,
C.audioUrl,
C.name,
C.state,
C.syncParams,
S.smsId,
S.dir,
S.state,
N.noteId,
N.color from activity as A
left outer join calls C on A.callId=C.callId
left outer join sms S on A.smsId=S.smsId
left outer join contacts CNCT on coalesce(case when length(C.abId)=0 then null else C.abId end,
(
select addrBkId from numbers as nm,
contacts as cot
where nm.number=coalesce(C.number,S.Number) and nm.contactID = cot._id
order by cot.updated desc
limit 1)
)=CNCT.addrBkId
left outer join
(
select * from notes as nt
order by nt.lastMod asc
) as N on CNCT.addrBkId=N.addrBkId
where (C.state<>5 or C.state is NULL) and (C.callResult<>'abandoned' or C.callResult is NULL)
group by newCallType,number,weekOfYear,dayOfWeek
order by max(A.startEpoch) asc
)
group by _id
order by maa desc
limit 3
... where nm.number=coalesce(C.number,S.Number) ...
... where nm.number=coalesce(C.number,S.Number) ...
... where css.number = S.Number) ...
... coalesce(C.number,S.Number) ...
... where nm.number=coalesce(C.number,S.Number) ...
... group by newCallType,number,...
^^^^^^
All occurences of number are qualified with a table alias, except the last one. That one indeed is ambiguous.

I need to separate the text from a string based on column names

I am working on OCR based Android app, getting this text as string from the attached image dynamically (getting the text in Horizontal Direction from the image)
Text from Image:
"Part Name Part Cost Engine Oil and Oil Filter Replacement Rs 10K Alf Filter Rs 4500 Cabin AC Micro Filter Rs 4000 Pollen Filter Rs 1200 - 1500 AC Disinfectant Rs 3000 Fuel Filter Rs 6000 - 8000 Spark Plug Set Replacement (Applicable in TFSI / Petrol Car Range) Rs 10K Body Wash, Basic Clean 8. Engine Degrease Rs 3000 Body Wax Polish Detailed Rs 7000 - 8000 Car interior Dry Clean with Genn Clean Rs 8000 - 10000 Wheel Alignment \u0026 Balancing Rs 6000 - 7000 Brake Pads Replacernent (Pair) Rs 30K - 32K Brake Disc Replacernent (Pair) Rs 30K - 35K ..........".
I need to separate the Part Name and Part Cost(just 2 columns i.e Part Name, Part Cost) (ignore all extra text from the column heading). Separate the values from String and should store it in SQLIte Database Android. I am stuck how to get the values and separate them.
The text returned from the OCR isn't ideal. The first thing you should do is check if whatever OCR solution can be configured to provide a better output. Ideally, you want the lines to be separated by newline characters and the space between the columns to be interpreted as something more useful, such as a tab character.
If you have no way of changing the text you get, you'll have to find some way of parsing it. You may want to look into using a parser, such as ANTLR to make this easier.
The following observations may help you to come up with a parsing strategy:
Column 2 items all start with "Rs" or "Upto Rs".
Column 2 items end with:
A number (where a number is allowed to be a string of digits [0-9.], optionally followed by a "K"
"Lakh"
Column 1 items don't begin with a number or "Lakh"
So a basic algorithm could be:
List<String> column1 = new ArrayList<String>();
List<String> column2 = new ArrayList<String>();
String[] tokens = ocrString.split(" ");
List<String> column = column1;
String item = "";
for (int i = 0; i < tokens.length; i++) {
String token = tokens[i];
String nextToken = i == tokens.length - 1 ? "" : tokens[i+1];
if (column == column1) {
if (token == "Rs" || (token == "Upto" && nextToken == "Rs")) {
column = column2;
column.add(item); item = "";
i--; continue;
}
item += " " + token;
} else {
item += " " + token;
if (/*token is number or "Lakh" and nextToken is not*/) {
column.add(item); item = "";
column = column1;
}
}
}

How to insert a table in to group in Corona SDK (.Lua)?

I get error message when i try to insert a table into a group
My table code is containing images
Here is the code i am using for the table
local myJoints = {}
for i = 1,5 do
local link = {}
for j = 1,17 do
link[j] = display.newImage( "link.png" )
link[j].x = 121 + (i*34)
link[j].y = 55 + (j*17)
physics.addBody( link[j], { density=2.0, friction=0, bounce=0 } )
-- Create joints between links
if (j > 1) then
prevLink = link[j-1] -- each link is joined with the one above it
else
prevLink = wall -- top link is joined to overhanging beam
end
myJoints[#myJoints + 1] = physics.newJoint( "pivot", prevLink, link[j], 121 + (i*34), 46 + (j*17) )
end
end
and here is the code for group
GUI:insert(myJoints);
i have my background image in the GUI group and it is covering the table.
I don't know if it is actually possible to insert table into a group
Any help please
Thanks in Advance!
You can't insert a table into a group using the "insert" method because that method is looking for a display object. Try calling GUI.myJoints = myJoints. Also keep in mind that your table just references your display objects, which is different from having them in a group.

Android : set selected item of a Spinner from DB with Cursor

I have a problem with Cursors.
I have 3 tables in my DB : facture (means invoice), vehicule (vehicle) and garage.
An invoice concerns one vehicle and one garage. When I create an invoice, I select the vehicle and the garage from spinners.
When I want to update an invoice, I need to set the item selected in these spinners.
Here is how I do :
for (int iVhc = 0; iVhc < spListeVhc.getCount(); iVhc++) {
Cursor valueVhc = (Cursor) spListeVhc.getItemAtPosition(iVhc);
long idVhc = facture.getLong(facture.getColumnIndexOrThrow("TB_VEHICULE._id"));
long idSpVhc = valueVhc.getLong(valueVhc.getColumnIndex("TB_VEHICULE._id"));
if (idSpVhc == idVhc) {
spListeVhc.setSelection(iVhc);
}
}
for (int iGar = 0; iGar < spListeGar.getCount(); iGar++) {
Cursor valueGar = (Cursor) spListeGar.getItemAtPosition(iGar);
long idGar = facture.getLong(facture.getColumnIndexOrThrow("TB_GARAGE._id"));
long idSpGar = valueGar.getLong(valueGar.getColumnIndex("TB_GARAGE._id"));
if (idSpGar == idGar) {
spListeGar.setSelection(iGar);
}
}
It works for the garage, but the problem is that, for a reason that I don't understand, the spinner of vehicles takes the same ID than the garage.
That means, if the garage selected has the ID 2 in the DB, the selected vehicle will be the vehicle with ID 2 too.
??
Here is my query to get the invoice:
public Cursor recupFacture(long idFacture){
return db.rawQuery("SELECT TB_FACTURE._id, libelle_fa, date_fa, nom_vhc, kilometrage_fa, nom_garage, remarque_fa, date_paie_fa, montant_fa, TB_VEHICULE._id, TB_GARAGE._id" +
" FROM TB_FACTURE, TB_VEHICULE, TB_GARAGE" +
" WHERE fk_vhc_fa = TB_VEHICULE._id" +
" AND fk_gar_fa = TB_GARAGE._id" +
" AND TB_FACTURE._id ="+idFacture, null);
}
And I realised that I have thi kind of mistakes in my log :
08-10 12:54:22.431: ERROR/Cursor(17072): requesting column name with table name -- TB_VEHICULE._id
And same for garage...
Thanks for your help!
EDIT :
I found a solution.
I replaced the TB_GARAGE._id and TB_VEHICULE._id by the fk at the lines :
long idVhc = facture.getLong(facture.getColumnIndexOrThrow("TB_VEHICULE._id"));
long idGar = facture.getLong(facture.getColumnIndexOrThrow("TB_GARAGE._id"));
However, I can't really explain why it works like this but not with the ID.
The prefix of the table causes a strange mistake...
Are you saving the invoice correctly? Make sure you are not accidentally saving the garage ID as vehicle ID as well.
Otherwise, how is "fracture" defined? Perhaps there is a mistake there.

Categories

Resources