perleager has asked for the wisdom of the Perl Monks concerning the following question:

Hello all:

I'm trying to make a little message script for my users on my website. It's not exactly a message board but more of a mini e-mail system.

I'm using mysql and DBI for this.

Basically I don't know where to start on creating such a reply system for this lil message script I'm building.

Lets say user "BOB100" messages "MIKEY" saying "Hey Mikey whats up?"

Mikey's homepage would then display a You have a message from Bobby: "Hey Mikey" -read button- / -reply button-

Mikey then hits the reply button and goes to a new page with the message Input form and replys saying "Hey Bob"

Now, on Bobby's homepage it'll say message from Mikey: "Hey Bob" ..............BUT how do I keep the original message from Bob onto the db such as a e-mail reply:

Message from mike : date 11/2/03
Hey Bob

----
Original Message from Bob100 : date 11/1/03
Hey Mikey

And as they keep replying to eachother, the log of all replies continues etc etc...

Basically I'm just stuck on how to set up the mysql DB so I can get this working properly...
I have a mysql db set up as following:
id / touser / createdby / message / date / status 1 mike bob100 heymike 11/2/03 notread

On the homepage to view new messages, the code will be something using a sql statement such as "select * from messages where touser = '$userloggedin'" .... and that will display any new messages for the user.

Is this setup on the right track? I can't seem to implement this reply sequencing option with how I have this db setup, can anyone help or any suggestions?

Thanks,
Anthony

Replies are listed 'Best First'.
Re: Message Reply Sequencing
by Coruscate (Sexton) on Dec 03, 2003 at 06:22 UTC

    I'd probably implement the database something like this:

    CREATE TABLE messages( msg_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, parent_id INT NOT NULL, status VARCHAR(3) NOT NULL, from_who VARCHAR(30) NOT NULL, to_who VARCHAR(30) NOT NULL, sent_when DATETIME NOT NULL, msg_text TEXT NOT NULL ); CREATE TABLE users( user VARCHAR(30) NOT NULL PRIMARY KEY, # etc, etc. );

    Upon an original message (non-replies), you insert the following into .messages. Note the -1 value for parent_id. This is an indication that this message is a parent message, not a reply to anything.

    INSERT INTO messages VALUES( '',-1,'NR','Coruscate','perleager',NOW(),'hello there!' );

    A reply to this message would be inserted as follows. Note the parent_id field. This would be the id number of the message that is being replied to.

    INSERT INTO messages VALUES( '',10932,'NR','perleager','Coruscate',NOW(),'hello back!' );

    To display a message in its "thread-like state" (showing the entire 'conversation'), you simply throw together a method that looks at the current msg_id, then recurses through itself to propagate up the history tree.

    The 'NR' I used is borrowed from another reply to this node, which I assume stands for 'Not Read'. To delete a message with this database setup, you wouldn't be able to actually delete the entry from the database until all sub-messages of that message are removed as well. My solution would be to set the 'status' column to 'DEL' when a user deletes a messages. Your code would then see to not display this message in the inbox, but the data would still be available to add to the archived thread-like state. Add a cron script that rips through the database every so often and actually deletes info from the database by being smart enough to find entire "threads" that have been deleted.

Re: Message Reply Sequencing
by Roger (Parson) on Dec 03, 2003 at 05:35 UTC
    Personally I would design my tables like this -

    Table: Messages
    message_idrecipient_idsender_idmessagedatestatus
    1500501hey mike2003-11-02NR

    Primary key: message_id
    Foreign keys: recipient_id, sender_id


    Table: User
    idnicknamefullname
    500bobBob
    501janeJane

    Primary key: id

    So when user bob logs in, the SQL to check for new/unread messages would be like this -
    SELECT * FROM messages WHERE recipient_id=? AND status='NR'
    After Bob has seen the message (assuming that the message id is saved some where on your web page (hidden field perhaps, or a session variable) -
    UPDATE messages SET status='OK' WHERE message_id = ?
    And when Bob replies a message back to Jane -
    $msg = "original message"; # assume this is from the prev message $reply = $newmsg . "\nOriginal Message\n------------\n" . $msg; # and then just insert the reply into messages table with SQL insert INSERT INTO messages (message_id, recipient_id, sender_id, message, date, status) VALUES (?, ?, ?, ?, ?, 'NR')
    And for the sequencing of message_id's, I normally use a database trigger on INSERT, that queries the table searching for the maximum message_id, add 1, and set as the new message_id. If you don't want to use triggers you could certainly do this easily with SQL and a bit of Perl.

    Ok, what could be tricky is when multiple users are trying to send messages to others at the same time. For that you need to implement proper locking mechanism if you don't use DB triggers, and that's one occation where I think DB triggers are quite useful. And you certainly would need to handle insert exceptions and try again if necessary.

      for the sequencing of message_id's, I normally use a database trigger on INSERT, that queries the table searching for the maximum message_id, add 1, and set as the new message_id

      Oooooorrrr... you could just add an auto_incremented message_id field and let the database handle the incrementing mechanism. :)

        Well, that could be really nice, but I am using Oracle here that doesn't have this feature unfortunately. :-(