diff --git a/coreapi/message_storage.c b/coreapi/message_storage.c index 8a04d1ad2..86887c7b7 100644 --- a/coreapi/message_storage.c +++ b/coreapi/message_storage.c @@ -20,17 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "private.h" #include "linphonecore.h" -#ifdef WIN32 - -static inline char *my_ctime_r(const time_t *t, char *buf){ - strcpy(buf,ctime(t)); - return buf; -} - -#else -#define my_ctime_r ctime_r -#endif - #ifdef MSG_STORAGE_ENABLED #include "sqlite3.h" @@ -157,8 +146,8 @@ void linphone_chat_message_store_state(LinphoneChatMessage *msg){ LinphoneCore *lc=msg->chat_room->lc; if (lc->db){ char *buf=sqlite3_mprintf("UPDATE history SET status=%i WHERE (message = %Q OR url = %Q) AND utc = %i;", - msg->state,msg->message,msg->external_body_url,msg->time); - linphone_sql_request(lc->db,buf); + msg->state,msg->message,msg->external_body_url,msg->time); + linphone_sql_request(lc->db,buf); sqlite3_free(buf); } @@ -381,6 +370,27 @@ void linphone_message_storage_init_chat_rooms(LinphoneCore *lc) { sqlite3_free(buf); } +static void _linphone_message_storage_profile(void*data,const char*statement, sqlite3_uint64 duration){ + ms_warning("SQL statement '%s' took %" PRId64 " microseconds", statement, duration / 1000 ); +} + +static void linphone_message_storage_activate_debug(sqlite3* db, bool_t debug){ + if( debug ){ + sqlite3_profile(db, _linphone_message_storage_profile, NULL ); + } else { + sqlite3_profile(db, NULL, NULL ); + } +} + +void linphone_core_message_storage_set_debug(LinphoneCore *lc, bool_t debug){ + + lc->debug_storage = debug; + + if( lc->db ){ + linphone_message_storage_activate_debug(lc->db, debug); + } +} + void linphone_core_message_storage_init(LinphoneCore *lc){ int ret; const char *errmsg; @@ -394,6 +404,9 @@ void linphone_core_message_storage_init(LinphoneCore *lc){ ms_error("Error in the opening: %s.\n", errmsg); sqlite3_close(db); } + + linphone_message_storage_activate_debug(db, lc->debug_storage); + linphone_create_table(db); linphone_update_table(db); lc->db=db; diff --git a/coreapi/private.h b/coreapi/private.h index d43f6454f..a2fb3d9c2 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -701,6 +701,7 @@ struct _LinphoneCore char *chat_db_file; #ifdef MSG_STORAGE_ENABLED sqlite3 *db; + bool_t debug_storage; #endif #ifdef BUILD_UPNP UpnpContext *upnp; @@ -815,6 +816,7 @@ void linphone_message_storage_init_chat_rooms(LinphoneCore *lc); void linphone_chat_message_store_state(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); void linphone_core_play_named_tone(LinphoneCore *lc, LinphoneToneID id); bool_t linphone_core_tone_indications_enabled(LinphoneCore*lc); diff --git a/tester/Makefile.am b/tester/Makefile.am index 1cda152c7..46ffb12cd 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -26,7 +26,7 @@ liblinphonetester_la_LDFLAGS= -no-undefined liblinphonetester_la_LIBADD= ../coreapi/liblinphone.la $(CUNIT_LIBS) AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/coreapi -AM_CFLAGS = $(STRICT_OPTIONS) -DIN_LINPHONE $(ORTP_CFLAGS) $(MEDIASTREAMER_CFLAGS) $(CUNIT_CFLAGS) $(BELLESIP_CFLAGS) $(LIBXML2_CFLAGS) +AM_CFLAGS = $(STRICT_OPTIONS) -DIN_LINPHONE $(ORTP_CFLAGS) $(MEDIASTREAMER_CFLAGS) $(CUNIT_CFLAGS) $(BELLESIP_CFLAGS) $(LIBXML2_CFLAGS) $(SQLITE3_CFLAGS) if !BUILD_IOS diff --git a/tester/message_tester.c b/tester/message_tester.c index 6aa884616..b5b8934e4 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -1,19 +1,19 @@ /* - liblinphone_tester - liblinphone test suite - Copyright (C) 2013 Belledonne Communications SARL + liblinphone_tester - liblinphone test suite + Copyright (C) 2013 Belledonne Communications SARL - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ @@ -23,6 +23,11 @@ #include "private.h" #include "liblinphone_tester.h" +#ifdef MSG_STORAGE_ENABLED +#include +#endif + + static char* message_external_body_url; void text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from_address, const char *message) { @@ -97,7 +102,7 @@ static void text_message(void) { static void text_message_within_dialog(void) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - + lp_config_set_int(pauline->lc->config,"sip","chat_use_call_dialogs",1); char* to = linphone_address_as_string(marie->identity); @@ -105,7 +110,7 @@ static void text_message_within_dialog(void) { ms_free(to); CU_ASSERT_TRUE(call(marie,pauline)); - + linphone_chat_room_send_message(chat_room,"Bla bla bla bla"); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); @@ -287,7 +292,7 @@ static void text_message_denied(void) { /*pauline doesn't want to be disturbed*/ linphone_core_disable_chat(pauline->lc,LinphoneReasonDoNotDisturb); - + linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,marie->lc); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageNotDelivered,1)); @@ -385,6 +390,89 @@ static void is_composing_notification(void) { linphone_core_manager_destroy(pauline); } +#ifdef MSG_STORAGE_ENABLED + +/* + * Copy file "from" to file "to". + * Destination file is truncated if existing. + * Return 1 on success, 0 on error (printing an error). + */ +static int +message_tester_copy_file(const char *from, const char *to) +{ + char message[256]; + FILE *in, *out; + char buf[256]; + size_t n; + + /* Open "from" file for reading */ + in=fopen(from, "r"); + if ( in == NULL ) + { + snprintf(message, 255, "Can't open %s for reading: %s\n", + from, strerror(errno)); + fprintf(stderr, "%s", message); + return 0; + } + + /* Open "to" file for writing (will truncate existing files) */ + out=fopen(to, "w"); + if ( out == NULL ) + { + snprintf(message, 255, "Can't open %s for writing: %s\n", + to, strerror(errno)); + fprintf(stderr, "%s", message); + fclose(in); + return 0; + } + + /* Copy data from "in" to "out" */ + while ( (n=fread(buf, 1, sizeof buf, in)) > 0 ) + { + if ( ! fwrite(buf, 1, n, out) ) + { + fclose(in); + fclose(out); + return 0; + } + } + + fclose(in); + fclose(out); + + return 1; +} + +static int check_no_strange_time(void* data,int argc, char** argv,char** cNames) { + CU_ASSERT_EQUAL(argc, 0); + return 0; +} + +static void message_storage_migration() { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + char src_db[256]; + char tmp_db[256]; + snprintf(src_db,sizeof(src_db), "%s/messages.db", liblinphone_tester_file_prefix); + snprintf(tmp_db,sizeof(tmp_db), "%s/tmp.db", liblinphone_tester_file_prefix); + + CU_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 1); + + // enable to test the performances of the migration step + //linphone_core_message_storage_set_debug(marie->lc, TRUE); + + // the messages.db has 10000 dummy messages with the very first DB scheme. + // This will test the migration procedure + linphone_core_set_chat_database_path(marie->lc, "tmp.db"); + + MSList* chatrooms = linphone_core_get_chat_rooms(marie->lc); + CU_ASSERT(ms_list_size(chatrooms) > 0); + + // check that all messages have been migrated to the UTC time storage + CU_ASSERT(sqlite3_exec(marie->lc->db, "SELECT * FROM history WHERE time != '-1';", check_no_strange_time, NULL, NULL) == SQLITE_OK ); +} + +#endif + test_t message_tests[] = { { "Text message", text_message }, { "Text message within call's dialog", text_message_within_dialog}, @@ -398,6 +486,9 @@ test_t message_tests[] = { { "Info message", info_message }, { "Info message with body", info_message_with_body }, { "IsComposing notification", is_composing_notification } +#ifdef MSG_STORAGE_ENABLED + ,{ "Database migration", message_storage_migration } +#endif }; test_suite_t message_test_suite = { diff --git a/tester/messages.db b/tester/messages.db new file mode 100644 index 000000000..072aed397 Binary files /dev/null and b/tester/messages.db differ