Add an API to set and retrieve chat messages "app data". This allows clients to store resilient data for each messages

This commit is contained in:
Guillaume BIENKOWSKI 2014-06-02 14:05:30 +02:00
parent 450489e25e
commit a29a93cd76
4 changed files with 85 additions and 10 deletions

View file

@ -668,6 +668,36 @@ void linphone_chat_message_set_external_body_url(LinphoneChatMessage* message,co
message->external_body_url=url?ms_strdup(url):NULL;
}
/**
* Linphone message has an app-specific field that can store a text. The application might want
* to use it for keeping data over restarts, like thumbnail image path.
* @param message #LinphoneChatMessage
* @return the application-specific data or NULL if none has been stored.
*/
const char* linphone_chat_message_get_appdata(const LinphoneChatMessage* message){
return message->appdata;
}
/**
* Linphone message has an app-specific field that can store a text. The application might want
* to use it for keeping data over restarts, like thumbnail image path.
*
* Invoking this function will attempt to update the message storage to reflect the changeif it is
* enabled.
*
* @param message #LinphoneChatMessage
* @param data the data to store into the message
*/
void linphone_chat_message_set_appdata(LinphoneChatMessage* message, const char* data){
if( message->appdata ){
ms_free(message->appdata);
}
message->appdata = data? ms_strdup(data) : NULL;
linphone_chat_message_store_appdata(message);
}
/**
* Set origin of the message
*@param message #LinphoneChatMessage obj
@ -805,6 +835,7 @@ LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* msg)
};*/
LinphoneChatMessage* new_message = linphone_chat_room_create_message(msg->chat_room,msg->message);
if (msg->external_body_url) new_message->external_body_url=ms_strdup(msg->external_body_url);
if (msg->appdata) new_message->appdata = ms_strdup(msg->appdata);
new_message->cb=msg->cb;
new_message->cb_ud=msg->cb_ud;
new_message->message_userdata=msg->message_userdata;
@ -831,6 +862,7 @@ static void _linphone_chat_message_destroy(LinphoneChatMessage* msg) {
if (msg->op) sal_op_release(msg->op);
if (msg->message) ms_free(msg->message);
if (msg->external_body_url) ms_free(msg->external_body_url);
if (msg->appdata) ms_free(msg->appdata);
if (msg->from) linphone_address_destroy(msg->from);
if (msg->to) linphone_address_destroy(msg->to);
if (msg->custom_headers) sal_custom_header_free(msg->custom_headers);

View file

@ -1130,7 +1130,9 @@ LINPHONE_PUBLIC void linphone_chat_message_set_to(LinphoneChatMessage* message,
LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_to(const LinphoneChatMessage* message);
LINPHONE_PUBLIC const char* linphone_chat_message_get_external_body_url(const LinphoneChatMessage* message);
LINPHONE_PUBLIC void linphone_chat_message_set_external_body_url(LinphoneChatMessage* message,const char* url);
LINPHONE_PUBLIC const char * linphone_chat_message_get_text(const LinphoneChatMessage* message);
LINPHONE_PUBLIC const char* linphone_chat_message_get_appdata(const LinphoneChatMessage* message);
LINPHONE_PUBLIC void linphone_chat_message_set_appdata(LinphoneChatMessage* message, const char* data);
LINPHONE_PUBLIC const char* linphone_chat_message_get_text(const LinphoneChatMessage* message);
LINPHONE_PUBLIC time_t linphone_chat_message_get_time(const LinphoneChatMessage* message);
LINPHONE_PUBLIC void* linphone_chat_message_get_user_data(const LinphoneChatMessage* message);
LINPHONE_PUBLIC void linphone_chat_message_set_user_data(LinphoneChatMessage* message,void*);
@ -1622,7 +1624,7 @@ LINPHONE_PUBLIC bool_t linphone_core_payload_type_is_vbr(LinphoneCore *lc, const
* @param[in] lc the #LinphoneCore object
* @param[in] pt the #PayloadType to modify.
* @param[in] bitrate the IP bitrate in kbit/s.
* @ingroup media_parameters
* @ingroup media_parameters
**/
LINPHONE_PUBLIC void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, PayloadType *pt, int bitrate);
@ -1631,7 +1633,7 @@ LINPHONE_PUBLIC void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, Pa
* @param[in] lc the #LinphoneCore object
* @param[in] pt the #PayloadType to modify.
* @return bitrate the IP bitrate in kbit/s, or -1 if an error occured.
* @ingroup media_parameters
* @ingroup media_parameters
**/
LINPHONE_PUBLIC int linphone_core_get_payload_type_bitrate(LinphoneCore *lc, const PayloadType *pt);

View file

@ -37,6 +37,20 @@ static inline LinphoneChatMessage* get_transient_message(LinphoneChatRoom* cr, u
return NULL;
}
/* DB layout:
* | 0 | storage_id
* | 1 | localContact
* | 2 | remoteContact
* | 3 | direction flag
* | 4 | message
* | 5 | time (unused now, used to be string-based timestamp)
* | 6 | read flag
* | 7 | status
* | 8 | external body url
* | 9 | utc timestamp
* | 10 | app data text
*/
static void create_chat_message(char **argv, void *data){
LinphoneChatRoom *cr = (LinphoneChatRoom *)data;
LinphoneAddress *from;
@ -67,7 +81,8 @@ static void create_chat_message(char **argv, void *data){
new_message->is_read=atoi(argv[6]);
new_message->state=atoi(argv[7]);
new_message->storage_id=storage_id;
new_message->external_body_url=argv[8]?ms_strdup(argv[8]):NULL;
new_message->external_body_url= argv[8] ? ms_strdup(argv[8]) : NULL;
new_message->appdata = argv[10]? ms_strdup(argv[10]) : NULL;
}
cr->messages_hist=ms_list_prepend(cr->messages_hist,new_message);
}
@ -95,7 +110,7 @@ void linphone_sql_request_message(sqlite3 *db,const char *stmt,LinphoneChatRoom
}
}
void linphone_sql_request(sqlite3* db,const char *stmt){
int linphone_sql_request(sqlite3* db,const char *stmt){
char* errmsg=NULL;
int ret;
ret=sqlite3_exec(db,stmt,NULL,NULL,&errmsg);
@ -103,6 +118,7 @@ void linphone_sql_request(sqlite3* db,const char *stmt){
ms_error("linphone_sql_request: error sqlite3_exec(): %s.\n", errmsg);
sqlite3_free(errmsg);
}
return ret;
}
// Process the request to fetch all chat contacts
@ -123,7 +139,7 @@ unsigned int linphone_chat_message_store(LinphoneChatMessage *msg){
if (lc->db){
char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(msg->chat_room));
char *local_contact=linphone_address_as_string_uri_only(linphone_chat_message_get_local_address(msg));
char *buf=sqlite3_mprintf("INSERT INTO history VALUES(NULL,%Q,%Q,%i,%Q,%Q,%i,%i,%Q,%i);",
char *buf=sqlite3_mprintf("INSERT INTO history VALUES(NULL,%Q,%Q,%i,%Q,%Q,%i,%i,%Q,%i,%Q);",
local_contact,
peer,
msg->dir,
@ -132,7 +148,8 @@ unsigned int linphone_chat_message_store(LinphoneChatMessage *msg){
msg->is_read,
msg->state,
msg->external_body_url,
msg->time);
msg->time,
msg->appdata);
linphone_sql_request(lc->db,buf);
sqlite3_free(buf);
ms_free(local_contact);
@ -159,6 +176,16 @@ void linphone_chat_message_store_state(LinphoneChatMessage *msg){
}
}
void linphone_chat_message_store_appdata(LinphoneChatMessage* msg){
LinphoneCore *lc=msg->chat_room->lc;
if (lc->db){
char *buf=sqlite3_mprintf("UPDATE history SET appdata=%Q WHERE id=%i;",
msg->appdata,msg->storage_id);
linphone_sql_request(lc->db,buf);
sqlite3_free(buf);
}
}
void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){
LinphoneCore *lc=linphone_chat_room_get_lc(cr);
int read=1;
@ -302,11 +329,11 @@ static time_t parse_time_from_db( const char* time ){
}
static int migrate_messages(void* data,int argc, char** argv, char** column_names) {
static int migrate_messages_timestamp(void* data,int argc, char** argv, char** column_names) {
time_t new_time = parse_time_from_db(argv[1]);
if( new_time ){
/* replace 'time' by -1 and set 'utc' to the timestamp */
char *buf = sqlite3_mprintf("UPDATE history SET utc=%i,time='-1' WHERE id=%i", new_time, atoi(argv[0]));
char *buf = sqlite3_mprintf("UPDATE history SET utc=%i,time='-1' WHERE id=%i;", new_time, atoi(argv[0]));
if( buf) {
linphone_sql_request((sqlite3*)data, buf);
sqlite3_free(buf);
@ -324,7 +351,7 @@ static void linphone_migrate_timestamps(sqlite3* db){
linphone_sql_request(db,"BEGIN TRANSACTION");
ret = sqlite3_exec(db,"SELECT id,time,direction FROM history WHERE time != '-1'", migrate_messages, db, &errmsg);
ret = sqlite3_exec(db,"SELECT id,time,direction FROM history WHERE time != '-1';", migrate_messages_timestamp, db, &errmsg);
if( ret != SQLITE_OK ){
ms_warning("Error migrating outgoing messages: %s.\n", errmsg);
sqlite3_free(errmsg);
@ -359,6 +386,15 @@ void linphone_update_table(sqlite3* db) {
// migrate from old text-based timestamps to unix time-based timestamps
linphone_migrate_timestamps(db);
}
// new field for app-specific storage
ret=sqlite3_exec(db,"ALTER TABLE history ADD COLUMN appdata TEXT;",NULL,NULL,&errmsg);
if(ret != SQLITE_OK) {
ms_message("Table already up to date: %s.", errmsg);
sqlite3_free(errmsg);
} else {
ms_debug("Table updated successfully for app-specific data.");
}
}
void linphone_message_storage_init_chat_rooms(LinphoneCore *lc) {
@ -431,6 +467,9 @@ unsigned int linphone_chat_message_store(LinphoneChatMessage *cr){
void linphone_chat_message_store_state(LinphoneChatMessage *cr){
}
void linphone_chat_message_store_appdata(LinphoneChatMessage *msg){
}
void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){
}

View file

@ -144,6 +144,7 @@ struct _LinphoneChatMessage {
LinphoneChatMessageStateChangedCb cb;
void* cb_ud;
void* message_userdata;
char* appdata;
char* external_body_url;
LinphoneAddress *from;
LinphoneAddress *to;
@ -821,6 +822,7 @@ sqlite3 * linphone_message_storage_init();
void linphone_message_storage_init_chat_rooms(LinphoneCore *lc);
#endif
void linphone_chat_message_store_state(LinphoneChatMessage *msg);
void linphone_chat_message_store_appdata(LinphoneChatMessage* msg);
void linphone_core_message_storage_init(LinphoneCore *lc);
void linphone_core_message_storage_close(LinphoneCore *lc);
void linphone_core_message_storage_set_debug(LinphoneCore *lc, bool_t debug);