let db = require('@config/database') let Tags = require('@models/Tag') let Attachment = require('@models/Attachment') var rp = require('request-promise'); var SolrNode = require('solr-node'); let Note = module.exports = {} // Create client var client = new SolrNode({ host: '127.0.0.1', port: '8983', core: 'note', protocol: 'http' }); Note.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 note (user_id, 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) }) } Note.update = (userId, noteId, noteText, fancyInput, color) => { return new Promise((resolve, reject) => { const now = Math.round((+new Date)/1000) db.promise() .query('UPDATE note SET text = ?, raw_input = ?, updated = ?, color = ? WHERE id = ? AND user_id = ? 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, 'note_tag': 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) }) } Note.delete = (userId, noteId) => { return new Promise((resolve, reject) => { db.promise().query('DELETE FROM note WHERE note.id = ? AND note.user_id = ?', [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 note_tag WHERE note_tag.note_id = ? AND note_tag.user_id = ?', [noteId,userId]) .then((rows, fields)=> { resolve(true) }) }) }) }) } Note.get = (userId, noteId) => { return new Promise((resolve, reject) => { db.promise() .query('SELECT text, updated, raw_input, color FROM note WHERE user_id = ? AND id = ? LIMIT 1', [userId,noteId]) .then((rows, fields) => { resolve(rows[0][0]) }) .catch(console.log) }) } Note.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,note_tag& hl=on& q=user_id:${userId} AND (note_text:${searchQuery} OR attachment_text:${searchQuery} OR note_tag:${searchQuery})& wt=json& fl=id& hl.fl=note_text,attachment_text,note_tag& 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([]) } }) } Note.search = (userId, searchQuery, searchTags) => { return new Promise((resolve, reject) => { //Define return data objects let returnData = { 'notes':[], 'tags':[] } Note.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 note.id, SUBSTRING(note.text, 1, 400) as text, updated, color, count(distinct note_tag.id) as tag_count, count(distinct attachment.id) as attachment_count FROM note LEFT JOIN note_tag ON (note.id = note_tag.note_id) LEFT JOIN attachment ON (note.id = attachment.note_id AND attachment.attachment_type = 1) WHERE note.user_id = ?` let searchParams = [userId] if(solrNoteIds.length > 0){ searchParams.push(solrNoteIds) noteSearchQuery += ' AND note.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 note_tag.tag_id IN (?)' } //Finish up note query noteSearchQuery += ' GROUP BY note.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].note_tag){ note['tag_highlights'] = highlights[note.id].note_tag } //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 tag.id, tag.text, count(tag.id) as usages FROM note_tag JOIN tag ON (tag.id = note_tag.tag_id) WHERE note_tag.user_id = ? AND note_id IN (?) GROUP BY tag.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) }) }