started some app structure
This commit is contained in:
parent
9046ccf137
commit
3286a2e52b
@ -22,7 +22,7 @@ imap.once("ready", function () {
|
||||
console.log(results[results.length - 1]);
|
||||
});
|
||||
|
||||
const f = imap.fetch(970, { bodies: ['TEXT'], size: true, struct: true, envelope: true });
|
||||
const f = imap.fetch(970, { size: true, struct: true, envelope: true });
|
||||
// var f = imap.seq.fetch('1:3', {
|
||||
// bodies: 'HEADER.FIELDS (FROM TO SUBJECT DATE)',
|
||||
// struct: true
|
||||
@ -30,23 +30,23 @@ imap.once("ready", function () {
|
||||
f.on("message", function (msg, seqno) {
|
||||
// console.log("Message #%d", seqno);
|
||||
// var prefix = "(#" + seqno + ") ";
|
||||
msg.on("body", function (stream, info) {
|
||||
simpleParser(stream, async (err, parsed) => {
|
||||
// find box id;
|
||||
console.log(parsed)
|
||||
const boxId = 1;
|
||||
// saveMessage(parsed, boxId);
|
||||
console.log(parsed.subject);
|
||||
fs.writeFileSync("./test.txt", JSON.stringify(parsed));
|
||||
});
|
||||
// console.log(prefix + 'Body');
|
||||
// stream.pipe(fs.createWriteStream('msg-' + seqno + '-body.txt'));
|
||||
});
|
||||
// msg.on("body", function (stream, info) {
|
||||
// simpleParser(stream, async (err, parsed) => {
|
||||
// // find box id;
|
||||
// // console.log(parsed)
|
||||
// const boxId = 1;
|
||||
// saveMessage(parsed, boxId);
|
||||
// // console.log(parsed.subject);
|
||||
// // fs.writeFileSync("./test.txt", JSON.stringify(parsed));
|
||||
// });
|
||||
// // console.log(prefix + 'Body');
|
||||
// // stream.pipe(fs.createWriteStream('msg-' + seqno + '-body.txt'));
|
||||
// });
|
||||
msg.once('attributes', attrs => {
|
||||
// todo find boxId
|
||||
const boxId = 1;
|
||||
console.log(attrs)
|
||||
// saveMessage(attrs, boxId, imap);
|
||||
// console.log(attrs)
|
||||
saveMessage(attrs, boxId, imap);
|
||||
});
|
||||
});
|
||||
|
||||
@ -58,7 +58,7 @@ imap.once("ready", function () {
|
||||
});
|
||||
f.once("end", function () {
|
||||
console.log("Done fetching all messages!");
|
||||
imap.end();
|
||||
// imap.end();
|
||||
});
|
||||
// });
|
||||
return;
|
||||
@ -135,66 +135,6 @@ imap.once("end", function () {
|
||||
|
||||
imap.connect();
|
||||
|
||||
// const getEmails = () => {
|
||||
// imap.once('ready', () => {
|
||||
// imap.openBox('INBOX', false, () => {
|
||||
// imap.search(['UNSEEN'], (err, results) => {
|
||||
// const f = imap.fetch(results, {bodies: ''});
|
||||
// f.on('message', msg => {
|
||||
// msg.on('body', stream => {
|
||||
// simpleParser(stream, async (err, parsed) => {
|
||||
// // const {from, subject, textAsHtml, text} = parsed;
|
||||
// // console.log(parsed.from.value);
|
||||
// // console.log(parsed.subject);
|
||||
// // console.log(parsed.date)
|
||||
// // console.log(parsed.replyTo.value);
|
||||
// // console.log(parsed.messageId);
|
||||
// // console.log(parsed.html);
|
||||
// // console.log(parsed.text);
|
||||
// // console.log(parsed.textAsHtml);
|
||||
|
||||
// // 'x-emsg-mtaselection' => 'prod_5_emailing.carrefour.fr',
|
||||
// // 'message-id' => '<emsg.6584.7d09.15dd1ec64c1@ukmme02.em.unica.net>',
|
||||
// // 'feedback-id' => 'emailing.carrefour.fr:10070-6584:emsg-x',
|
||||
// // 'list' => { unsubscribe: [Object] },
|
||||
// // 'mime-version' => '1.0',
|
||||
// // 'content-type' => { value: 'text/html', params: [Object] },
|
||||
// // 'content-transfer-encoding' => 'quoted-printable'
|
||||
|
||||
// });
|
||||
// });
|
||||
// msg.once('attributes', attrs => {
|
||||
// const {uid} = attrs;
|
||||
// console.log(uid)
|
||||
// // imap.addFlags(uid, ['\\Seen'], () => {
|
||||
// // // Mark the email as read after reading it
|
||||
// // console.log('Marked as read!');
|
||||
// // });
|
||||
// });
|
||||
// });
|
||||
// f.once('error', ex => {
|
||||
// return Promise.reject(ex);
|
||||
// });
|
||||
// f.once('end', () => {
|
||||
// console.log('Done fetching all messages!');
|
||||
// imap.end();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// imap.once('error', err => {
|
||||
// console.log(err);
|
||||
// });
|
||||
|
||||
// imap.once('end', () => {
|
||||
// console.log('Connection ended');
|
||||
// });
|
||||
|
||||
// imap.connect();
|
||||
// };
|
||||
|
||||
// getEmails();
|
||||
|
||||
function isValidEmail(email) {
|
||||
// todo
|
||||
|
@ -8,9 +8,17 @@ const {
|
||||
saveHeader_fields,
|
||||
saveAddress_fields,
|
||||
registerBodypart,
|
||||
saveBodypart
|
||||
saveBodypart,
|
||||
} = require("../sql/saveMessage");
|
||||
const { getFieldId } = require("../sql/mail");
|
||||
|
||||
const {
|
||||
createRoom,
|
||||
registerMessageInRoom,
|
||||
createThread,
|
||||
registerMessageInThread,
|
||||
isRoomGroup
|
||||
} = require("../sql/saveMessageApp");
|
||||
const { getFieldId, findRoomByOwner } = require("../sql/mail");
|
||||
|
||||
function saveMessage(attrs, mailboxId, imap) {
|
||||
const envelope = attrs.envelope;
|
||||
@ -95,34 +103,77 @@ function saveMessage(attrs, mailboxId, imap) {
|
||||
}
|
||||
});
|
||||
|
||||
// todo check for different provider
|
||||
if (envelope?.inReplyTo) {
|
||||
`SELECT app_room_messages.room, app_room_messages.thread FROM app_room_messages INNER JOIN messages WHERE messages.messageID = '${envelope.inReplyTo}' AND app_room_messages.message = messages.id`;
|
||||
// parent message is in a thread, so register this message only in a thread
|
||||
if (thread) {
|
||||
`INSERT IGNORE INTO app_room_messages (thread, message) VALUES('${thread}', '${messageId}')`;
|
||||
// increment not read counter and lastUpdate is not read (both)
|
||||
} else if (room) {
|
||||
|
||||
if (!isGroup) {
|
||||
// check if create thread
|
||||
} else {
|
||||
// check if create new group and delete thread
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
/**
|
||||
* if reply to then add to same group as previous and update type if necessary
|
||||
* else add to sender group
|
||||
*
|
||||
*/
|
||||
|
||||
// todo check for different provider name of inreplyto
|
||||
registerMessageInApp()
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function haveSameReceivers() {
|
||||
// take cc and to
|
||||
}
|
||||
|
||||
function registerMessageInApp() {
|
||||
if (envelope.inReplyTo) {
|
||||
registerReplyMessage();
|
||||
} else {
|
||||
findRoomByOwner(ownerId).then((res) => {
|
||||
if (res.length == 0) {
|
||||
registerMessageInRoom(messageId, res[0].id);
|
||||
} else {
|
||||
createRoom(envelope.subject, ownerId, envelope.flags.includes["seen"]).then((roomId) => {
|
||||
registerMessageInRoom(messageId, roomId);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function registerReplyMessage() {
|
||||
findSpaceFromMessage(messageId).then((spaces) => {
|
||||
if(spaces.length == 0) { // no space, so is a transfer
|
||||
// todo test if members of transferred message are included
|
||||
} else if (spaces[0].room) { // message in room
|
||||
isRoomGroup(spaces[0].room_id).then((isGroup) => {
|
||||
if (isGroup) {
|
||||
if (hasSameMembersAsParent(messageId)) {
|
||||
registerMessageInRoom(messageId, spaces[0].room_id);
|
||||
} else {
|
||||
// group and not the same member as the reply
|
||||
// some recipient has been removed create a thread
|
||||
const notSeen = 0; // todo
|
||||
const isDm = 0; // todo
|
||||
createThread(space[0].room_id, envelope.subject, notSeen, isDm).then((threadId) => {
|
||||
registerMessageInThread(messageId, threadId);
|
||||
});
|
||||
}
|
||||
} else { // reply from channel
|
||||
// todo
|
||||
// if (messageInRoom == 1) { // was new channel transform to group
|
||||
// // register new message in group
|
||||
// } else if (sender == owner) { // correction from the original sender
|
||||
// // leave in the same channel
|
||||
// } else { // user response to announcement
|
||||
// // create new thread
|
||||
// }
|
||||
}
|
||||
});
|
||||
} else if (spaces[0].thread) { // message in thread
|
||||
// todo
|
||||
// if (hasSameMembersAsParent(messageId)) {
|
||||
// // register new message in thread
|
||||
// // possibly convert to room only if parent is channel
|
||||
// } else {
|
||||
// // create sub thread
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
// `SELECT app_room_messages.room, app_room_messages.thread FROM app_room_messages INNER JOIN messages WHERE messages.messageID = '${envelope.inReplyTo}' AND app_room_messages.message = messages.id`;
|
||||
|
||||
}
|
||||
|
||||
function findTextPart(struct) {
|
||||
for (var i = 0, len = struct.length, r; i < len; ++i) {
|
||||
if (Array.isArray(struct[i])) {
|
||||
|
@ -23,7 +23,7 @@ router.get("/{mailboxId}/messages", (req, res) => {
|
||||
// todo check token
|
||||
// todo use offset
|
||||
const query = ``;
|
||||
SELECT header_fields.value FROM header_fields INNER JOIN field_names WHERE header_fields.field = field_names.id AND (field_names.name = "subject" OR field_names.name = "date"); ORDER BY messages.idate
|
||||
// SELECT header_fields.value FROM header_fields INNER JOIN field_names WHERE header_fields.field = field_names.id AND (field_names.name = "subject" OR field_names.name = "date"); ORDER BY messages.idate
|
||||
// number of message missed in the room
|
||||
});
|
||||
|
||||
|
57
back/sql/mail.js
Normal file
57
back/sql/mail.js
Normal file
@ -0,0 +1,57 @@
|
||||
const bdd = require("./bdd.js").bdd;
|
||||
const DEBUG = require("../utils/debug").DEBUG;
|
||||
|
||||
function isValidEmail(email) {
|
||||
// todo
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function getAddresseId(email, name) {
|
||||
const localpart = email.split("@")[0];
|
||||
const domain = email.split("@")[1];
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!isValidEmail(email)) reject("Not a valid email");
|
||||
const query = `INSERT INTO address (address_name, localpart, domain, email) VALUES ('${name}', '${localpart}', '${domain}', '${email}')
|
||||
ON DUPLICATE KEY UPDATE email = '${email}', id = LAST_INSERT_ID(id)`;
|
||||
bdd.query(query, (err, results, fields) => {
|
||||
if (err) reject(err);
|
||||
resolve(results.insertId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getMailboxId(email) {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve(0)
|
||||
});
|
||||
// todo
|
||||
}
|
||||
|
||||
function getFieldId(field) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const query = `INSERT INTO field_name (field_name) VALUES ('${field}') ON DUPLICATE KEY UPDATE field_id=LAST_INSERT_ID(field_id);
|
||||
`;
|
||||
bdd.query(query, (err, results, fields) => {
|
||||
if (err) reject(err);
|
||||
resolve(results.insertId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function findRoomByOwner(ownerId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const query = `SELECT room_id FROM app_room WHERE owner_id = '${ownerId}'`;
|
||||
bdd.query(query, (err, results, fields) => {
|
||||
if (err) reject(err);
|
||||
resolve(results);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getAddresseId,
|
||||
getMailboxId,
|
||||
getFieldId,
|
||||
findRoomByOwner,
|
||||
};
|
@ -2,9 +2,8 @@ const bdd = require("./bdd.js").bdd;
|
||||
const DEBUG = require("../utils/debug").DEBUG;
|
||||
|
||||
function registerMessage(timestamp, rfc822size, messageId) {
|
||||
// todo messageId
|
||||
return new Promise((resolve, reject) => {
|
||||
const query = `INSERT INTO messages (idate, rfc822size) VALUES (${timestamp}, '${rfc822size}')`;
|
||||
const query = `INSERT INTO message (idate, messageID, rfc822size) VALUES (${timestamp}, '${messageId}', '${rfc822size}')`;
|
||||
bdd.query(query, (err, results, fields) => {
|
||||
if (err) reject(err);
|
||||
resolve(results.insertId);
|
||||
@ -13,14 +12,14 @@ function registerMessage(timestamp, rfc822size, messageId) {
|
||||
}
|
||||
|
||||
function registerMailbox_message(mailboxId, uid, messageId, modseq, seen, deleted) {
|
||||
const query = `INSERT IGNORE INTO mailbox_messages (mailbox, uid, message, modseq, seen, deleted) VALUES ('${mailboxId}', '${uid}', '${messageId}', '${modseq}', '${seen}', '${deleted}')`;
|
||||
const query = `INSERT IGNORE INTO mailbox_message (mailbox_id, uid, message_id, modseq, seen, deleted) VALUES ('${mailboxId}', '${uid}', '${messageId}', '${modseq}', '${seen}', '${deleted}')`;
|
||||
bdd.query(query, (err, results, fields) => {
|
||||
if (err) DEBUG.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
function registerBodypart(messageId, part, bodypartId, bytes, nbLines) {
|
||||
const query = `INSERT IGNORE INTO part_numbers (message, part, bodypart, bytes, nbLines) VALUES ('${messageId}', '${part}', '${bodypartId}', '${bytes}', '${nbLines}')`;
|
||||
const query = `INSERT IGNORE INTO part_number (message_id, part, bodypart, bytes, nbLines) VALUES ('${messageId}', '${part}', '${bodypartId}', '${bytes}', '${nbLines}')`;
|
||||
bdd.query(query, (err, results, fields) => {
|
||||
if (err) DEBUG.log(err);
|
||||
});
|
||||
@ -29,7 +28,7 @@ function registerBodypart(messageId, part, bodypartId, bytes, nbLines) {
|
||||
|
||||
function saveBodypart(bytes, hash, text, data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const query = `INSERT IGNORE INTO bodyparts (bytes, hash, text, data) VALUES ('${bytes}', '${hash}', '${text}', '${data}')`;
|
||||
const query = `INSERT IGNORE INTO bodypart (bytes, hash, text, data) VALUES ('${bytes}', '${hash}', '${text}', '${data}')`;
|
||||
bdd.query(query, (err, results, fields) => {
|
||||
if (err) reject(err);
|
||||
resolve(results.insertId);
|
||||
@ -38,14 +37,14 @@ function saveBodypart(bytes, hash, text, data) {
|
||||
}
|
||||
|
||||
function saveHeader_fields(message, part, position, field, value) {
|
||||
const query = `INSERT IGNORE INTO header_fields (message, part, position, field, value) VALUES ('${message}', '${part}', '${position}', '${field}', '${value}')`;
|
||||
const query = `INSERT IGNORE INTO header_field (message_id, part, position, field_id, value) VALUES ('${message}', '${part}', '${position}', '${field}', '${value}')`;
|
||||
bdd.query(query, (err, results, fields) => {
|
||||
if (err) throw err;
|
||||
});
|
||||
}
|
||||
|
||||
function saveAddress_fields(message, part, position, field, number, address) {
|
||||
const query = `INSERT IGNORE INTO address_fields (message, part, position, field, number, address) VALUES ('${message}', '${part}', '${position}', '${field}', '${number}', '${address}')`;
|
||||
const query = `INSERT IGNORE INTO address_field (message_id , part, position, field_id, number, address_id) VALUES ('${message}', '${part}', '${position}', '${field}', '${number}', '${address}')`;
|
||||
bdd.query(query, (err, results, fields) => {
|
||||
if (err) throw err;
|
||||
});
|
||||
@ -57,5 +56,5 @@ module.exports = {
|
||||
saveHeader_fields,
|
||||
saveAddress_fields,
|
||||
registerBodypart,
|
||||
saveBodypart
|
||||
saveBodypart,
|
||||
}
|
92
back/sql/saveMessageApp.js
Normal file
92
back/sql/saveMessageApp.js
Normal file
@ -0,0 +1,92 @@
|
||||
const bdd = require("./bdd.js").bdd;
|
||||
const DEBUG = require("../utils/debug").DEBUG;
|
||||
|
||||
function createRoom(roomName, ownerId, notSeen) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const query = `INSERT INTO app_room (room_name, owner_id, notSeen) VALUES ('${roomName}', '${ownerId}', '${notSeen}')`;
|
||||
bdd.query(query, (err, results, fields) => {
|
||||
if (err) reject(err);
|
||||
resolve(results.insertId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function registerMessageInRoom(messageId, roomId, isSeen) {
|
||||
const query = `INSERT INTO app_room_message (message_id, room_id) VALUES ('${messageId}', '${roomId}')`;
|
||||
bdd.query(query, (err, results, fields) => {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
updateLastUpdateRoom(roomId);
|
||||
|
||||
if (!isSeen) {
|
||||
incrementNotSeenRoom(roomId);
|
||||
}
|
||||
}
|
||||
|
||||
function updateLastUpdateRoom(roomId) {
|
||||
// todo
|
||||
}
|
||||
|
||||
function incrementNotSeenRoom(roomId) {
|
||||
// todo
|
||||
}
|
||||
|
||||
function createThread(roomId, threadName, notSeen, isDm) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const query = `INSERT INTO app_thread
|
||||
(room_id, thread_name, notSeen, isDm)
|
||||
VALUES (
|
||||
'${roomId}',
|
||||
'${threadName}',
|
||||
'${notSeen}',
|
||||
'${isDm}',
|
||||
)`;
|
||||
bdd.query(query, (err, results, fields) => {
|
||||
if (err) reject(err);
|
||||
resolve(results.insertId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function registerMessageInThread(messageId, threadId, isSeen) {
|
||||
// todo check if it is still a thread or should be a room
|
||||
const query = `INSERT IGNORE INTO app_room_messages
|
||||
(message_id, thread_id) VALUES ('${messageId}', '${threadId}')`;
|
||||
bdd.query(query, (err, results, fields) => {
|
||||
if (err) throw err;
|
||||
});
|
||||
updateLastUpdateThread(threadId);
|
||||
|
||||
if (!isSeen) {
|
||||
incrementNotSeenThread(threadId);
|
||||
}
|
||||
}
|
||||
|
||||
function updateLastUpdateRoom(threadId) {
|
||||
// todo
|
||||
// check for parent
|
||||
}
|
||||
|
||||
function incrementNotSeenThread(threadId) {
|
||||
// todo
|
||||
// also increment parent room
|
||||
}
|
||||
|
||||
function isRoomGroup(roomId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const query = `SELECT isGroup FROM app_room WHERE room_id = '${roomId}'`;
|
||||
bdd.query(query, (err, results, fields) => {
|
||||
if (err) reject(err);
|
||||
resolve(results[0].isGroup);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createRoom,
|
||||
registerMessageInRoom,
|
||||
createThread,
|
||||
registerMessageInThread,
|
||||
isRoomGroup
|
||||
};
|
175
back/sql/structureV2.sql
Normal file
175
back/sql/structureV2.sql
Normal file
@ -0,0 +1,175 @@
|
||||
/**
|
||||
* Mail storage
|
||||
*/
|
||||
|
||||
-- 1
|
||||
CREATE TABLE address (
|
||||
address_id INT AUTO_INCREMENT,
|
||||
address_name TEXT,
|
||||
localpart TEXT NOT NULL,
|
||||
domain TEXT NOT NULL,
|
||||
email TEXT NOT NULL,
|
||||
PRIMARY KEY (address_id),
|
||||
UNIQUE KEY (email)
|
||||
);
|
||||
|
||||
-- 3
|
||||
CREATE TABLE mailbox (
|
||||
mailbox_id INT AUTO_INCREMENT,
|
||||
account_id INT NOT NULL,
|
||||
mailbox_name TEXT NOT NULL,
|
||||
uidnext INT NOT NULL DEFAULT 1,
|
||||
nextmodseq BIGINT NOT NULL DEFAULT 1,
|
||||
first_recent INT NOT NULL DEFAULT 1,
|
||||
uidvalidity INT NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (mailbox_id),
|
||||
UNIQUE KEY (mailbox_name),
|
||||
FOREIGN KEY (account_id) REFERENCES app_account(account_id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- 4
|
||||
CREATE TABLE message (
|
||||
message_id INT AUTO_INCREMENT,
|
||||
messageID TEXT NOT NULL,
|
||||
idate TIMESTAMP NOT NULL,
|
||||
rfc822size INT NOT NULL,
|
||||
PRIMARY KEY (message_id),
|
||||
UNIQUE KEY (messageID)
|
||||
);
|
||||
|
||||
-- 5
|
||||
-- if mailbox_message deleted message is not deleted
|
||||
CREATE TABLE mailbox_message (
|
||||
mailbox_id INT NOT NULL,
|
||||
uid INT,
|
||||
message_id INT,
|
||||
modseq BIGINT NOT NULL,
|
||||
seen BIT(1) NOT NULL DEFAULT 0,
|
||||
deleted BIT(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (uid, message_id),
|
||||
FOREIGN KEY (mailbox_id) REFERENCES mailbox(mailbox_id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (message_id) REFERENCES message(message_id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- 6
|
||||
CREATE TABLE part_number (
|
||||
message_id INT NOT NULL,
|
||||
part VARCHAR(128) NOT NULL,
|
||||
bodypart_id INT NOT NULL,
|
||||
bytes INT,
|
||||
nb_lines INT,
|
||||
PRIMARY KEY (message_id, part),
|
||||
FOREIGN KEY (message_id) REFERENCES message(message_id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (bodypart_id) REFERENCES bodypart(bodypart_id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- 7
|
||||
CREATE TABLE bodypart (
|
||||
bodypart_id INT AUTO_INCREMENT,
|
||||
bytes INT NOT NULL,
|
||||
hash TEXT NOT NULL,
|
||||
text TEXT,
|
||||
data BINARY,
|
||||
PRIMARY KEY (bodypart_id)
|
||||
);
|
||||
|
||||
-- 8
|
||||
CREATE TABLE field_name (
|
||||
field_id INT AUTO_INCREMENT,
|
||||
field_name VARCHAR (255),
|
||||
PRIMARY KEY (field_id),
|
||||
UNIQUE KEY (field_name)
|
||||
);
|
||||
|
||||
-- 9
|
||||
CREATE TABLE header_field (
|
||||
message_id INT NOT NULL,
|
||||
part VARCHAR(128) NOT NULL,
|
||||
position INT NOT NULL,
|
||||
field_id INT NOT NULL,
|
||||
value TEXT NOT NULL,
|
||||
UNIQUE KEY (message_id, part, position, field_id),
|
||||
FOREIGN KEY (message_id, part) REFERENCES part_number(message_id, part) ON DELETE CASCADE,
|
||||
FOREIGN KEY (field_id) REFERENCES field_name(field_id)
|
||||
);
|
||||
|
||||
-- 10
|
||||
CREATE TABLE address_field (
|
||||
message_id INT NOT NULL,
|
||||
part VARCHAR(128) NOT NULL,
|
||||
position INT NOT NULL,
|
||||
field_id INT NOT NULL,
|
||||
number INT,
|
||||
address_id INT NOT NULL,
|
||||
FOREIGN KEY (message_id, part) REFERENCES part_number(message_id, part) ON DELETE CASCADE,
|
||||
FOREIGN KEY (field_id) REFERENCES field_name(field_id),
|
||||
FOREIGN KEY (address_id) REFERENCES address(address_id)
|
||||
);
|
||||
|
||||
/**
|
||||
* App table
|
||||
*/
|
||||
|
||||
-- 2
|
||||
CREATE TABLE app_account (
|
||||
account_id INT AUTO_INCREMENT,
|
||||
user_id INT NOT NULL,
|
||||
account_pwd BINARY(22),
|
||||
xoauth VARCHAR(116),
|
||||
xoauth2 VARCHAR(116),
|
||||
host VARCHAR(255) NOT NULL DEFAULT 'localhost',
|
||||
port INT(5) NOT NULL DEFAULT 143,
|
||||
tls BIT(1) NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (account_id),
|
||||
FOREIGN KEY (user_id) REFERENCES address(address_id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- 11
|
||||
CREATE TABLE app_room (
|
||||
room_id INT AUTO_INCREMENT,
|
||||
room_name VARCHAR(30) NOT NULL,
|
||||
owner_id INT NOT NULL,
|
||||
isGroup BIT(1) NOT NULL DEFAULT 0,
|
||||
notSeen INT NOT NULL DEFAULT 0,
|
||||
lastUpdate TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(),
|
||||
PRIMARY KEY (room_id),
|
||||
FOREIGN KEY (owner_id) REFERENCES address(address_id)
|
||||
);
|
||||
|
||||
-- 12
|
||||
CREATE TABLE app_thread (
|
||||
thread_id INT AUTO_INCREMENT,
|
||||
room_id INT NOT NULL,
|
||||
thread_name VARCHAR(30) NOT NULL,
|
||||
notSeen INT NOT NULL DEFAULT 0,
|
||||
lastUpdate TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(),
|
||||
isDm BIT(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (thread_id),
|
||||
FOREIGN KEY (room_id) REFERENCES app_room(room_id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- 13
|
||||
CREATE TABLE app_room_message (
|
||||
message_id INT NOT NULL,
|
||||
room_id INT,
|
||||
thread_id INT,
|
||||
FOREIGN KEY (message_id) REFERENCES message(message_id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (room_id) REFERENCES app_room(room_id) ON DELETE SET NULL,
|
||||
FOREIGN KEY (thread_id) REFERENCES app_thread(thread_id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
-- 14
|
||||
CREATE TABLE app_room_member (
|
||||
room_id INT NOT NULL,
|
||||
member_id INT NOT NULL,
|
||||
FOREIGN KEY (room_id) REFERENCES app_room(room_id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (member_id) REFERENCES address(address_id)
|
||||
);
|
||||
|
||||
-- 14
|
||||
CREATE TABLE app_thread_member (
|
||||
thread_id INT NOT NULL,
|
||||
member_id INT NOT NULL,
|
||||
FOREIGN KEY (thread_id) REFERENCES app_thread(thread_id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (member_id) REFERENCES address(address_id)
|
||||
);
|
34
doc.js
Normal file
34
doc.js
Normal file
@ -0,0 +1,34 @@
|
||||
if (isReply) {
|
||||
if (inThread) {
|
||||
if (hasSameMembers) {
|
||||
// register new message in thread
|
||||
// possibly convert to room only if parent is channel
|
||||
} else {
|
||||
// create sub thread
|
||||
}
|
||||
} else if (inRoom) {
|
||||
if (isGroup) {
|
||||
if (hasSameMembers) {
|
||||
// register new message in group
|
||||
} else {
|
||||
// create thread
|
||||
}
|
||||
} else { // reply from channel
|
||||
if (messageInRoom == 1) { // was new channel transform to group
|
||||
// register new message in group
|
||||
} else if (sender == owner) { // correction from the original sender
|
||||
// leave in the same channel
|
||||
} else { // user response to announcement
|
||||
// create new thread
|
||||
}
|
||||
}
|
||||
} else { // transfer
|
||||
// todo test if members of transferred message are included
|
||||
}
|
||||
} else {
|
||||
if (inRoomByOwner) {
|
||||
// register message in room
|
||||
} else {
|
||||
// create room
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user