]> sjero.net Git - linphone/blob - coreapi/message_storage.c
0c41c20d078659712f4a7d954c143f38393ee342
[linphone] / coreapi / message_storage.c
1 /*\r
2 message_storage.c\r
3 Copyright (C) 2012  Belledonne Communications, Grenoble, France\r
4 \r
5 This program is free software; you can redistribute it and/or\r
6 modify it under the terms of the GNU General Public License\r
7 as published by the Free Software Foundation; either version 2\r
8 of the License, or (at your option) any later version.\r
9 \r
10 This program is distributed in the hope that it will be useful,\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 GNU General Public License for more details.\r
14 \r
15 You should have received a copy of the GNU General Public License\r
16 along with this program; if not, write to the Free Software\r
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
18 */\r
19 \r
20 #include "private.h"\r
21 #include "linphonecore.h"\r
22 \r
23 #ifdef WIN32\r
24 \r
25 static inline char *my_ctime_r(const time_t *t, char *buf){\r
26         strcpy(buf,ctime(t));\r
27         return buf;\r
28 }\r
29 \r
30 #else\r
31 #define my_ctime_r ctime_r\r
32 #endif\r
33 \r
34 #ifdef MSG_STORAGE_ENABLED\r
35 \r
36 #include "sqlite3.h"\r
37 \r
38 static const char *days[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};\r
39 static const char *months[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};\r
40 \r
41 \r
42 static void create_chat_message(char **argv, void *data){\r
43         LinphoneChatRoom *cr = (LinphoneChatRoom *)data;\r
44         LinphoneChatMessage* new_message = linphone_chat_room_create_message(cr,argv[4]);\r
45         LinphoneAddress *from;\r
46         struct tm ret={0};\r
47         char tmp1[80]={0};\r
48         char tmp2[80]={0};\r
49         \r
50         if(atoi(argv[3])==LinphoneChatMessageIncoming){\r
51                 from=linphone_address_new(argv[2]);\r
52         } else {\r
53                 from=linphone_address_new(argv[1]);\r
54         }\r
55         linphone_chat_message_set_from(new_message,from);\r
56         linphone_address_destroy(from);\r
57 \r
58         if(argv[5]!=NULL){\r
59                 int i,j;\r
60                 sscanf(argv[5],"%3c %3c%d%d:%d:%d %d",tmp1,tmp2,&ret.tm_mday,\r
61                      &ret.tm_hour,&ret.tm_min,&ret.tm_sec,&ret.tm_year);\r
62                 ret.tm_year-=1900;\r
63                 for(i=0;i<7;i++) { \r
64                         if(strcmp(tmp1,days[i])==0) ret.tm_wday=i; \r
65                 }\r
66                 for(j=0;j<12;j++) { \r
67                         if(strcmp(tmp2,months[j])==0) ret.tm_mon=j; \r
68                 }\r
69         }\r
70         new_message->time=argv[5]!=NULL ? mktime(&ret) : time(NULL);\r
71         new_message->state=atoi(argv[7]);\r
72         cr->messages_hist=ms_list_prepend(cr->messages_hist,new_message);\r
73 }\r
74 \r
75 static int callback(void *data, int argc, char **argv, char **colName){\r
76     create_chat_message(argv,data);\r
77     return 0;\r
78 }\r
79 \r
80 void linphone_sql_request_message(sqlite3 *db,const char *stmt,LinphoneChatRoom *cr){\r
81         char* errmsg=NULL;\r
82         int ret;\r
83         ret=sqlite3_exec(db,stmt,callback,cr,&errmsg);\r
84         if(ret != SQLITE_OK) {\r
85                 printf("Error in creation: %s.\n", errmsg);\r
86                 sqlite3_free(errmsg);\r
87         }\r
88 }\r
89 \r
90 void linphone_sql_request(sqlite3* db,const char *stmt){\r
91         char* errmsg=NULL;\r
92         int ret;\r
93         ret=sqlite3_exec(db,stmt,0,0,&errmsg);\r
94         if(ret != SQLITE_OK) {\r
95                 ms_error("linphone_sql_request: error sqlite3_exec(): %s.\n", errmsg);\r
96                 sqlite3_free(errmsg);\r
97         }\r
98 }\r
99 \r
100 void linphone_chat_message_store(LinphoneChatMessage *msg){\r
101         LinphoneCore *lc=linphone_chat_room_get_lc(msg->chat_room);\r
102         if (lc->db){\r
103                 char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(msg->chat_room));\r
104                 char *local_contact=linphone_address_as_string_uri_only(linphone_chat_message_get_local_address(msg));\r
105                 char datebuf[26];\r
106                 char *buf=sqlite3_mprintf("insert into history values(NULL,%Q,%Q,%i,%Q,%Q,%i,%i);",\r
107                                                 local_contact,peer,msg->dir,msg->message,my_ctime_r(&msg->time,datebuf),msg->is_read,msg->state);\r
108                 linphone_sql_request(lc->db,buf);\r
109                 sqlite3_free(buf);\r
110                 ms_free(local_contact);\r
111                 ms_free(peer);\r
112         }\r
113 }\r
114 \r
115 void linphone_chat_message_store_state(LinphoneChatMessage *msg){\r
116         LinphoneCore *lc=msg->chat_room->lc;\r
117         if (lc->db){\r
118                 char time_str[26];\r
119                 char *buf=sqlite3_mprintf("update history set status=%i where message = %Q and time = %Q;",\r
120                         msg->state,msg->message,my_ctime_r(&msg->time,time_str));\r
121                 linphone_sql_request(lc->db,buf);\r
122                 sqlite3_free(buf);\r
123         }\r
124 }\r
125 \r
126 void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){\r
127         LinphoneCore *lc=linphone_chat_room_get_lc(cr);\r
128         int read=1;\r
129         \r
130         if (lc->db==NULL) return ;\r
131 \r
132         char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr));\r
133         char *buf=sqlite3_mprintf("update history set read=%i where remoteContact = %Q;",\r
134                        read,peer);\r
135         linphone_sql_request(lc->db,buf);\r
136         sqlite3_free(buf);\r
137         ms_free(peer);\r
138 }\r
139 \r
140 int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr){\r
141         LinphoneCore *lc=linphone_chat_room_get_lc(cr);\r
142         int numrows=0;\r
143         \r
144         if (lc->db==NULL) return 0;\r
145         \r
146         char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr));\r
147         char *buf=sqlite3_mprintf("select count(*) from history where remoteContact = %Q and read = 0;",peer);\r
148         sqlite3_stmt *selectStatement;\r
149         int returnValue = sqlite3_prepare_v2(lc->db,buf,-1,&selectStatement,NULL);\r
150         if (returnValue == SQLITE_OK){\r
151                 if(sqlite3_step(selectStatement) == SQLITE_ROW){\r
152                         numrows= sqlite3_column_int(selectStatement, 0);\r
153                 }\r
154         }\r
155         sqlite3_finalize(selectStatement);\r
156         sqlite3_free(buf);\r
157         ms_free(peer);\r
158         return numrows;\r
159 }\r
160 \r
161 void linphone_chat_room_delete_history(LinphoneChatRoom *cr){\r
162         LinphoneCore *lc=cr->lc;\r
163         \r
164         if (lc->db==NULL) return ;\r
165         \r
166         char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr));\r
167         char *buf=sqlite3_mprintf("delete from history where remoteContact = %Q;",peer);\r
168         linphone_sql_request(lc->db,buf);\r
169         sqlite3_free(buf);\r
170         ms_free(peer);\r
171 }\r
172 \r
173 MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message){\r
174         LinphoneCore *lc=linphone_chat_room_get_lc(cr);\r
175         MSList *ret;\r
176         \r
177         if (lc->db==NULL) return NULL;\r
178         char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr));\r
179         cr->messages_hist = NULL;\r
180         char *buf=sqlite3_mprintf("select * from history where remoteContact = %Q order by id DESC limit %i ;",peer,nb_message);\r
181         linphone_sql_request_message(lc->db,buf,cr);\r
182         sqlite3_free(buf);\r
183         ret=cr->messages_hist;\r
184         cr->messages_hist=NULL;\r
185         ms_free(peer);\r
186         return ret;\r
187 }\r
188 \r
189 void linphone_close_storage(sqlite3* db){\r
190         sqlite3_close(db);\r
191 }\r
192 \r
193 void linphone_create_table(sqlite3* db){\r
194         char* errmsg=NULL;\r
195         int ret;\r
196         ret=sqlite3_exec(db,"CREATE TABLE if not exists history (id INTEGER PRIMARY KEY AUTOINCREMENT, localContact TEXT NOT NULL, remoteContact TEXT NOT NULL, direction INTEGER, message TEXT, time TEXT NOT NULL, read INTEGER, status INTEGER);",\r
197                 0,0,&errmsg);\r
198         if(ret != SQLITE_OK) {\r
199                 printf("Error in creation: %s.\n", errmsg);\r
200                 sqlite3_free(errmsg);\r
201         }\r
202 }\r
203 \r
204 void linphone_core_message_storage_init(LinphoneCore *lc){\r
205         int ret;\r
206         char *errmsg=NULL;\r
207         sqlite3 *db;\r
208         ret=sqlite3_open(lc->chat_db_file,&db);\r
209         if(ret != SQLITE_OK) {\r
210                 printf("Error in the opening: %s.\n", errmsg);\r
211                 sqlite3_close(db);\r
212                 sqlite3_free(errmsg);\r
213         }\r
214         linphone_create_table(db);\r
215         lc->db=db;\r
216 }\r
217 \r
218 void linphone_core_message_storage_close(LinphoneCore *lc){\r
219         if (lc->db){\r
220                 sqlite3_close(lc->db);\r
221                 lc->db=NULL;\r
222         }\r
223 }\r
224 \r
225 #else \r
226 \r
227 void linphone_chat_message_store(LinphoneChatMessage *cr){\r
228 }\r
229 \r
230 void linphone_chat_message_store_state(LinphoneChatMessage *cr){\r
231 }\r
232 \r
233 void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){\r
234 }\r
235 \r
236 MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message){\r
237         return NULL;\r
238 }\r
239 \r
240 void linphone_chat_room_delete_history(LinphoneChatRoom *cr){\r
241 }\r
242 \r
243 void linphone_core_message_storage_init(LinphoneCore *lc){\r
244 }\r
245 \r
246 void linphone_core_message_storage_close(LinphoneCore *lc){\r
247 }\r
248 \r
249 int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr){\r
250         return 0;\r
251 }\r
252 \r
253 #endif\r