Skip to main content

Module message

Module message 

Source
Expand description

Message table rows, query helpers, and body parsing.

§Iterating over Message Data

Use Message::stream() to iterate over the default message query.

§Example

use imessage_database::{
    error::table::TableError,
    tables::{
        messages::Message,
        table::{get_connection, Table},
    },
    util::dirs::default_db_path,
};

#[derive(Debug)]
struct ProgramError(TableError);

impl From<TableError> for ProgramError {
    fn from(err: TableError) -> Self {
        Self(err)
    }
}

// Get the default database path and connect to it
let db_path = default_db_path();
let conn = get_connection(&db_path).unwrap();

Message::stream(&conn, |message_result| {
   match message_result {
       Ok(message) => println!("Message: {:#?}", message),
       Err(e) => eprintln!("Error: {:?}", e),
   }
   Ok::<(), ProgramError>(())
}).unwrap();

§Making Custom Message Queries

Message includes a few fields that are derived by the default query and are not direct message table columns:

§Sample Queries

Custom queries must include those derived columns:

SELECT
    *,
    c.chat_id,
    (SELECT COUNT(*) FROM message_attachment_join a WHERE m.ROWID = a.message_id) as num_attachments,
    d.chat_id as deleted_from,
    (SELECT COUNT(*) FROM message m2 WHERE m2.thread_originator_guid = m.guid) as num_replies
FROM
    message as m
LEFT JOIN chat_message_join as c ON m.ROWID = c.message_id
LEFT JOIN chat_recoverable_message_join as d ON m.ROWID = d.message_id
ORDER BY
    m.date;

If a source database does not include recoverable-message or reply columns, synthesize the missing values:

SELECT
    *,
    c.chat_id,
    (SELECT COUNT(*) FROM message_attachment_join a WHERE m.ROWID = a.message_id) as num_attachments,
    NULL as deleted_from,
    0 as num_replies
FROM
    message as m
LEFT JOIN chat_message_join as c ON m.ROWID = c.message_id
ORDER BY
    m.date;

§Custom Query Example

This returns an iterator over messages that have an associated emoji:

use imessage_database::{
    tables::{
        messages::Message,
        table::{get_connection, Table},
    },
    util::dirs::default_db_path
};

let db_path = default_db_path();
let db = get_connection(&db_path).unwrap();

let mut statement = db.prepare_cached("
SELECT
    *,
    c.chat_id,
    (SELECT COUNT(*) FROM message_attachment_join a WHERE m.ROWID = a.message_id) as num_attachments,
    d.chat_id as deleted_from,
    (SELECT COUNT(*) FROM message m2 WHERE m2.thread_originator_guid = m.guid) as num_replies
FROM
    message as m
LEFT JOIN chat_message_join as c ON m.ROWID = c.message_id
LEFT JOIN chat_recoverable_message_join as d ON m.ROWID = d.message_id
WHERE m.associated_message_emoji IS NOT NULL
ORDER BY
    m.date;
").unwrap();

for message in Message::rows(&mut statement, []).unwrap() {
    println!("{:#?}", message);
}

Structs§

Message
Row from the message table, plus body/edit metadata populated by parse_body.
ParsedBody
Body data returned by Message::parse_body.