diff options
author | tomsmeding <tom.smeding@gmail.com> | 2017-07-05 22:28:51 +0200 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2017-07-05 22:28:51 +0200 |
commit | 4b4b42877fc81ad055f5326185e80530d23361e7 (patch) | |
tree | 5fcda074409854f921ca83f07bda5ae60b62d1d3 | |
parent | 7c30c3f9c9312500bbb86a98f81ce15982b6907a (diff) |
server: Get history before id
-rw-r--r-- | command.c | 28 | ||||
-rw-r--r-- | db.c | 35 | ||||
-rw-r--r-- | db.h | 2 |
3 files changed, 53 insertions, 12 deletions
@@ -1,6 +1,7 @@ #define _GNU_SOURCE #include <stdio.h> #include <string.h> +#include <limits.h> #include <errno.h> #include <sys/time.h> #include <sys/socket.h> @@ -238,11 +239,14 @@ static bool cmd_send(struct conn_data *data,const char *tag,const char **args){ return closed; } -static bool cmd_history(struct conn_data *data,const char *tag,const char **args){ +static bool history_cmd_helper( + struct conn_data *data,const char *tag,const char **args, + const char *cmdname,i64 beforeid){ char *endp; i64 nrequested=strtoll(args[1],&endp,10); if(args[1][0]=='\0'||*endp!='\0'||nrequested<0){ - debug("Connection fd=%d sent an invalid number for 'history': '%s'",data->fd,args[1]); + debug("Connection fd=%d sent an invalid number for '%s': '%s'", + data->fd,cmdname,args[1]); return true; } @@ -261,7 +265,7 @@ static bool cmd_history(struct conn_data *data,const char *tag,const char **args return false; } - struct db_message_list ml=db_get_messages(roomid,nrequested); + struct db_message_list ml=db_get_messages_before(roomid,nrequested,beforeid); char *buf=NULL; i64 len=asprintf(&buf,"%s history %" PRIi64 "\n",tag,ml.count); bool closed=net_send_raw_text(data->fd,buf,len); @@ -286,6 +290,23 @@ static bool cmd_history(struct conn_data *data,const char *tag,const char **args return closed; } +static bool cmd_history(struct conn_data *data,const char *tag,const char **args){ + return history_cmd_helper(data,tag,args,"history",-1); +} + +static bool cmd_history_before(struct conn_data *data,const char *tag,const char **args){ + char *endp; + i64 beforeid=strtoll(args[2],&endp,10); + if(args[2][0]=='\0'||*endp!='\0'){ + debug("Connection fd=%d sent an invalid id for 'history_before': '%s'", + data->fd,args[2]); + return true; + } + if(beforeid<0)beforeid=INT64_MAX; + + return history_cmd_helper(data,tag,args,"history_before",beforeid); +} + static bool cmd_ping(struct conn_data *data,const char *tag,const char **args){ (void)args; return net_send_pong(data->fd,tag); @@ -353,6 +374,7 @@ static const struct cmd_info commands[]={ {"invite",2,false,cmd_invite}, {"send",2,true,cmd_send}, {"history",2,false,cmd_history}, + {"history_before",3,false,cmd_history_before}, {"ping",0,false,cmd_ping}, {"is_online",1,false,cmd_is_online}, {"firebase_token",1,false,cmd_firebase_token}, @@ -304,18 +304,35 @@ void db_create_message(i64 roomid,i64 userid,i64 timestamp,const char *message){ } struct db_message_list db_get_messages(i64 roomid,i64 count){ + return db_get_messages_before(roomid,count,-1); +} + +struct db_message_list db_get_messages_before(i64 roomid,i64 count,i64 beforeid){ assert(count>=0); sqlite3_stmt *stmt; - SQLITE(prepare_v2,database, - "select id, user, time, message " - "from Messages " - "where room = ? " - "order by time desc " - "limit ?" - ,-1,&stmt,NULL); - SQLITE(bind_int64,stmt,1,roomid); - SQLITE(bind_int64,stmt,2,count); + if(beforeid<0){ + SQLITE(prepare_v2,database, + "select id, user, time, message " + "from Messages " + "where room = ? " + "order by time desc " + "limit ?" + ,-1,&stmt,NULL); + SQLITE(bind_int64,stmt,1,roomid); + SQLITE(bind_int64,stmt,2,count); + } else { + SQLITE(prepare_v2,database, + "select id, user, time, message " + "from Messages " + "where room = ? and time < (select time from Messages where id = ?) " + "order by time desc " + "limit ?" + ,-1,&stmt,NULL); + SQLITE(bind_int64,stmt,1,roomid); + SQLITE(bind_int64,stmt,2,beforeid); + SQLITE(bind_int64,stmt,3,count); + } struct db_message_list ml; i64 cap=count; @@ -60,6 +60,8 @@ bool db_delete_token(i64 userid,const char *token); void db_create_message(i64 roomid,i64 userid,i64 timestamp,const char *message); struct db_message_list db_get_messages(i64 roomid,i64 count); // gets latest `count` messages +// if beforeid<0, same as db_get_messages +struct db_message_list db_get_messages_before(i64 roomid,i64 count,i64 beforeid); void db_nullify_name_id(struct db_name_id ni); void db_nullify_room_list(struct db_room_list rl); |