]> sjero.net Git - linphone/blob - coreapi/message_storage.c
clean message storage API
[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;\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         }\r
87 }\r
88 \r
89 void linphone_sql_request(sqlite3* db,const char *stmt){\r
90         char* errmsg=NULL;\r
91         int ret;\r
92         ret=sqlite3_exec(db,stmt,0,0,&errmsg);\r
93         if(ret != SQLITE_OK) {\r
94                 ms_error("linphone_sql_request: error sqlite3_exec(): %s.\n", errmsg);\r
95                 sqlite3_free(errmsg);\r
96         }\r
97 }\r
98 \r
99 void linphone_chat_message_store(LinphoneChatMessage *msg){\r
100         LinphoneCore *lc=linphone_chat_room_get_lc(msg->chat_room);\r
101         if (lc->db){\r
102                 const char *peer=msg->chat_room->peer;\r
103                 char *local_contact=linphone_address_as_string_uri_only(linphone_chat_message_get_local_address(msg));\r
104                 char datebuf[26];\r
105                 char *buf=sqlite3_mprintf("insert into history values(NULL,%Q,%Q,%i,%Q,%Q,%i,%i);",\r
106                                                 local_contact,peer,msg->dir,msg->message,my_ctime_r(&msg->time,datebuf),msg->is_read,msg->state);\r
107                 linphone_sql_request(lc->db,buf);\r
108                 sqlite3_free(buf);\r
109                 ms_free(local_contact);\r
110         }\r
111 }\r
112 \r
113 void linphone_chat_message_store_state(LinphoneChatMessage *msg){\r
114         LinphoneCore *lc=msg->chat_room->lc;\r
115         if (lc->db){\r
116                 char time_str[26];\r
117                 char *buf=sqlite3_mprintf("update history set status=%i where message = %Q and time = %Q;",\r
118                         msg->state,msg->message,my_ctime_r(&msg->time,time_str));\r
119                 linphone_sql_request(lc->db,buf);\r
120                 sqlite3_free(buf);\r
121         }\r
122 }\r
123 \r
124 void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){\r
125         LinphoneCore *lc=linphone_chat_room_get_lc(cr);\r
126         int read=1;\r
127         \r
128         if (lc->db==NULL) return ;\r
129 \r
130         char *buf=sqlite3_mprintf("update history set read=%i where remoteContact = %Q;",\r
131                        read,cr->peer);\r
132         linphone_sql_request(lc->db,buf);\r
133         sqlite3_free(buf);\r
134 }\r
135 \r
136 void linphone_chat_room_delete_history(LinphoneChatRoom *cr){\r
137         LinphoneCore *lc=cr->lc;\r
138         \r
139         if (lc->db==NULL) return ;\r
140         char *buf=sqlite3_mprintf("delete from history where remoteContact = %Q;",cr->peer);\r
141         linphone_sql_request(lc->db,buf);\r
142         sqlite3_free(buf);\r
143 }\r
144 \r
145 MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message){\r
146         LinphoneCore *lc=linphone_chat_room_get_lc(cr);\r
147         MSList *ret;\r
148         \r
149         if (lc->db==NULL) return NULL;\r
150         \r
151         cr->messages_hist = NULL;\r
152         char *buf=sqlite3_mprintf("select * from history where remoteContact = %Q order by id DESC limit %i ;",cr->peer,nb_message);\r
153         linphone_sql_request_message(lc->db,buf,cr);\r
154         sqlite3_free(buf);\r
155         ret=cr->messages_hist;\r
156         cr->messages_hist=NULL;\r
157         return ret;\r
158 }\r
159 \r
160 void linphone_close_storage(sqlite3* db){\r
161         sqlite3_close(db);\r
162 }\r
163 \r
164 void linphone_create_table(sqlite3* db){\r
165         char* errmsg;\r
166         int ret;\r
167         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
168                 0,0,&errmsg);\r
169         if(ret != SQLITE_OK) {\r
170                 printf("Error in creation: %s.\n", errmsg);\r
171         }\r
172 }\r
173 \r
174 void linphone_core_message_storage_init(LinphoneCore *lc){\r
175         int ret;\r
176         char *errmsg=NULL;\r
177         sqlite3 *db;\r
178         ret=sqlite3_open(lc->chat_db_file,&db);\r
179         if(ret != SQLITE_OK) {\r
180                 printf("Error in the opening: %s.\n", errmsg);\r
181                 sqlite3_close(db);\r
182                 sqlite3_free(errmsg);\r
183         }\r
184         linphone_create_table(db);\r
185         lc->db=db;\r
186 }\r
187 \r
188 void linphone_core_message_storage_close(LinphoneCore *lc){\r
189         if (lc->db){\r
190                 sqlite3_close(lc->db);\r
191                 lc->db=NULL;\r
192         }\r
193 }\r
194 \r
195 #else \r
196 \r
197 void linphone_chat_message_store(LinphoneChatMessage *cr){\r
198 }\r
199 \r
200 void linphone_chat_message_store_state(LinphoneChatMessage *cr){\r
201 }\r
202 \r
203 void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){\r
204 }\r
205 \r
206 MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message){\r
207         return NULL;\r
208 }\r
209 \r
210 void linphone_chat_room_delete_history(LinphoneChatRoom *cr){\r
211 }\r
212 \r
213 void linphone_core_message_storage_init(LinphoneCore *lc){\r
214 }\r
215 \r
216 void linphone_core_message_storage_close(LinphoneCore *lc){\r
217 }\r
218 \r
219 #endif\r