My job is to maintain an application that is essentially a database for another application. the application uses ORM GreenDao.
Here is StorageUtil.getResults method which processes queries:
public static JSONArray getResults(Database database, String query) {
Cursor cursor = database.rawQuery(query, null);
JSONArray resultSet = new JSONArray();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
int totalColumn = cursor.getColumnCount();
JSONObject rowObject = new JSONObject();
for (int i = 0; i < totalColumn; i++) {
if (cursor.getColumnName(i) != null) {
try {
if (cursor.getString(i) != null) {
if (isJSONValid(cursor.getString(i))) {
try {
JSONObject object = new JSONObject(cursor.getString(i));
rowObject.put(cursor.getColumnName(i), object);
}catch (JSONException e){
Logger.error(e);
}
} else {
rowObject.put(cursor.getColumnName(i), cursor.getString(i));
}
} else {
rowObject.put(cursor.getColumnName(i), "");
}
} catch (Exception e) {
Logger.error(e);
}
}
}
resultSet.put(rowObject);
cursor.moveToNext();
}
cursor.close();
return resultSet;
}
Here is code of one of my entities:
#Entity(nameInDb = "UI_SV_FIAS")
#Storage(description = "FIAS", table = "UI_SV_FIAS")
public class Fias {
#Id
public String LINK;
#Property(nameInDb = "F_Street")
public String F_Street;
#Property(nameInDb = "C_Full_Address")
#Index
public String C_Full_Address;
#Property(nameInDb = "C_House_Number")
public String C_House_Number;
#Property(nameInDb = "C_Building_Number")
public String C_Building_Number;
public Fias() {
}
#Generated(hash = 1534843169)
public Fias(String LINK, String F_Street, String C_Full_Address,
String C_House_Number, String C_Building_Number) {
this.LINK = LINK;
this.F_Street = F_Street;
this.C_Full_Address = C_Full_Address;
this.C_House_Number = C_House_Number;
this.C_Building_Number = C_Building_Number;
}
Problem: the table has about 2,500,000 rows and when I get a query, for example, like this one:
http://localhost:8888/table?name=UI_SV_FIAS&query=select * from UI_SV_FIAS where C_Full_Address LIKE '%Чеченская%' ORDER BY C_House_Number, C_Full_Address limit 10
my app returns results in more then 10 seconds. But what I need is less then 3 seconds for such query.
Does anyone have an idea how can I get that?
Try this:
public static JSONArray getResults(Database database, String query) {
Cursor cursor = database.rawQuery(query, null);
JSONArray resultSet = new JSONArray();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
int totalColumn = cursor.getColumnCount();
JSONObject rowObject = new JSONObject();
for (int i = 0; i < totalColumn; i++) {
String columnName = cursor.getColumnName(i);
if (columnName != null) {
try {
String columnValue = cursor.getString(i);
if (columnValue != null) {
if (isJSONValid(columnValue)) {
try {
JSONObject object = new JSONObject(columnValue);
rowObject.put(columnName, object);
}catch (JSONException e){
Logger.error(e);
}
} else {
rowObject.put(columnName, columnValue);
}
} else {
rowObject.put(columnName, "");
}
} catch (Exception e) {
Logger.error(e);
}
}
}
resultSet.put(rowObject);
cursor.moveToNext();
}
cursor.close();
return resultSet;
}
Related
I want to get the events from a public google calendar in my app.
This is my activity, with the access to somePublicCalendar#google.com which I've changed for a fake account, but my calendar is public. Of course, somePublicCalendar#gmail.com is not my account and I can't manage it. Just want to see if I there's a gap for scheduling and appointment.
This is my activity, and for the moment, the cursor seems to be empty.
public class calendar extends AppCompatActivity implements View.OnClickListener{
CalendarView calendarView;
final int callbackId = 42;
Button home;
// Projection array. Creating indices for this array instead of doing
// dynamic lookups improves performance.
public static final String[] EVENT_PROJECTION = new String[] {
CalendarContract.Calendars._ID, // 0
CalendarContract.Calendars.ACCOUNT_NAME, // 1
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, // 2
CalendarContract.Calendars.OWNER_ACCOUNT // 3
};
// The indices for the projection array above.
private static final int PROJECTION_ID_INDEX = 0;
private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1;
private static final int PROJECTION_DISPLAY_NAME_INDEX = 2;
private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calendar);
home = findViewById(R.id.inicio);
calendarView = findViewById(R.id.calendarView);
checkPermission(callbackId, Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR);
calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
#Override
public void onSelectedDayChange(#NonNull CalendarView view, int year, int month, int dayOfMonth) {
consultarCalendario();
}
});
}
#Override
public void onRequestPermissionsResult(int callbackId,
String permissions[], int[] grantResults) {
}
public void consultarCalendario() {
// Run query
Cursor cur = null;
ContentResolver cr = getContentResolver();
Uri uri = CalendarContract.Calendars.CONTENT_URI;
String selection = "((" + CalendarContract.Calendars.ACCOUNT_NAME + " = ?) AND ("
+ CalendarContract.Calendars.ACCOUNT_TYPE + " = ?) AND ("
+ CalendarContract.Calendars.OWNER_ACCOUNT + " = ?))";
String[] selectionArgs = new String[]{"somePublicCalendar#gmail.com", "com.google",
"somePublicCalendar#gmail.com"};
// Submit the query and get a Cursor object back.
cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);
// Use the cursor to step through the returned records
while (cur.moveToNext()) {
long calID = 0;
String displayName = null;
String accountName = null;
String ownerName = null;
// Get the field values
calID = cur.getLong(PROJECTION_ID_INDEX);
displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX);
accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX);
ownerName = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX);
// Do something with the values...
Log.d("Conexion a calendario",calID + "/" + displayName+ "/" + accountName + "/" + ownerName);
}
}
private void checkPermission(int callbackId, String... permissionsId) {
boolean permissions = true;
for (String p : permissionsId) {
permissions = permissions && ContextCompat.checkSelfPermission(this, p) == PERMISSION_GRANTED;
}
if (!permissions)
ActivityCompat.requestPermissions(this, permissionsId, callbackId);
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.inicio:
startActivity(new Intent(this, Principal.class));
break;
}
}
}
I'm not familiar with the Calendar libraries you are using, but this is how I got entries from a Google Calendar:
private void callGetEvents() {
String sURL1 = "https://www.googleapis.com/calendar/v3/calendars/somePublicCalendar%40gmail.com/events?key=XYZTHECALENDARKEYZYX";
getEvents(sURL1);
}
private void getEvents(String url) {
final ProgressDialog dialog;
dialog = new ProgressDialog(thisContext);
dialog.setMessage((String) getResources().getText(R.string.loading_please_wait));
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
listOfEvents = new ArrayList<EventItem>();
JsonObjectRequest req = new JsonObjectRequest(url, null, new Response.Listener<JSONObject> () {
#SuppressLint("SimpleDateFormat")
#Override
public void onResponse(JSONObject response) {
try {
JSONArray items = response.getJSONArray("items");
Date today = new Date();
for (int i = 0; i < items.length(); i++) {
JSONObject oneObject = null;
try {
oneObject = items.getJSONObject(i);
} catch (JSONException e) {
continue;
}
String title = "";
try {
title = oneObject.getString("summary");
} catch (JSONException e) {
title = "";
}
String description = "";
try {
description = oneObject.getString("description");
} catch (JSONException e) {
description = "";
}
String location = "";
try {
location = oneObject.getString("location");
} catch (JSONException e) {
location = "";
}
JSONObject startObject = null;
String startDate = "";
Date start_date = new Date();
JSONObject endObject = null;
String endDate = "";
Date end_date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
try {
startObject = oneObject.getJSONObject("start");
startDate = startObject.getString("dateTime");
try {
start_date = dateFormat.parse(startDate);
} catch (java.text.ParseException e) {
e.printStackTrace();
}
} catch (JSONException e) {
e.printStackTrace();
}
try {
endObject = oneObject.getJSONObject("end");
endDate = endObject.getString("dateTime");
try {
end_date = dateFormat.parse(endDate);
} catch (java.text.ParseException e) {
e.printStackTrace();
}
} catch (JSONException e) {
e.printStackTrace();
}
EventItem item = new EventItem(title, description, location, start_date, end_date);
Log.i("Compare", today.toString() + ":" + endDate);
if (title.length() > 0) {
if (today.compareTo(end_date) < 0) {
listOfEvents.add(item);
}
}
}
Collections.sort(listOfEvents, new Comparator<EventItem>() {
public int compare(EventItem o1, EventItem o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
});
try {
adapter = new EventListAdapter(thisContext, listOfEvents);
eventListView.setAdapter(adapter);
} catch (Exception e) {
e.printStackTrace();
}
} catch (JSONException e) {
e.printStackTrace();
}
dialog.dismiss();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
Log.e("Error: ", error.getMessage());
dialog.dismiss();
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json; charset=UTF-8");
headers.put("Content-Type", "application/json; charset=UTF-8");
return headers;
};
};
// add the request object to the queue to be executed
MyApplication.getInstance().addToRequestQueue(req);
}
How can i convert this json array to a json object. And i need to store this json to a remote server. How can i do it. I cannot find a perfect tutorial for this purpose.
private JSONArray getResults() {
String myPath = "/data/data/com.example.sebastian.patientdetails/databases/" + "MyDBName.db";
String myTable = "patients";
SQLiteDatabase myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
String searchQuery = "SELECT * FROM " + myTable;
Cursor cursor = myDataBase.rawQuery(searchQuery, null);
JSONArray resultSet = new JSONArray();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
int totalColumn = cursor.getColumnCount();
JSONObject rowObject = new JSONObject();
for (int i = 0; i < totalColumn; i++) {
if (cursor.getColumnName(i) != null) {
try {
if (cursor.getString(i) != null) {
Log.d("TAG_NAME", cursor.getString(i));
rowObject.put(cursor.getColumnName(i), cursor.getString(i));
} else {
rowObject.put(cursor.getColumnName(i), "");
}
} catch (Exception e) {
Log.d("TAG_NAME", e.getMessage());
}
}
}
resultSet.put(rowObject);
cursor.moveToNext();
}
cursor.close();
Log.d("TAG_NAME", resultSet.toString());
return resultSet;
}
while (!cursor.isAfterLast()) {
int totalColumn = cursor.getColumnCount();
JSONObject rowObject = new JSONObject();
//new jsonarray
JSONArray jsonArray=new JSONArray();
for (int i = 0; i < totalColumn; i++) {
if (cursor.getColumnName(i) != null) {
//new jsonarray of items jsonObject
JSONObject object = new JSONObject();
try {
if (cursor.getString(i) != null) {
Log.d("TAG_NAME", cursor.getString(i));
object.put(cursor.getColumnName(i),cursor.getString(i));
} else {
object .put(cursor.getColumnName(i), "");
}
//put jsonarray
jsonArray.put(object );
} catch (Exception e) {
Log.d("TAG_NAME", e.getMessage());
}
}
}
//put request jsonobject
rowObject.put(jsonArray);
resultSet.put(rowObject);
cursor.moveToNext();
}
you can use Google of Gson.jar,
There is a method to convert json array into jsonObject,
JSONArray array;
for(int n = 0; n < array.length(); n++)
{
JSONObject object = array.getJSONObject(n);
//do what ever you want
}
I made a filter and filtering the values from the couch-base. Only first time i am able to getting the right filter values, after that it is returing the previous filter values every time. So i have to clear the cache every time. Please help.
Here is my query code.
public Query getFilterQuery(final String titles, final String sender,
final String sysName, final String prosName, final String fromDate,
final String toDate) {
final SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
com.couchbase.lite.View view = database.getView(FILTER_VIEW);
if (view.getMap() == null) {
Mapper mapper = new Mapper() {
public void map(Map<String, Object> document, Emitter emitter) {
String type = (String) document.get(AppConstants.KEY_DOC_TYPE);
if (AppConstants.DOC_TYPE_MESSAGE.equals(type)) {
String message_type = (String) document.get(AppConstants.MESSAGE_TYPE);
Log.d("message_type", message_type);
if (message_type.equals("task")) {
String msgDetails = (String) document.get(AppConstants.MESSAGE_BODY);
try {
JSONObject msgObj = new JSONObject(msgDetails);
DocumentReader documentReader = mApplication
.getDocumentReader(message_type);
documentReader.setJsonObject(msgObj);
String title = (String) documentReader.getValue("task.title");
JSONArray infoArray = (JSONArray) documentReader.getValue("task.info");
String taskDate = null;
String senderName = null;
String processName = null;
for (int i = 0; i < infoArray.length(); i++) {
JSONObject jObject = infoArray
.getJSONObject(i);
String field_label = jObject
.getString(AppConstants.LABEL);
if (field_label.equals(TASK_DATE)) {
taskDate = jObject
.getString(AppConstants.FIELD_VALUE);
Log.d("taskDate", taskDate);
}
if (field_label.equals(SENDER)) {
senderName = jObject
.getString(AppConstants.FIELD_VALUE);
}
if (field_label.equals(PROCESS_NAME)) {
processName = jObject
.getString(AppConstants.FIELD_VALUE);
}
}
Date dateFrom = null;
Date dateTo = null;
try {
date = dateFormat.parse(taskDate);
Log.d("taskDate", taskDate);
if (toDate != null && fromDate != null) {
dateTo = dateFormat.parse(toDate);
dateFrom = dateFormat.parse(fromDate);
}
} catch (ParseException e) {
e.printStackTrace();
}
/*if (titles != null && titles.contains(title)) {
emitter.emit(document.get(AppConstants.MESSAGE_ID),document);
}*/
if (senderName != null && senderName.contains(sender)) {
emitter.emit(document.get(AppConstants.MESSAGE_ID),document);
}
/*if (processName != null && processName.contains(prosName)) {
emitter.emit(document.get(AppConstants.MESSAGE_ID),document);
}*/
/*if (date.before(dateTo) && date.after(dateFrom)) {
emitter.emit(document.get(AppConstants.MESSAGE_ID),document);
}*/
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
};
view.setMap(mapper, "1");
}
Query query = view.createQuery();
return query;
}
}
A Query in Couchbase-lite is split into 2 parts.
Setting up the view (basically - the index)
Running the query against the view.
You should create you view only once (your mapper) and run queries against it with a search term under startkey and endkey.
You can also do a compound index, which is basically a string compound from several keys and search by it.
If you set the map everytime you run the query-the query will not be updated, as it look at you version argument and it's always set to a string "1".
if you will change it you will get a new index for you query - but it should be used only in dev when you change your view.
Roi.
how can I "convert" a Cursor to a JSONArray?
my cursor as 3columns (_id, name, birth)
I've searched but I can't not find any examples
Cursor to JSONArray
public JSONArray cur2Json(Cursor cursor) {
JSONArray resultSet = new JSONArray();
cursor.moveToFirst();
while (cursor.isAfterLast() == false) {
int totalColumn = cursor.getColumnCount();
JSONObject rowObject = new JSONObject();
for (int i = 0; i < totalColumn; i++) {
if (cursor.getColumnName(i) != null) {
try {
rowObject.put(cursor.getColumnName(i),
cursor.getString(i));
} catch (Exception e) {
Log.d(TAG, e.getMessage());
}
}
}
resultSet.put(rowObject);
cursor.moveToNext();
}
cursor.close();
return resultSet;
}
private String cursorToString(Cursor crs) {
JSONArray arr = new JSONArray();
crs.moveToFirst();
while (!crs.isAfterLast()) {
int nColumns = crs.getColumnCount();
JSONObject row = new JSONObject();
for (int i = 0 ; i < nColumns ; i++) {
String colName = crs.getColumnName(i);
if (colName != null) {
String val = "";
try {
switch (crs.getType(i)) {
case Cursor.FIELD_TYPE_BLOB : row.put(colName, crs.getBlob(i).toString()); break;
case Cursor.FIELD_TYPE_FLOAT : row.put(colName, crs.getDouble(i)) ; break;
case Cursor.FIELD_TYPE_INTEGER: row.put(colName, crs.getLong(i)) ; break;
case Cursor.FIELD_TYPE_NULL : row.put(colName, null) ; break;
case Cursor.FIELD_TYPE_STRING : row.put(colName, crs.getString(i)) ; break;
}
} catch (JSONException e) {
}
}
}
arr.put(row);
if (!crs.moveToNext())
break;
}
crs.close(); // close the cursor
return arr.toString();
}
You can't convert the contents of a cursor directly into a JSONObject, but you can do that with some logic.
for eg: retrieve the Strings from the cursor, form a String which follows the JSON format, and use it to make a json object :
JSONObject jFromCursor=new JSONObject(string_in_JSON_format);
i'm using feed.jar of libs-for-android, and i need to parse json data.
I've founded JsonContentHandler.java class similar to XmlContentHandler.java used in demos.
Can you give me an example on how to use JsonContentHandler?
thank you.
ps: https://code.google.com/p/libs-for-android/
Example input:
{"results": [{"id": "1f3d", "title": "Result title", "content": "Some content"}, ...]}
Example code:
public class MyContentHandler extends JsonContentHandler {
private final MatrixCursor mOutput;
public MyContentHandler(MatrixCursor cursor) {
mOutput = cursor;
}
#Override
protected Object getContent(String source) throws JSONException {
JSONObject data = new JSONObject(source);
int columnCount = output.getColumnCount();
JSONArray results = data.getJSONArray("results");
for (int i = 0; i < results.length(); i++) {
JSONObject result = results.getJSONObject(i);
String id = result.getString("id");
String title = result.getString("title");
String content = result.getString("content");
// Generate a positive integer ID for compatibility with CursorAdapter
Long baseId = Long.valueOf(Math.abs(id.hashCode()));
RowBuilder builder = output.newRow();
for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
String columnName = output.getColumnName(columnIndex);
if (columnName.equals(MyContract.Items._ID)) {
builder.add(baseId);
} else if (columnName.equals(MyContract.Items.ID)) {
builder.add(id);
} else if (columnName.equals(MyContract.Items.TITLE)) {
builder.add(title);
} else if (columnName.equals(MyContract.Items.CONTENT)) {
builder.add(content);
} else {
throw new RuntimeException("Unknown column: " + columnName);
}
}
}
// Tell FeedLoader how many rows were added
return FeedLoader.documentInfo(results.length());
}
}