let db = require('@config/database') let Tags = require('@models/Tags') let Attachment = require('@models/Attachment') var rp = require('request-promise'); var SolrNode = require('solr-node'); let Notes = module.exports = {} // Create client var client = new SolrNode({ host: '127.0.0.1', port: '8983', core: 'note', protocol: 'http' }); Notes.create = (userId, noteText) => { return new Promise((resolve, reject) => { if(userId == null || userId < 10){ reject('User Id required to create note') } const created = Math.round((+new Date)/1000) db.promise() .query('INSERT INTO notes (user, text, created) VALUES (?,?,?)', [userId, noteText, created]) .then((rows, fields) => { resolve(rows[0].insertId) //Only return the new note ID when creating a new note }) .catch(console.log) }) } Notes.update = (userId, noteId, noteText, fancyInput, color) => { return new Promise((resolve, reject) => { const now = Math.round((+new Date)/1000) db.promise() .query('UPDATE notes SET text = ?, raw_input = ?, updated = ?, color = ? WHERE id = ? AND user = ? LIMIT 1', [noteText, fancyInput, now, color, noteId, userId]) .then((rows, fields) => { //Process note text and attachment data Attachment.scanTextForWebsites(userId, noteId, noteText).then( attachmentText => { // // Update Solr index // Tags.string(userId, noteId).then(tagString => { // JSON Data var data = { 'id': noteId,//string - ID of note 'user_id': userId,//int 'note_text': noteText, 'notes_tags': tagString, 'attachment_text': attachmentText, }; // Update document to Solr server client.update(data, function(err, result) { if (err) { console.log(err); return; } console.log('Note Solr Update, node/solrid ('+noteId+'):'); console.log(result.responseHeader) }); }) }) //Send back updated response resolve(rows[0]) }) .catch(console.log) }) } Notes.delete = (userId, noteId) => { return new Promise((resolve, reject) => { // DELETE FROM notes WHERE notes.id = 290 AND notes.user = 61; // DELETE FROM attachment WHERE attachment.note_id = 290 AND attachment.user_id = 61; // DELETE FROM notes_tags WHERE notes_tags.note_id = 290 AND notes_tags.user_id = 61; db.promise().query('DELETE FROM notes WHERE notes.id = ? AND notes.user = ?', [noteId,userId]) .then((rows, fields) => { db.promise().query('DELETE FROM attachment WHERE attachment.note_id = ? AND attachment.user_id = ?', [noteId,userId]) .then((rows, fields)=> { db.promise().query('DELETE FROM notes_tags WHERE notes_tags.note_id = ? AND notes_tags.user_id = ?', [noteId,userId]) .then((rows, fields)=> { console.log('All Deleted') resolve(true) }) }) }) }) } Notes.get = (userId, noteId) => { return new Promise((resolve, reject) => { db.promise() .query('SELECT text, updated, raw_input, color FROM notes WHERE user = ? AND id = ? LIMIT 1', [userId,noteId]) .then((rows, fields) => { resolve(rows[0][0]) }) .catch(console.log) }) } Notes.getLatest = (userId) => { return new Promise((resolve, reject) => { db.promise() .query('SELECT id, SUBSTRING(text, 1, 100) as text FROM notes WHERE user = ? ORDER BY updated DESC, created DESC', [userId]) .then((rows, fields) => { resolve(rows[0]) }) .catch(console.log) }) } Notes.solrQuery = (userId, searchQuery, searchTags) => { return new Promise((resolve, reject) => { if(searchQuery != '' && searchQuery != null){ let urlQuery = `/solr/note/select?hl.fl=note_text&hl=on&q=user_id:${userId} AND note_text:${searchQuery}&wt=json` urlQuery = `/solr/note/select? hl.fl=note_text,attachment_text,notes_tags& hl=on& q=user_id:${userId} AND (note_text:${searchQuery} OR attachment_text:${searchQuery} OR notes_tags:${searchQuery})& wt=json& fl=id& hl.fl=note_text,attachment_text,notes_tags& hl.snippets=20& hl.maxAnalyzedChars=100000` rp('http://127.0.0.1:8983'+urlQuery) .then(function (htmlString) { let solrResult = JSON.parse(htmlString) resolve(solrResult) }) } else { resolve([]) } }) } Notes.search = (userId, searchQuery, searchTags) => { return new Promise((resolve, reject) => { //Define return data objects let returnData = { 'notes':[], 'tags':[] } Notes.solrQuery(userId, searchQuery, searchTags).then( solrResult => { let highlights = solrResult.highlighting //Parse Note ID's from solr search let solrNoteIds = [] if(solrResult.response){ solrResult.response.docs.forEach(item => { solrNoteIds.push(parseInt(item.id)) }) } //Default note lookup gets all notes let noteSearchQuery = ` SELECT notes.id, SUBSTRING(notes.text, 1, 400) as text, updated, color, count(distinct notes_tags.id) as tag_count, count(distinct attachment.id) as attachment_count FROM notes LEFT JOIN notes_tags ON (notes.id = notes_tags.note_id) LEFT JOIN attachment ON (notes.id = attachment.note_id AND attachment.attachment_type = 1) WHERE user = ?` let searchParams = [userId] if(solrNoteIds.length > 0){ searchParams.push(solrNoteIds) noteSearchQuery += ' AND notes.id IN (?)' } // if(searchQuery != ''){ // //If a search query is defined, search notes for that word // searchParams.push('%'+searchQuery+'%') // noteSearchQuery += ' AND text LIKE ?' // } if(searchTags.length > 0){ //If tags are passed, use those tags in search searchParams.push(searchTags) noteSearchQuery += ' AND notes_tags.tag_id IN (?)' } //Finish up note query noteSearchQuery += ' GROUP BY notes.id ORDER BY updated DESC, created DESC, id DESC' db.promise() .query(noteSearchQuery, searchParams) .then((noteRows, noteFields) => { //Push all notes returnData['notes'] = noteRows[0] //pull out all note ids so we can fetch all tags for those notes let noteIds = [] returnData['notes'].forEach(note => { //Grab note ID for finding tags noteIds.push(note.id) //Attempt to pull string out of first tag in note let reg = note.text.match(/<([\w]+)[^>]*>(.*?)<\/\1>/g) //Pull out first html tag contents, that is the title if(reg != null && reg[0]){ note.title = reg[0] //First line from HTML } else { note.title = note.text //Entire note } //Clean up html title note.title = note.title .replace(/&[#A-Za-z0-9]+;/g,'') //Rip out all HTML entities .replace(/<[^>]+>/g, '') //Rip out all HTML tags //Generate Subtext note.subtext = '' if(note.text != '' && note.title != ''){ note.subtext = note.text .replace(/&[#A-Za-z0-9]+;/g,' ') //Rip out all HTML entities .replace(/<[^>]+>/g, ' ') //Rip out all HTML tags .replace(/\s+/g, ' ') //Remove all whitespace .substring(note.title.length + 2) } note.note_highlights = [] note.attachment_highlights = [] note.tag_highlights = [] //Push in solr highlights if(highlights && highlights[note.id] && highlights[note.id].note_text){ note['note_highlights'] = highlights[note.id].note_text } if(highlights && highlights[note.id] && highlights[note.id].attachment_text){ note['attachment_highlights'] = highlights[note.id].attachment_text } if(highlights && highlights[note.id] && highlights[note.id].notes_tags){ note['tag_highlights'] = highlights[note.id].notes_tags } //Clear out note.text before sending it to front end delete note.text }) //If no notes are returned, there are no tags, return empty if(noteIds.length == 0){ resolve(returnData) } //Only show tags of selected notes db.promise() .query(`SELECT tags.id, tags.text, count(tags.id) as usages FROM notes_tags JOIN tags ON (tags.id = notes_tags.tag_id) WHERE notes_tags.user_id = ? AND note_id IN (?) GROUP BY tags.id ORDER BY usages DESC;`,[userId, noteIds]) .then((tagRows, tagFields) => { returnData['tags'] = tagRows[0] resolve(returnData) }) .catch(console.log) }) .catch(console.log) }) .catch(console.log) }) }