diff --git a/ChangeLog b/ChangeLog index 19d669e09..51ac49d13 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2007-11-03 Mickael Remond + + * src/ejabberd_auth.erl: Better count management and batch users + retrieval for relational database (Thanks to Massimiliano Mirra). + * src/ejabberd_auth_odbc.erl: Likewise. + * src/odbc/odbc_queries.erl: Likewise. + 2007-11-02 Mickael Remond * src/web/ejabberd_http_poll.erl: Refactoring. Moved c2s limits diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl index 6ecd054d1..d62cf333f 100644 --- a/src/ejabberd_auth.erl +++ b/src/ejabberd_auth.erl @@ -22,7 +22,9 @@ try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, + get_vh_registered_users/2, get_vh_registered_users_number/1, + get_vh_registered_users_number/2, get_password/2, get_password_s/2, is_user_exists/2, @@ -108,6 +110,12 @@ get_vh_registered_users(Server) -> M:get_vh_registered_users(Server) end, auth_modules(Server)). +get_vh_registered_users(Server, Opts) -> + lists:flatmap( + fun(M) -> + M:get_vh_registered_users(Server, Opts) + end, auth_modules(Server)). + get_vh_registered_users_number(Server) -> lists:sum( lists:map( @@ -121,6 +129,19 @@ get_vh_registered_users_number(Server) -> end end, auth_modules(Server))). +get_vh_registered_users_number(Server, Opts) -> + lists:sum( + lists:map( + fun(M) -> + case erlang:function_exported( + M, get_vh_registered_users_number, 2) of + true -> + M:get_vh_registered_users_number(Server, Opts); + false -> + length(M:get_vh_registered_users(Server)) + end + end, auth_modules(Server))). + get_password(User, Server) -> lists:foldl( fun(M, false) -> diff --git a/src/ejabberd_auth_odbc.erl b/src/ejabberd_auth_odbc.erl index e045e05c5..cc65aa053 100644 --- a/src/ejabberd_auth_odbc.erl +++ b/src/ejabberd_auth_odbc.erl @@ -18,7 +18,9 @@ try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, + get_vh_registered_users/2, get_vh_registered_users_number/1, + get_vh_registered_users_number/2, get_password/2, get_password_s/2, is_user_exists/2, @@ -122,6 +124,15 @@ get_vh_registered_users(Server) -> [] end. +get_vh_registered_users(Server, Opts) -> + LServer = jlib:nameprep(Server), + case catch odbc_queries:list_users(LServer, Opts) of + {selected, ["username"], Res} -> + [{U, LServer} || {U} <- Res]; + _ -> + [] + end. + get_vh_registered_users_number(Server) -> LServer = jlib:nameprep(Server), case catch odbc_queries:users_number(LServer) of @@ -131,6 +142,15 @@ get_vh_registered_users_number(Server) -> 0 end. +get_vh_registered_users_number(Server, Opts) -> + LServer = jlib:nameprep(Server), + case catch odbc_queries:users_number(LServer, Opts) of + {selected, [_], [{Res}]} -> + list_to_integer(Res); + Other -> + 0 + end. + get_password(User, Server) -> case jlib:nodeprep(User) of error -> diff --git a/src/odbc/odbc_queries.erl b/src/odbc/odbc_queries.erl index 9b0ec61a3..c2ba81f9b 100644 --- a/src/odbc/odbc_queries.erl +++ b/src/odbc/odbc_queries.erl @@ -15,7 +15,9 @@ del_user/2, del_user_return_password/3, list_users/1, + list_users/2, users_number/1, + users_number/2, add_spool_sql/2, add_spool/2, get_and_del_spool_msg_t/2, @@ -111,6 +113,34 @@ list_users(LServer) -> LServer, "select username from users"). +list_users(LServer, [{from, Start}, {to, End}]) when is_integer(Start) and + is_integer(End) -> + list_users(LServer, [{limit, End-Start}, {offset, Start-1}]); +list_users(LServer, [{prefix, Prefix}, {from, Start}, {to, End}]) when is_list(Prefix) and + is_integer(Start) and + is_integer(End) -> + list_users(LServer, [{prefix, Prefix}, {limit, End-Start}, {offset, Start}]); + +list_users(LServer, [{limit, Limit}, {offset, Offset}]) when is_integer(Limit) and + is_integer(Offset) -> + ejabberd_odbc:sql_query( + LServer, + io_lib:format( + "select username from users " ++ + "order by username " ++ + "limit ~w offset ~w", [Limit, Offset])); +list_users(LServer, [{prefix, Prefix}, + {limit, Limit}, + {offset, Offset}]) when is_list(Prefix) and + is_integer(Limit) and + is_integer(Offset) -> + ejabberd_odbc:sql_query( + LServer, + io_lib:format("select username from users " ++ + "where username like '~s%' " ++ + "order by username " ++ + "limit ~w offset ~w ", [Prefix, Limit, Offset])). + users_number(LServer) -> case ejabberd_config:get_local_option( {pgsql_users_number_estimate, LServer}) of @@ -125,6 +155,17 @@ users_number(LServer) -> "select count(*) from users") end. +users_number(LServer, [{prefix, Prefix}]) when is_list(Prefix) -> + ejabberd_odbc:sql_query( + LServer, + io_lib:fwrite("select count(*) from users " ++ + %% Warning: Escape prefix at higher level to prevent SQL + %% injection. + "where username like '~s%'", [Prefix])); +users_number(LServer, []) -> + users_number(LServer). + + add_spool_sql(Username, XML) -> ["insert into spool(username, xml) " "values ('", Username, "', '",