/*\r
- * This file is part of NeverNote \r
+ * This file is part of NixNote \r
* Copyright 2009 Randy Baumgarte\r
* \r
* This file may be licensed under the terms of of the\r
import java.util.HashMap;\r
import java.util.List;\r
\r
+import org.apache.commons.lang3.StringEscapeUtils;\r
+\r
import com.evernote.edam.type.Note;\r
import com.evernote.edam.type.NoteAttributes;\r
import com.evernote.edam.type.Resource;\r
\r
import cx.fbn.nevernote.Global;\r
import cx.fbn.nevernote.evernote.EnmlConverter;\r
+import cx.fbn.nevernote.evernote.NoteMetadata;\r
import cx.fbn.nevernote.sql.driver.NSqlQuery;\r
import cx.fbn.nevernote.utilities.ApplicationLogger;\r
import cx.fbn.nevernote.utilities.Pair;\r
noteTagsTable = new NoteTagsTable(logger, db);\r
getQueryWithContent = null;\r
getQueryWithoutContent = null;\r
- \r
}\r
// Create the table\r
public void createTable() {\r
- getQueryWithContent = new NSqlQuery(db.getConnection());\r
- getQueryWithoutContent = new NSqlQuery(db.getConnection());\r
+ //getQueryWithContent = new NSqlQuery(db.getConnection());\r
+ //getQueryWithoutContent = new NSqlQuery(db.getConnection());\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
logger.log(logger.HIGH, "Creating table Note...");\r
if (!query.exec("Create table Note (guid varchar primary key, " +\r
if (!query.exec("CREATE INDEX unsynchronized_notes on note (isDirty desc, guid);"))\r
logger.log(logger.HIGH, "note unsynchronized_notes index creation FAILED!!!"); \r
noteTagsTable.createTable();\r
- noteResourceTable.createTable(); \r
+// noteResourceTable.createTable(); \r
}\r
// Drop the table\r
public void dropTable() {\r
StringBuilder updated = new StringBuilder(simple.format(n.getUpdated())); \r
StringBuilder deleted = new StringBuilder(simple.format(n.getDeleted()));\r
\r
- EnmlConverter enml = new EnmlConverter(logger);\r
+ \r
\r
query.bindValue(":guid", n.getGuid());\r
query.bindValue(":updateSequenceNumber", n.getUpdateSequenceNum());\r
query.bindValue(":title", n.getTitle());\r
- query.bindValue(":content", enml.fixEnXMLCrap(enml.fixEnMediaCrap(n.getContent())));\r
+ if (isDirty) {\r
+ EnmlConverter enml = new EnmlConverter(logger);\r
+ query.bindValue(":content", enml.fixEnXMLCrap(enml.fixEnMediaCrap(n.getContent())));\r
+ }\r
+ else\r
+ query.bindValue(":content", n.getContent());\r
query.bindValue(":contentHash", n.getContentHash());\r
query.bindValue(":contentLength", n.getContentLength());\r
query.bindValue(":created", created.toString());\r
query.bindValue(":attributeSource", n.getAttributes().getSource());\r
query.bindValue(":attributeSourceUrl", n.getAttributes().getSourceURL());\r
query.bindValue(":attributeSourceApplication", n.getAttributes().getSourceApplication());\r
+ } else {\r
+ created = new StringBuilder(simple.format(n.getCreated())); \r
+ query.bindValue(":attributeSubjectDate", created.toString());\r
+ query.bindValue(":attributeLatitude", 0.0);\r
+ query.bindValue(":attributeLongitude", 0.0);\r
+ query.bindValue(":attributeAltitude", 0.0);\r
+ query.bindValue(":attributeAuthor", "");\r
+ query.bindValue(":attributeSource", "");\r
+ query.bindValue(":attributeSourceUrl", "");\r
+ query.bindValue(":attributeSourceApplication", "");\r
}\r
query.bindValue(":indexNeeded", true);\r
query.bindValue(":isExpunged", false);\r
} \r
// Setup queries for get to save time later\r
private void prepareQueries() {\r
- getQueryWithContent = new NSqlQuery(db.getConnection());\r
- getQueryWithoutContent = new NSqlQuery(db.getConnection());\r
- getAllQueryWithoutContent = new NSqlQuery(db.getConnection());\r
- \r
- if (!getQueryWithContent.prepare("Select "\r
- +"guid, updateSequenceNumber, title, "\r
- +"created, updated, deleted, active, notebookGuid, "\r
- +"attributeSubjectDate, attributeLatitude, attributeLongitude, attributeAltitude, "\r
- +"attributeAuthor, attributeSource, attributeSourceUrl, attributeSourceApplication, "\r
- +"content, contentHash, contentLength"\r
- +" from Note where guid=:guid and isExpunged=false")) {\r
- logger.log(logger.EXTREME, "Note SQL select prepare with content has failed.");\r
- logger.log(logger.MEDIUM, getQueryWithContent.lastError());\r
+ if (getQueryWithContent == null) {\r
+ getQueryWithContent = new NSqlQuery(db.getConnection());\r
+ if (!getQueryWithContent.prepare("Select "\r
+ +"guid, updateSequenceNumber, title, "\r
+ +"created, updated, deleted, active, notebookGuid, "\r
+ +"attributeSubjectDate, attributeLatitude, attributeLongitude, attributeAltitude, "\r
+ +"attributeAuthor, attributeSource, attributeSourceUrl, attributeSourceApplication, "\r
+ +"attributeContentClass, "\r
+ +"content, contentHash, contentLength"\r
+ +" from Note where guid=:guid and isExpunged=false")) {\r
+ logger.log(logger.EXTREME, "Note SQL select prepare with content has failed.");\r
+ logger.log(logger.MEDIUM, getQueryWithContent.lastError());\r
+ }\r
}\r
\r
- if (!getQueryWithoutContent.prepare("Select "\r
- +"guid, updateSequenceNumber, title, "\r
- +"created, updated, deleted, active, notebookGuid, "\r
- +"attributeSubjectDate, attributeLatitude, attributeLongitude, attributeAltitude, "\r
- +"attributeAuthor, attributeSource, attributeSourceUrl, attributeSourceApplication "\r
- +" from Note where guid=:guid and isExpunged=false")) {\r
- logger.log(logger.EXTREME, "Note SQL select prepare without content has failed.");\r
- logger.log(logger.MEDIUM, getQueryWithoutContent.lastError());\r
+ if (getQueryWithoutContent == null) {\r
+ getQueryWithoutContent = new NSqlQuery(db.getConnection());\r
+ if (!getQueryWithoutContent.prepare("Select "\r
+ +"guid, updateSequenceNumber, title, "\r
+ +"created, updated, deleted, active, notebookGuid, "\r
+ +"attributeSubjectDate, attributeLatitude, attributeLongitude, attributeAltitude, "\r
+ +"attributeAuthor, attributeSource, attributeSourceUrl, attributeSourceApplication, "\r
+ +"attributeContentClass"\r
+ +" from Note where guid=:guid and isExpunged=false")) {\r
+ logger.log(logger.EXTREME, "Note SQL select prepare without content has failed.");\r
+ logger.log(logger.MEDIUM, getQueryWithoutContent.lastError());\r
+ }\r
}\r
- if (!getAllQueryWithoutContent.prepare("Select "\r
+ \r
+ if (getAllQueryWithoutContent == null) {\r
+ getAllQueryWithoutContent = new NSqlQuery(db.getConnection());\r
+ \r
+ if (!getAllQueryWithoutContent.prepare("Select "\r
+"guid, updateSequenceNumber, title, "\r
+"created, updated, deleted, active, notebookGuid, "\r
+"attributeSubjectDate, attributeLatitude, attributeLongitude, attributeAltitude, "\r
- +"attributeAuthor, attributeSource, attributeSourceUrl, attributeSourceApplication "\r
+ +"attributeAuthor, attributeSource, attributeSourceUrl, attributeSourceApplication, "\r
+ +"attributeContentClass "\r
+" from Note where isExpunged = false")) {\r
- logger.log(logger.EXTREME, "Note SQL select prepare without content has failed.");\r
+ logger.log(logger.EXTREME, "Note SQL select prepare without content has failed.");\r
logger.log(logger.MEDIUM, getQueryWithoutContent.lastError());\r
+ }\r
}\r
}\r
\r
- // Get a note's content in raw, binary format for the sync.\r
- public String getNoteContentBinary(String guid) {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.prepare("Select content from note where guid=:guid");\r
- query.bindValue(":guid", guid);\r
- query.exec(); \r
- query.next();\r
- return query.valueString(0);\r
- }\r
+\r
// Get a note's content in blob format for index.\r
public String getNoteContentNoUTFConversion(String guid) {\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
}\r
// Get a note by Guid\r
public Note getNote(String noteGuid, boolean loadContent, boolean loadResources, boolean loadRecognition, boolean loadBinary, boolean loadTags) {\r
+\r
+// extractMetadata("otherKey:{values};baumgarte:{titleColor=fff;pinned=true;};finalKey:{values1);");\r
if (noteGuid == null)\r
return null;\r
if (noteGuid.trim().equals(""))\r
}\r
Note n = mapNoteFromQuery(query, loadContent, loadResources, loadRecognition, loadBinary, loadTags);\r
n.setContent(fixCarriageReturn(n.getContent()));\r
+ n.getAttributes().setContentClassIsSet(false);\r
return n;\r
}\r
// Get a note by Guid\r
DateFormat indfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");\r
// indfm = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy");\r
\r
- \r
Note n = new Note();\r
NoteAttributes na = new NoteAttributes();\r
n.setAttributes(na);\r
na.setSource(query.valueString(13));\r
na.setSourceURL(query.valueString(14));\r
na.setSourceApplication(query.valueString(15));\r
+ na.setContentClass(query.valueString(16));\r
\r
if (loadTags) {\r
- n.setTagGuids(noteTagsTable.getNoteTags(n.getGuid()));\r
+ List<String> tagGuids = noteTagsTable.getNoteTags(n.getGuid());\r
List<String> tagNames = new ArrayList<String>();\r
- TagTable tagTable = new TagTable(logger, db);\r
- for (int i=0; i<n.getTagGuids().size(); i++) {\r
- String currentGuid = n.getTagGuids().get(i);\r
+ TagTable tagTable = db.getTagTable();\r
+ for (int i=0; i<tagGuids.size(); i++) {\r
+ String currentGuid = tagGuids.get(i);\r
Tag tag = tagTable.getTag(currentGuid);\r
- tagNames.add(tag.getName());\r
+ if (tag.getName() != null)\r
+ tagNames.add(tag.getName());\r
+ else\r
+ tagNames.add("");\r
}\r
+\r
n.setTagNames(tagNames);\r
+ n.setTagGuids(tagGuids); \r
}\r
\r
if (loadContent) {\r
- \r
QTextCodec codec = QTextCodec.codecForLocale();\r
codec = QTextCodec.codecForName("UTF-8");\r
- String unicode = codec.fromUnicode(query.valueString(16)).toString();\r
- n.setContent(unicode);\r
+ String unicode = codec.fromUnicode(query.valueString(17)).toString();\r
+\r
+ // This is a hack. Basically I need to convert HTML Entities to "normal" text, but if I\r
+ // convert the < character to < it will mess up the XML parsing. So, to get around this\r
+ // I am "bit stuffing" the < to &< so StringEscapeUtils doesn't unescape it. After\r
+ // I'm done I convert it back.\r
+ StringBuffer buffer = new StringBuffer(unicode);\r
+ if (Global.enableHTMLEntitiesFix && unicode.indexOf("&#") > 0) {\r
+ unicode = query.valueString(17);\r
+ //System.out.println(unicode);\r
+ //unicode = unicode.replace("<", "&_lt;");\r
+ //unicode = codec.fromUnicode(StringEscapeUtils.unescapeHtml(unicode)).toString();\r
+ //unicode = unicode.replace("&_lt;", "<");\r
+ //System.out.println("************************");\r
+ int j=1;\r
+ for (int i=buffer.indexOf("&#"); i != -1 && buffer.indexOf("&#", i)>0; i=buffer.indexOf("&#",i+1)) {\r
+ j = buffer.indexOf(";",i)+1;\r
+ if (i<j) {\r
+ String entity = buffer.substring(i,j).toString();\r
+ int len = entity.length()-1;\r
+ String tempEntity = entity.substring(2, len);\r
+ try {\r
+ Integer.parseInt(tempEntity);\r
+ entity = codec.fromUnicode(StringEscapeUtils.unescapeHtml4(entity)).toString();\r
+ buffer.delete(i, j);\r
+ buffer.insert(i, entity);\r
+ } catch (Exception e){ }\r
+ \r
+ }\r
+ } \r
+ } \r
+ \r
+ n.setContent(unicode);\r
// n.setContent(query.valueString(16).toString());\r
\r
- String contentHash = query.valueString(17);\r
+ String contentHash = query.valueString(18);\r
if (contentHash != null)\r
n.setContentHash(contentHash.getBytes());\r
- n.setContentLength(new Integer(query.valueString(18)));\r
+ n.setContentLength(new Integer(query.valueString(19)));\r
}\r
if (loadResources)\r
n.setResources(noteResourceTable.getNoteResources(n.getGuid(), loadBinary));\r
logger.log(logger.MEDIUM, query.lastError());\r
}\r
\r
+// QTextCodec codec = QTextCodec.codecForLocale();\r
+// codec = QTextCodec.codecForName("UTF-8");\r
+// query.bindValue(":content", codec.fromUnicode(content).toString());\r
query.bindValue(":content", content);\r
query.bindValue(":guid", guid);\r
\r
}\r
public void restoreNote(String guid) {\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.prepare("Update Note set deleted='1969-12-31 19.00.00', active=true, isDirty=true where guid=:guid");\r
+ query.prepare("Update Note set deleted=:reset, active=true, isDirty=true where guid=:guid");\r
// query.prepare("Update Note set deleted=0, active=true, isDirty=true where guid=:guid");\r
query.bindValue(":guid", guid);\r
+ query.bindValue(":reset", "1969-12-31 19:00:00");\r
if (!query.exec()) {\r
logger.log(logger.MEDIUM, "Note restore failed.");\r
logger.log(logger.MEDIUM, query.lastError());\r
\r
\r
NSqlQuery note = new NSqlQuery(db.getConnection());\r
- NSqlQuery resources = new NSqlQuery(db.getConnection());\r
+ NSqlQuery resources = new NSqlQuery(db.getResourceConnection());\r
NSqlQuery tags = new NSqlQuery(db.getConnection());\r
- NSqlQuery words = new NSqlQuery(db.getConnection());\r
+ NSqlQuery words = new NSqlQuery(db.getIndexConnection());\r
\r
note.prepare("Delete from Note where guid=:guid");\r
resources.prepare("Delete from NoteResources where noteGuid=:guid");\r
logger.log(logger.MEDIUM, "Note tags delete failed.");\r
logger.log(logger.MEDIUM, tags.lastError());\r
}\r
+\r
if (!words.exec()) {\r
logger.log(logger.MEDIUM, "Word delete failed.");\r
logger.log(logger.MEDIUM, words.lastError());\r
}\r
\r
}\r
+ // Purge a bunch of notes based upon the notebook\r
+ public void expungeNotesByNotebook(String notebookGuid, boolean permanentExpunge, boolean needsSync) {\r
+ List<String> notes = getNotesByNotebook(notebookGuid);\r
+ for (int i=0; i<notes.size(); i++) {\r
+ expungeNote(notes.get(i), permanentExpunge, needsSync);\r
+ }\r
+ }\r
+\r
// Purge a note (actually delete it instead of just marking it deleted)\r
public void hideExpungedNote(String guid, boolean needsSync) {\r
NSqlQuery note = new NSqlQuery(db.getConnection());\r
- NSqlQuery resources = new NSqlQuery(db.getConnection());\r
+ NSqlQuery resources = new NSqlQuery(db.getResourceConnection());\r
NSqlQuery tags = new NSqlQuery(db.getConnection());\r
- NSqlQuery words = new NSqlQuery(db.getConnection());\r
+ NSqlQuery words = new NSqlQuery(db.getIndexConnection());\r
\r
note.prepare("Update Note set isExpunged=true where guid=:guid");\r
resources.prepare("Delete from NoteResources where noteGuid=:guid");\r
tags.prepare("Delete from NoteTags where noteGuid=:guid");\r
- words.prepare("Delete from words where guid=:guid");\r
+// words.prepare("Delete from words where guid=:guid");\r
\r
note.bindValue(":guid", guid);\r
resources.bindValue(":guid", guid);\r
logger.log(logger.MEDIUM, "Note tags delete failed.");\r
logger.log(logger.MEDIUM, tags.lastError());\r
}\r
- if (!words.exec()) {\r
- logger.log(logger.MEDIUM, "Word delete failed.");\r
- logger.log(logger.MEDIUM, words.lastError());\r
- }\r
+// System.out.println("Hiding Note: Deleting words");\r
+// if (!words.exec()) {\r
+// logger.log(logger.MEDIUM, "Word delete failed.");\r
+// logger.log(logger.MEDIUM, words.lastError());\r
+// }\r
if (needsSync) {\r
DeletedTable deletedTable = new DeletedTable(logger, db);\r
deletedTable.addDeletedItem(guid, "Note");\r
public void expungeAllDeletedNotes() {\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
query.exec("select guid, updateSequenceNumber from note where active = false");\r
+ List<String> guids = new ArrayList<String>();\r
+ List<Integer> usns = new ArrayList<Integer>();\r
while (query.next()) {\r
- String guid = query.valueString(0);\r
+ guids.add(query.valueString(0));\r
Integer usn = new Integer(query.valueString(1));\r
+ usns.add(usn);\r
+ }\r
+ \r
+ for (int i=0; i<guids.size(); i++) {\r
+ Integer usn = usns.get(i);\r
+ String guid = guids.get(i);\r
if (usn == 0)\r
expungeNote(guid, true, false);\r
else\r
public void updateNoteGuid(String oldGuid, String newGuid) {\r
boolean check;\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.prepare("Update Note set guid=:newGuid where guid=:oldGuid");\r
+ NSqlQuery resQuery = new NSqlQuery(db.getResourceConnection());\r
+ NSqlQuery wordQuery = new NSqlQuery(db.getIndexConnection());\r
+ query.prepare("Update Note set guid=:newGuid, original_guid=:original_guid where guid=:oldGuid");\r
\r
+ query.bindValue(":original_guid", oldGuid);\r
query.bindValue(":newGuid", newGuid);\r
query.bindValue(":oldGuid", oldGuid);\r
\r
logger.log(logger.MEDIUM, query.lastError());\r
}\r
\r
- query.prepare("Update words set guid=:newGuid where guid=:oldGuid");\r
- query.bindValue(":newGuid", newGuid);\r
- query.bindValue(":oldGuid", oldGuid);\r
- query.exec();\r
+ wordQuery.prepare("Update words set guid=:newGuid where guid=:oldGuid");\r
+ wordQuery.bindValue(":newGuid", newGuid);\r
+ wordQuery.bindValue(":oldGuid", oldGuid);\r
+ wordQuery.exec();\r
if (!check) {\r
logger.log(logger.MEDIUM, "Note guid update failed for Words.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
+ logger.log(logger.MEDIUM, wordQuery.lastError());\r
}\r
- query.prepare("Update noteresources set noteguid=:newGuid where noteguid=:oldGuid");\r
- query.bindValue(":newGuid", newGuid);\r
- query.bindValue(":oldGuid", oldGuid);\r
- query.exec();\r
+ resQuery.prepare("Update noteresources set noteguid=:newGuid where noteguid=:oldGuid");\r
+ resQuery.bindValue(":newGuid", newGuid);\r
+ resQuery.bindValue(":oldGuid", oldGuid);\r
+ resQuery.exec();\r
if (!check) {\r
logger.log(logger.MEDIUM, "Note guid update failed for noteresources.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
+ logger.log(logger.MEDIUM, resQuery.lastError());\r
}\r
}\r
// Update a note\r
- public void updateNote(Note n, boolean isNew) {\r
- boolean isExpunged = isNoteExpunged(n.getGuid());\r
- int titleColor = getNoteTitleColor(n.getGuid());\r
- expungeNote(n.getGuid(), !isExpunged, false);\r
+ public void updateNote(Note n) {\r
+ NoteMetadata meta = getNoteMetaInformation(n.getGuid());\r
+ String originalGuid = findAlternateGuid(n.getGuid());\r
+ expungeNote(n.getGuid(), true, false);\r
addNote(n, false);\r
- if (titleColor != -1)\r
- setNoteTitleColor(n.getGuid(), titleColor);\r
+ if (n!=null) {\r
+ updateNoteMetadata(meta);\r
+ }\r
+ if (originalGuid != null) {\r
+ updateNoteGuid(n.getGuid(), originalGuid);\r
+ updateNoteGuid(originalGuid, n.getGuid());\r
+ }\r
}\r
// Does a note exist?\r
public boolean exists(String guid) {\r
boolean retVal = query.next();\r
return retVal;\r
}\r
- // This is a convience method to check if a tag exists & update/create based upon it\r
- public void syncNote(Note tag, boolean isDirty) {\r
- if (exists(tag.getGuid()))\r
- updateNote(tag, isDirty);\r
+ // This is a convience method to check if a note exists & update/create based upon it\r
+ public void syncNote(Note note) {\r
+ // If we got the note from Evernote we use its \r
+ // metadata instead of the local copy.\r
+ NoteMetadata meta = null;\r
+ if (note.getAttributes() != null && note.getAttributes().getSourceApplication() != null) {\r
+ meta = extractMetadata(note.getAttributes().getSourceApplication());\r
+ } else \r
+ meta = getNoteMetaInformation(note.getGuid());\r
+ \r
+ // Now, if the note exists we simply update it. Otherwise we\r
+ // add a new note.\r
+ if (exists(note.getGuid())) {\r
+ updateNote(note);\r
+ }\r
else\r
- addNote(tag, isDirty);\r
+ addNote(note, false);\r
+ \r
+ // If we have metadata, we write it out.\r
+ if (meta != null) {\r
+ meta.setGuid(note.getGuid());\r
+ updateNoteMetadata(meta);\r
+ }\r
}\r
// Get a list of notes that need to be updated\r
public List <Note> getDirty() {\r
\r
return returnValue; \r
}\r
- // Get a list of notes that need to be updated\r
- public List <String> getUnsynchronizedGUIDs() {\r
- String guid;\r
- List<String> index = new ArrayList<String>();\r
- \r
- boolean check; \r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- check = query.exec("Select guid from Note where isDirty=true");\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL retrieve has failed: " +query.lastError().toString());\r
- \r
- // Get a list of the notes\r
- while (query.next()) {\r
- guid = new String();\r
- guid = query.valueString(0);\r
- index.add(guid); \r
- } \r
- return index; \r
- }\r
+\r
// Reset the dirty bit\r
public void resetDirtyFlag(String guid) {\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
public List<Note> getAllNotes() {\r
List<Note> notes = new ArrayList<Note>();\r
prepareQueries();\r
- boolean check; \r
+ boolean check; \r
+ if (getAllQueryWithoutContent == null) \r
+ prepareQueries();\r
NSqlQuery query = getAllQueryWithoutContent;\r
check = query.exec();\r
if (!check)\r
\r
// Update a note resource by the hash\r
public void updateNoteResourceGuidbyHash(String noteGuid, String resGuid, String hash) {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ NSqlQuery query = new NSqlQuery(db.getResourceConnection());\r
/* query.prepare("Select guid from NoteResources where noteGuid=:noteGuid and datahash=:hex");\r
query.bindValue(":noteGuid", noteGuid);\r
query.bindValue(":hex", hash);\r
return values;\r
}\r
\r
+ // Find a note based upon its title.\r
+ public List<Pair<String,String>> findNotesByTitle(String text) {\r
+ List<Pair<String,String>> results = new ArrayList<Pair<String,String>>();\r
+ boolean check; \r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ check = query.prepare("Select guid,title from Note where lower(title) like :title");\r
+ if (!check) \r
+ logger.log(logger.EXTREME, "Note SQL prepare for search by title has failed: " +query.lastError().toString());\r
+ \r
+ query.bindValue(":title", "%"+text.toLowerCase()+"%");\r
+ query.exec();\r
+ // Get a list of the notes\r
+ while (query.next()) {\r
+ Pair<String,String> p = new Pair<String,String>();\r
+ p.setFirst(query.valueString(0));\r
+ p.setSecond(query.valueString(1)); \r
+ results.add(p); \r
+ } \r
+ return results;\r
+ }\r
+\r
\r
\r
//********************************************************************************\r
} \r
return guids; \r
}\r
+\r
\r
+ // Get note meta information\r
+ public void updateNoteMetadata(NoteMetadata meta) {\r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ if (!query.prepare("Update Note set titleColor=:color, pinned=:pinned, attributeSourceApplication=:metaString where guid=:guid"))\r
+ logger.log(logger.EXTREME, "Note SQL prepare has failed on updateNoteMetadata.");\r
+ query.bindValue(":color", meta.getColor());\r
+ query.bindValue(":pinned", meta.isPinned());\r
+ query.bindValue(":guid", meta.getGuid());\r
+ query.bindValue(":metaString", buildMetadataString(meta));\r
+ if (!query.exec()) \r
+ logger.log(logger.EXTREME, "Note SQL exec has failed on updateNoteMetadata.");\r
+ return;\r
+ }\r
\r
- //**********************************************************************************\r
- //* Title color functions\r
- //**********************************************************************************\r
- // Get the title color of all notes\r
- public List<Pair<String, Integer>> getNoteTitleColors() {\r
- List<Pair<String,Integer>> returnValue = new ArrayList<Pair<String,Integer>>();\r
+ // Get all note meta information\r
+ public HashMap<String, NoteMetadata> getNotesMetaInformation() {\r
+ HashMap<String, NoteMetadata> returnValue = new HashMap<String, NoteMetadata>();\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
\r
- if (!query.exec("Select guid,titleColor from Note where titleColor != -1"))\r
- logger.log(logger.EXTREME, "Note SQL retrieve has failed on getUnindexed().");\r
+ if (!query.exec("Select guid,titleColor, isDirty, pinned from Note"))\r
+ logger.log(logger.EXTREME, "Note SQL retrieve has failed on getNoteMetaInformation.");\r
\r
- String guid;\r
- Integer color;\r
- \r
// Get a list of the notes\r
while (query.next()) {\r
- Pair<String, Integer> pair = new Pair<String,Integer>();\r
- guid = query.valueString(0);\r
- color = query.valueInteger(1);\r
- pair.setFirst(guid);\r
- pair.setSecond(color);\r
- returnValue.add(pair); \r
+ NoteMetadata note = new NoteMetadata();\r
+ note.setGuid(query.valueString(0));\r
+ note.setColor(query.valueInteger(1));\r
+ note.setDirty(query.valueBoolean(2, false));\r
+ int pinned = query.valueInteger(3);\r
+ if (pinned > 0) \r
+ note.setPinned(true);\r
+ returnValue.put(note.getGuid(), note); \r
} \r
\r
return returnValue;\r
}\r
- // Set a title color\r
- public void setNoteTitleColor(String guid, int color) {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- query.prepare("Update note set titlecolor=:color where guid=:guid");\r
- query.bindValue(":guid", guid);\r
- query.bindValue(":color", color);\r
- if (!query.exec())\r
- logger.log(logger.EXTREME, "Error updating title color.");\r
- }\r
- // Get in individual note's title color\r
- // Get the title color of all notes\r
- public Integer getNoteTitleColor(String guid) {\r
- List<Pair<String,Integer>> returnValue = new ArrayList<Pair<String,Integer>>();\r
+ // Get note meta information\r
+ public NoteMetadata getNoteMetaInformation(String guid) {\r
NSqlQuery query = new NSqlQuery(db.getConnection());\r
\r
- query.prepare("Select titleColor from Note where titleColor != -1 and guid=:guid");\r
- query.bindValue(":guid", guid);\r
- if (!query.exec())\r
- logger.log(logger.EXTREME, "Note SQL retrieve has failed on getNoteTitleColor(guid).");\r
+ if (!query.prepare("Select guid,titleColor, isDirty, pinned from Note where guid=:guid")) {\r
+ logger.log(logger.EXTREME, "Note SQL retrieve has failed on getNoteMetaInformation.");\r
+ return null;\r
+ }\r
+ query.bindValue(":guid", guid);\r
+ query.exec();\r
\r
- Integer color = -1;\r
- \r
// Get a list of the notes\r
while (query.next()) {\r
- Pair<String, Integer> pair = new Pair<String,Integer>();\r
- guid = query.valueString(0);\r
- color = query.valueInteger(1);\r
- pair.setFirst(guid);\r
- pair.setSecond(color);\r
- returnValue.add(pair); \r
+ NoteMetadata note = new NoteMetadata();\r
+ note.setGuid(query.valueString(0));\r
+ note.setColor(query.valueInteger(1));\r
+ note.setDirty(query.valueBoolean(2, false));\r
+ int pinned = query.valueInteger(3);\r
+ if (pinned > 0) \r
+ note.setPinned(true);\r
+ return note;\r
} \r
\r
- \r
- return color;\r
+ return null;\r
}\r
\r
\r
return 0; \r
}\r
\r
+ //***********************************************************************************\r
+ public String findAlternateGuid(String guid) {\r
+ boolean check;\r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ check = query.prepare("select guid from note where original_guid=:guid");\r
+ query.bindValue(":guid", guid);\r
+ check = query.exec();\r
+ if (!check) \r
+ logger.log(logger.EXTREME, "Note SQL findAlternateguid query failed: " +query.lastError().toString());\r
+ \r
+ if (query.next()) {\r
+ return query.valueString(0); \r
+ }\r
+\r
+ return null; \r
+ }\r
+ \r
+ //* Check if a note guid exists\r
+ public boolean guidExists(String guid) {\r
+ boolean check;\r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ check = query.prepare("select guid from note where guid=:guid");\r
+ query.bindValue(":guid", guid);\r
+ check = query.exec();\r
+ if (!check) \r
+ logger.log(logger.EXTREME, "Note SQL guidExists query failed: " +query.lastError().toString());\r
+ \r
+ if (query.next()) {\r
+ return true; \r
+ }\r
+\r
+ return false; \r
+ }\r
\r
// Update a note content's hash. This happens if a resource is edited outside of NN\r
public void updateResourceContentHash(String guid, String oldHash, String newHash) {\r
position = n.getContent().indexOf("<en-media", position+1);\r
}\r
}\r
+\r
+ // Extract metadata from a note's Note.attributes.sourceApplication\r
+ private NoteMetadata extractMetadata(String sourceApplication) {\r
+ String consumerKey = "baumgarte:{";\r
+ int startPos = sourceApplication.indexOf(consumerKey);\r
+ if (startPos < 0 )\r
+ return null;\r
+ \r
+ NoteMetadata meta = new NoteMetadata();\r
+ startPos = startPos+consumerKey.length();\r
+ \r
+// String startString = sourceApplication.substring(0,startPos);\r
+ String metaString = sourceApplication.substring(startPos);\r
+// String endString = metaString.substring(metaString.indexOf("};"));\r
+ int endPos = metaString.indexOf("};");\r
+ if (endPos > 0)\r
+ metaString = metaString.substring(0,endPos);\r
+ \r
+ String value = parseMetaString(metaString, "titleColor");\r
+ if (value != null)\r
+ meta.setColor(Integer.parseInt(value));\r
+ \r
+ value = parseMetaString(metaString, "pinned");\r
+ if (value != null && value.equals(true))\r
+ meta.setPinned(true);\r
+ \r
+ return meta;\r
+ }\r
+ \r
+ // Given a metadata string from attribute.sourceApplication, we\r
+ // extract the information for a given key.\r
+ private String parseMetaString(String metaString, String key) {\r
+ int startPos = metaString.indexOf(key);\r
+ if (startPos < 0)\r
+ return null;\r
+ \r
+ String value = metaString.substring(startPos+key.length()+1);\r
+ int endPos = value.indexOf(";");\r
+ if (endPos > 0)\r
+ value = value.substring(0,endPos);\r
+ \r
+ return value;\r
+ }\r
+ \r
+ // Given a set of metadata, we build a string that can be inserted\r
+ // into the attribute.sourceApplication string.\r
+ private String buildMetadataString(NoteMetadata meta) {\r
+ StringBuffer value = new StringBuffer(removeExistingMetaString(meta.getGuid()));\r
+ StringBuffer metaString = new StringBuffer();\r
+ \r
+ if (meta.isPinned()) {\r
+ metaString.append("pinned=true;");\r
+ }\r
+ if (meta.getColor() != -1) {\r
+ metaString.append("titleColor=" +new Integer(meta.getColor()).toString()+";");\r
+ }\r
+ if (metaString.length()>0) {\r
+ \r
+ // Adda any missing ";" or " " at the end of the existing \r
+ // string.\r
+ if (value.length()>1 && (!value.toString().trim().endsWith(";") || !value.toString().trim().endsWith(";"))) \r
+ value.append("; ");\r
+ \r
+ value.append("baumgarte:{");\r
+ value.append(metaString);\r
+ value.append("};");\r
+ return value.toString();\r
+ }\r
+ return null;\r
+ }\r
+\r
+ // This will remove the existing metadata string from the attribute.sourceApplication string.\r
+ private String removeExistingMetaString(String guid) {\r
+ NSqlQuery query = new NSqlQuery(db.getConnection());\r
+ \r
+ if (!query.prepare("Select attributeSourceApplication from Note where guid=:guid")) {\r
+ logger.log(logger.EXTREME, "Note SQL retrieve has failed in removeExistingMetaString.");\r
+ return null;\r
+ }\r
+ query.bindValue(":guid", guid);\r
+ query.exec();\r
+\r
+ // Get the application source string\r
+ String sourceApplication = null;\r
+ while (query.next()) {\r
+ sourceApplication = query.valueString(0);\r
+ }\r
+ if (sourceApplication == null) \r
+ return "";\r
+ \r
+ String consumerKey = "baumgarte:{";\r
+ int startPos = sourceApplication.indexOf(consumerKey);\r
+ if (startPos < 0 )\r
+ return sourceApplication;\r
+ String startString = sourceApplication.substring(0,startPos);\r
+ String metaString = sourceApplication.substring(startPos);\r
+ String endString = metaString.substring(metaString.indexOf("};")+2);\r
+\r
+ return startString+endString;\r
+ }\r
+\r
} \r
+\r
+\r
+\r
+\r