mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-26 16:26:24 +01:00
Merge from trunk (r1563 to r1613).
PR: EJABP-1 SVN Revision: 1614
This commit is contained in:
parent
aaecdc4b8a
commit
67a87af459
66
ChangeLog
66
ChangeLog
@ -1,3 +1,7 @@
|
||||
2008-10-08 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
Merge from trunk (r1563 to r1613).
|
||||
|
||||
2008-10-07 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
* src/ejabberd_local.erl: Fix a bug where an error stanza was not
|
||||
@ -9,6 +13,10 @@
|
||||
* src/mod_private.erl, src/mod_private_odbc.erl, src/mod_version.erl:
|
||||
Convert to exmpp. Thanks to Pablo Polvorin!
|
||||
|
||||
2008-10-07 Jerome Sautret <jerome.sautret@process-one.net>
|
||||
|
||||
* src/mod_roster_odbc.erl: fix MySQL multiple requests issue.
|
||||
|
||||
2008-10-06 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
* src/ejabberd_sm.erl (process_iq/3): Fix a bug where we were matching
|
||||
@ -32,6 +40,29 @@
|
||||
mixing lists and binaries in a non-working way. Thanks to Pablo
|
||||
Polvorin!
|
||||
|
||||
2008-10-06 Badlop <badlop@process-one.net>
|
||||
|
||||
* doc/guide.html: Regenerated
|
||||
|
||||
2008-10-06 Jerome Sautret <jerome.sautret@process-one.net>
|
||||
|
||||
* src/ejabberd_rdbms.erl: fix SQL database reconnection
|
||||
issues (EJAB-764) and add odbc_start_interval configuration
|
||||
directive (default to 30 seconds).
|
||||
* src/odbc/ejabberd_odbc.erl: likewise.
|
||||
* src/odbc/ejabberd_odbc_sup.erl: likewise.
|
||||
* doc/guide.tex: likewise.
|
||||
|
||||
2008-10-03 Jerome Sautret <jerome.sautret@process-one.net>
|
||||
|
||||
* src/odbc/odbc_queries.erl: Fix empty query that fail on MySQL.
|
||||
|
||||
2008-10-03 Jerome Sautret <jerome.sautret@process-one.net>
|
||||
|
||||
* src/mod_vcard_odbc: added vCard support for MS SQL Server 2005.
|
||||
* src/odbc/odbc_queries.erl: likewise.
|
||||
* src/odbc/mssql2005.sql: likewise.
|
||||
|
||||
2008-10-02 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
* src/mod_roster_odbc.erl: Fix a bug where a JID represented as a
|
||||
@ -59,6 +90,17 @@
|
||||
src/mod_roster_odbc.erl: Fix multiple bugs in ODBC mods, thanks to
|
||||
Pablo Polvorin!
|
||||
|
||||
2008-10-01 Mickael Remond <mremond@process-one.net>
|
||||
|
||||
* src/mod_shared_roster.erl: Correct roster push when changing
|
||||
a shared roster entry name (EJAB-738).
|
||||
|
||||
2008-09-30 Badlop <badlop@process-one.net>
|
||||
|
||||
* src/*/Makefile.win32: Provide explicit beam filenames because
|
||||
nmake does not accept wildcards (thanks to Attila
|
||||
Vangel)(EJAB-543)
|
||||
|
||||
2008-09-29 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
* src/jlib.erl (parse_xdata_submit, parse_xdata_fields): Fix a bug
|
||||
@ -99,6 +141,25 @@
|
||||
Ejabberd expects new structures. Add table conversion. Add try/catch
|
||||
block around exmpp_stringprep:*prep/1 uses.
|
||||
|
||||
2008-09-24 Christophe Romain <christophe.romain@process-one.net>
|
||||
|
||||
* src/mod_pubsub/mod_pubsub.erl: Allow PEP node type to be mapped with
|
||||
namespace (EJAB-739). Change get_items to use From (EJAB-751). (Thanks
|
||||
to Eric Cestari)
|
||||
* src/mod_pubsub/gen_pubsub_node.erl: Likewise
|
||||
* src/mod_pubsub/node_dispatch.erl: Likewise
|
||||
* src/mod_pubsub/node_buddy.erl: Likewise
|
||||
* src/mod_pubsub/node_zoo.erl: Likewise
|
||||
* src/mod_pubsub/node.template: Likewise
|
||||
* src/mod_pubsub/node_private.erl: Likewise
|
||||
* src/mod_pubsub/node_public.erl: Likewise
|
||||
* src/mod_pubsub/node_default.erl: Likewise
|
||||
* src/mod_pubsub/node_pep.erl: Likewise
|
||||
* src/mod_pubsub/node_club.erl: Likewise
|
||||
|
||||
* src/mod_pubsub/node_mb.erl: Added PEP microglobing node (Thanks to
|
||||
Eric Cestari)
|
||||
|
||||
2008-09-23 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
* src/mod_vcard.erl (process_sm_iq): Fix a bug where a badmatch
|
||||
@ -126,6 +187,11 @@
|
||||
|
||||
* src/mod_vcard_ldap.erl, src/mod_vcard_odbc.erl: Convert to exmpp.
|
||||
|
||||
2008-09-22 Mickael Remond <mremond@process-one.net>
|
||||
|
||||
* src/mod_configure.erl: Fix adhoc commands reply types for
|
||||
"get-online-users-num" and "get-registered-users-num" (EJAB-756).
|
||||
|
||||
2008-09-18 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
* src/mod_roster_odbc.erl: Convert to exmpp.
|
||||
|
@ -635,7 +635,7 @@ Handles c2s connections.<BR>
|
||||
Handles incoming s2s connections.<BR>
|
||||
Options: <TT>inet6</TT>, <TT>ip</TT>, <TT>max_stanza_size</TT>
|
||||
</DD><DT CLASS="dt-description"><B><TT>ejabberd_service</TT></B></DT><DD CLASS="dd-description">
|
||||
Interacts with <A HREF="http://www.ejabberd.im/tutorials-transports">external components</A>
|
||||
Interacts with an <A HREF="http://www.ejabberd.im/tutorials-transports">external component</A>
|
||||
(as defined in the Jabber Component Protocol (<A HREF="http://www.xmpp.org/extensions/xep-0114.html">XEP-0114</A>).<BR>
|
||||
Options: <TT>access</TT>, <TT>hosts</TT>, <TT>inet6</TT>,
|
||||
<TT>ip</TT>, <TT>shaper</TT>, <TT>service_check_from</TT>
|
||||
@ -655,9 +655,10 @@ used to disable control on the from field on packets send by an
|
||||
external components. The option can be either <TT>true</TT> or
|
||||
<TT>false</TT>. The default value is <TT>true</TT> which conforms to <A HREF="http://www.xmpp.org/extensions/xep-0114.html">XEP-0114</A>.
|
||||
</DD><DT CLASS="dt-description"><B><TT>{hosts, [Hostnames], [HostOptions]}</TT></B></DT><DD CLASS="dd-description">
|
||||
This option of <TT>ejabberd_service</TT> allows to define one or more hostnames
|
||||
of external Jabber components that provide a service.
|
||||
In <TT>HostOptions</TT> it is possible to define the password required to those components
|
||||
The external Jabber component that connects to this <TT>ejabberd_service</TT>
|
||||
can serve one or more hostnames.
|
||||
In <TT>HostOptions</TT> you can define options for the component;
|
||||
currently the only allowed option is the password required to the component
|
||||
when attempt to connect to ejabberd: <TT>{password, Secret}</TT>.
|
||||
Note that you cannot define in a single <TT>ejabberd_service</TT> components of
|
||||
different services: add an <TT>ejabberd_service</TT> for each service,
|
||||
@ -1261,6 +1262,9 @@ to keep alive the connections to the database.
|
||||
The default value is ’undefined’, so no keepalive requests are made.
|
||||
Specify in seconds: for example 28800 means 8 hours.
|
||||
</P><PRE CLASS="verbatim">{odbc_keepalive_interval, undefined}.
|
||||
</PRE><P>If the connection to the database fails, <TT>ejabberd</TT> waits 30 seconds before retrying.
|
||||
You can modify this interval with this option:
|
||||
</P><PRE CLASS="verbatim">{odbc_start_interval, 30}.
|
||||
</PRE><P> <A NAME="compilemysql"></A> </P><!--TOC subsubsection Driver Compilation-->
|
||||
<H4 CLASS="subsubsection"><!--SEC ANCHOR --><A HREF="#compilemysql">Driver Compilation</A></H4><!--SEC END --><P> <A NAME="compilemysql"></A>
|
||||
</P><P>You can skip this step if you installed <TT>ejabberd</TT> using a binary installer or
|
||||
@ -2055,7 +2059,9 @@ change nickname.
|
||||
status text in presence updates. If disallowed, the <TT>status</TT>
|
||||
text is stripped before broadcasting the presence update to all
|
||||
the room occupants.
|
||||
</DD><DT CLASS="dt-description"><B><TT>{anonymous, true}</TT></B></DT><DD CLASS="dd-description"> Occupants are allowed to see the real JIDs of other occupants.
|
||||
</DD><DT CLASS="dt-description"><B><TT>{anonymous, true}</TT></B></DT><DD CLASS="dd-description"> The room is anonymous:
|
||||
occupants don’t see the real JIDs of other occupants.
|
||||
Note that the room moderators can always see the real JIDs of the occupants.
|
||||
</DD><DT CLASS="dt-description"><B><TT>{logging, false}</TT></B></DT><DD CLASS="dd-description"> The public messages are logged using <TT>mod_muc_log</TT>.
|
||||
</DD><DT CLASS="dt-description"><B><TT>{max_users, 200}</TT></B></DT><DD CLASS="dd-description"> Maximum number of occupants in the room.
|
||||
</DD><DT CLASS="dt-description"><B><TT>{members_by_default, true}</TT></B></DT><DD CLASS="dd-description"> The occupants that enter the room are participants by default, so they have ’voice’.
|
||||
@ -3184,11 +3190,15 @@ Copy <CODE>~ejabberd/.erlang.cookie</CODE> file from <TT>first</TT> to
|
||||
<TT>second</TT>.<P>(alt) You can also add ‘<CODE>-cookie content_of_.erlang.cookie</CODE>’
|
||||
option to all ‘<TT>erl</TT>’ commands below.</P></LI><LI CLASS="li-enumerate">On <TT>second</TT> run the following command as the <TT>ejabberd</TT> daemon user,
|
||||
in the working directory of <TT>ejabberd</TT>:<PRE CLASS="verbatim">erl -sname ejabberd \
|
||||
-mnesia dir "/var/lib/ejabberd/" \
|
||||
-mnesia extra_db_nodes "['ejabberd@first']" \
|
||||
-s mnesia
|
||||
</PRE><P>This will start Mnesia serving the same database as <TT>ejabberd@first</TT>.
|
||||
You can check this by running the command ‘<CODE>mnesia:info().</CODE>’. You
|
||||
should see a lot of remote tables and a line like the following:</P><PRE CLASS="verbatim">running db nodes = [ejabberd@first, ejabberd@second]
|
||||
should see a lot of remote tables and a line like the following:</P><P>Note: the Mnesia directory may be different in your system.
|
||||
To know where does ejabberd expect Mnesia to be installed by default,
|
||||
call <A HREF="#ejabberdctl">4.1</A> without options and it will show some help,
|
||||
including the Mnesia database spool dir.</P><PRE CLASS="verbatim">running db nodes = [ejabberd@first, ejabberd@second]
|
||||
</PRE></LI><LI CLASS="li-enumerate">Now run the following in the same ‘<TT>erl</TT>’ session:<PRE CLASS="verbatim">mnesia:change_table_copy_type(schema, node(), disc_copies).
|
||||
</PRE><P>This will create local disc storage for the database.</P><P>(alt) Change storage type of the <TT>scheme</TT> table to ‘RAM and disc
|
||||
copy’ on the second node via the Web Admin.</P></LI><LI CLASS="li-enumerate">Now you can add replicas of various tables to this node with
|
||||
|
@ -1617,6 +1617,13 @@ Specify in seconds: for example 28800 means 8 hours.
|
||||
{odbc_keepalive_interval, undefined}.
|
||||
\end{verbatim}
|
||||
|
||||
If the connection to the database fails, \ejabberd{} waits 30 seconds before retrying.
|
||||
You can modify this interval with this option:
|
||||
\begin{verbatim}
|
||||
{odbc_start_interval, 30}.
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
\makesubsubsection{compilemysql}{Driver Compilation}
|
||||
\ind{MySQL!Driver Compilation}
|
||||
|
||||
|
@ -52,14 +52,21 @@ start_hosts() ->
|
||||
|
||||
%% Start the ODBC module on the given host
|
||||
start_odbc(Host) ->
|
||||
Supervisor_name = gen_mod:get_module_proc(Host, ejabberd_odbc_sup),
|
||||
ChildSpec =
|
||||
{gen_mod:get_module_proc(Host, ejabberd_odbc_sup),
|
||||
{Supervisor_name,
|
||||
{ejabberd_odbc_sup, start_link, [Host]},
|
||||
temporary,
|
||||
transient,
|
||||
infinity,
|
||||
supervisor,
|
||||
[ejabberd_odbc_sup]},
|
||||
supervisor:start_child(ejabberd_sup, ChildSpec).
|
||||
case supervisor:start_child(ejabberd_sup, ChildSpec) of
|
||||
{ok, _PID} ->
|
||||
ok;
|
||||
_Error ->
|
||||
?ERROR_MSG("Start of supervisor ~p failed:~n~p~nRetrying...~n", [Supervisor_name, _Error]),
|
||||
start_odbc(Host)
|
||||
end.
|
||||
|
||||
%% Returns true if we have configured odbc_server for the given host
|
||||
needs_odbc(Host) ->
|
||||
|
@ -4,8 +4,7 @@ include ..\Makefile.inc
|
||||
EFLAGS = -I .. -pz ..
|
||||
|
||||
OUTDIR = ..
|
||||
SOURCES = $(wildcard *.erl)
|
||||
BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
|
||||
BEAMS = ..\ejabberd_zlib.beam
|
||||
|
||||
SOURCE = ejabberd_zlib_drv.c
|
||||
OBJECT = ejabberd_zlib_drv.o
|
||||
|
@ -4,8 +4,7 @@ include ..\Makefile.inc
|
||||
EFLAGS = -I .. -pz ..
|
||||
|
||||
OUTDIR = ..
|
||||
SOURCES = $(wildcard *.erl)
|
||||
BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
|
||||
BEAMS = ..\eldap.beam ..\eldap_filter.beam ..\eldap_pool.beam ..\eldap_utils.beam
|
||||
|
||||
ALL : $(BEAMS)
|
||||
|
||||
|
@ -1240,7 +1240,7 @@ get_form(Host, ?NS_ADMINL("get-registered-users-num"), Lang) ->
|
||||
[#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
|
||||
[?HFIELD(),
|
||||
#xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
|
||||
[#xmlattr{name = 'type', value = "jid-single"},
|
||||
[#xmlattr{name = 'type', value = "text-single"},
|
||||
#xmlattr{name = 'label', value = ?T(Lang, "Number of registered users")},
|
||||
#xmlattr{name = 'var', value = "registeredusersnum"}], children =
|
||||
[#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Num)}]}]
|
||||
@ -1252,7 +1252,7 @@ get_form(Host, ?NS_ADMINL("get-online-users-num"), Lang) ->
|
||||
[#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
|
||||
[?HFIELD(),
|
||||
#xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
|
||||
[#xmlattr{name = 'type', value = "jid-single"},
|
||||
[#xmlattr{name = 'type', value = "text-single"},
|
||||
#xmlattr{name = 'label', value = ?T(Lang, "Number of online users")},
|
||||
#xmlattr{name = 'var', value = "onlineusersnum"}], children =
|
||||
[#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Num)}]}]
|
||||
|
@ -4,8 +4,7 @@ include ..\Makefile.inc
|
||||
EFLAGS = -I .. -pz ..
|
||||
|
||||
OUTDIR = ..
|
||||
SOURCES = $(wildcard *.erl)
|
||||
BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
|
||||
BEAMS = ..\iconv.beam ..\mod_irc.beam ..\mod_irc_connection.beam
|
||||
|
||||
SOURCE = iconv_erl.c
|
||||
OBJECT = iconv_erl.o
|
||||
|
@ -4,8 +4,7 @@ include ..\Makefile.inc
|
||||
EFLAGS = -I .. -pz ..
|
||||
|
||||
OUTDIR = ..
|
||||
SOURCES = $(wildcard *.erl)
|
||||
BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
|
||||
BEAMS = ..\mod_muc.beam ..\mod_muc_log.beam ..\mod_muc_room.beam
|
||||
|
||||
ALL : $(BEAMS)
|
||||
|
||||
|
@ -4,8 +4,7 @@ include ..\Makefile.inc
|
||||
EFLAGS = -I .. -pz ..
|
||||
|
||||
OUTDIR = ..
|
||||
SOURCES = $(wildcard *.erl)
|
||||
BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
|
||||
BEAMS = ..\mod_proxy65.beam ..\mod_proxy65_lib.beam ..\mod_proxy65_service.beam ..\mod_proxy65_sm.beam ..\mod_proxy65_stream.beam
|
||||
|
||||
ALL : $(BEAMS)
|
||||
|
||||
@ -19,7 +18,7 @@ $(OUTDIR)\mod_proxy65_service.beam : mod_proxy65_service.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_service.erl
|
||||
|
||||
$(OUTDIR)\mod_proxy65_sm.beam : mod_proxy65_sm.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) mod_mod_proxy65_sm.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_sm.erl
|
||||
|
||||
$(OUTDIR)\mod_proxy65_stream.beam : mod_proxy65_stream.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_stream.erl
|
||||
|
@ -4,8 +4,7 @@ include ..\Makefile.inc
|
||||
EFLAGS = -I .. -pz ..
|
||||
|
||||
OUTDIR = ..
|
||||
SOURCES = $(wildcard *.erl)
|
||||
BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
|
||||
BEAMS = ..\gen_pubsub_node.beam ..\gen_pubsub_nodetree.beam ..\mod_pubsub.beam ..\nodetree_default.beam ..\nodetree_virtual.beam ..\node_buddy.beam ..\node_club.beam ..\node_default.beam ..\node_dispatch.beam ..\node_pep.beam ..\node_private.beam ..\node_public.beam
|
||||
|
||||
ALL : $(BEAMS)
|
||||
|
||||
@ -27,9 +26,23 @@ $(OUTDIR)\nodetree_default.beam : nodetree_default.erl
|
||||
$(OUTDIR)\nodetree_virtual.beam : nodetree_virtual.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) nodetree_virtual.erl
|
||||
|
||||
$(OUTDIR)\node_buddy.beam : node_buddy.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) node_buddy.erl
|
||||
|
||||
$(OUTDIR)\node_club.beam : node_club.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) node_club.erl
|
||||
|
||||
$(OUTDIR)\node_default.beam : node_default.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) node_default.erl
|
||||
|
||||
$(OUTDIR)\node_dispatch.beam : node_dispatch.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) node_dispatch.erl
|
||||
|
||||
$(OUTDIR)\node_pep.beam : node_pep.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) node_pep.erl
|
||||
|
||||
$(OUTDIR)\node_private.beam : node_private.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) node_private.erl
|
||||
|
||||
$(OUTDIR)\node_public.beam : node_public.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) node_public.erl
|
||||
|
@ -63,7 +63,7 @@ behaviour_info(callbacks) ->
|
||||
{get_state, 3},
|
||||
{set_state, 1},
|
||||
{get_items, 7},
|
||||
{get_items, 2},
|
||||
{get_items, 3},
|
||||
{get_item, 8},
|
||||
{get_item, 3},
|
||||
{set_item, 1},
|
||||
|
@ -77,7 +77,8 @@
|
||||
delete_item/4,
|
||||
get_configure/4,
|
||||
set_configure/5,
|
||||
get_items/2,
|
||||
get_items/3,
|
||||
tree_action/3,
|
||||
node_action/3,
|
||||
node_action/4
|
||||
]).
|
||||
@ -114,6 +115,7 @@
|
||||
-record(state, {server_host,
|
||||
host,
|
||||
access,
|
||||
pep_mapping = [],
|
||||
nodetree = ?STDTREE,
|
||||
plugins = [?STDNODE]}).
|
||||
|
||||
@ -175,7 +177,7 @@ init([ServerHost, Opts]) ->
|
||||
{?NS_PUBSUB, ejabberd_sm, iq_sm},
|
||||
{?NS_PUBSUB_OWNER, ejabberd_sm, iq_sm}]),
|
||||
ejabberd_router:register_route(Host),
|
||||
{Plugins, NodeTree} = init_plugins(Host, ServerHost, Opts),
|
||||
{Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts),
|
||||
update_database(Host),
|
||||
ets:new(gen_mod:get_module_proc(Host, pubsub_state), [set, named_table]),
|
||||
ets:insert(gen_mod:get_module_proc(Host, pubsub_state), {nodetree, NodeTree}),
|
||||
@ -183,10 +185,12 @@ init([ServerHost, Opts]) ->
|
||||
ets:new(gen_mod:get_module_proc(ServerHost, pubsub_state), [set, named_table]),
|
||||
ets:insert(gen_mod:get_module_proc(ServerHost, pubsub_state), {nodetree, NodeTree}),
|
||||
ets:insert(gen_mod:get_module_proc(ServerHost, pubsub_state), {plugins, Plugins}),
|
||||
ets:insert(gen_mod:get_module_proc(ServerHost, pubsub_state), {pep_mapping, PepMapping}),
|
||||
init_nodes(Host, ServerHost),
|
||||
{ok, #state{host = Host,
|
||||
server_host = ServerHost,
|
||||
access = Access,
|
||||
pep_mapping = PepMapping,
|
||||
nodetree = NodeTree,
|
||||
plugins = Plugins}}.
|
||||
|
||||
@ -209,12 +213,14 @@ init_plugins(Host, ServerHost, Opts) ->
|
||||
?DEBUG("** tree plugin is ~p",[TreePlugin]),
|
||||
TreePlugin:init(Host, ServerHost, Opts),
|
||||
Plugins = lists:usort(gen_mod:get_opt(plugins, Opts, []) ++ [?STDNODE]),
|
||||
PepMapping = lists:usort(gen_mod:get_opt(pep_mapping, Opts, [])),
|
||||
?DEBUG("** PEP Mapping : ~p~n",[PepMapping]),
|
||||
lists:foreach(fun(Name) ->
|
||||
?DEBUG("** init ~s plugin",[Name]),
|
||||
Plugin = list_to_atom(?PLUGIN_PREFIX ++ Name),
|
||||
Plugin:init(Host, ServerHost, Opts)
|
||||
end, Plugins),
|
||||
{Plugins, TreePlugin}.
|
||||
{Plugins, TreePlugin, PepMapping}.
|
||||
|
||||
terminate_plugins(Host, ServerHost, Plugins, TreePlugin) ->
|
||||
lists:foreach(fun(Name) ->
|
||||
@ -371,11 +377,11 @@ disco_sm_items(Acc, _From, To, [], _Lang) ->
|
||||
{result, NodeItems ++ Items}
|
||||
end;
|
||||
|
||||
disco_sm_items(Acc, _From, To, Node, _Lang) ->
|
||||
disco_sm_items(Acc, From, To, Node, _Lang) ->
|
||||
%% TODO, use iq_disco_items(Host, Node, From)
|
||||
Host = To#jid.lserver,
|
||||
LJID = jlib:jid_tolower(jlib:jid_remove_resource(To)),
|
||||
case get_items(Host, Node) of
|
||||
case get_items(Host, Node, From) of
|
||||
[] ->
|
||||
Acc;
|
||||
AllItems ->
|
||||
@ -430,6 +436,8 @@ handle_call(server_host, _From, State) ->
|
||||
{reply, State#state.server_host, State};
|
||||
handle_call(plugins, _From, State) ->
|
||||
{reply, State#state.plugins, State};
|
||||
handle_call(pep_mapping, _From, State) ->
|
||||
{reply, State#state.pep_mapping, State};
|
||||
handle_call(nodetree, _From, State) ->
|
||||
{reply, State#state.nodetree, State};
|
||||
handle_call(stop, _From, State) ->
|
||||
@ -717,7 +725,7 @@ node_disco_info(Host, Node, From, Identity, Features) ->
|
||||
[] ->
|
||||
["leaf"]; %% No sub-nodes: it's a leaf node
|
||||
_ ->
|
||||
case node_call(Type, get_items, [Host, Node]) of
|
||||
case node_call(Type, get_items, [Host, Node, From]) of
|
||||
{result, []} -> ["collection"];
|
||||
{result, _} -> ["leaf", "collection"];
|
||||
_ -> []
|
||||
@ -782,7 +790,7 @@ iq_disco_items(Host, Item, From) ->
|
||||
%% TODO That is, remove name attribute
|
||||
Action =
|
||||
fun(#pubsub_node{type = Type}) ->
|
||||
NodeItems = case node_call(Type, get_items, [Host, Node]) of
|
||||
NodeItems = case node_call(Type, get_items, [Host, Node, From]) of
|
||||
{result, I} -> I;
|
||||
_ -> []
|
||||
end,
|
||||
@ -1183,10 +1191,7 @@ create_node(Host, ServerHost, [], Owner, Type, Access, Configuration) ->
|
||||
{error, extended_error(?ERR_NOT_ACCEPTABLE, "nodeid-required")}
|
||||
end;
|
||||
create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
|
||||
Type = case Host of
|
||||
{_User, _Server, _Resource} -> ?PEPNODE;
|
||||
_ -> GivenType
|
||||
end,
|
||||
Type = select_type(ServerHost, Host, Node, GivenType),
|
||||
Parent = lists:sublist(Node, length(Node) - 1),
|
||||
%% TODO, check/set node_type = Type
|
||||
ParseOptions = case xml:remove_cdata(Configuration) of
|
||||
@ -1488,12 +1493,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
|
||||
%% handles auto-create feature
|
||||
%% for automatic node creation. we'll take the default node type:
|
||||
%% first listed into the plugins configuration option, or pep
|
||||
Type = case Host of
|
||||
{_User, _Server, _Resource} ->
|
||||
?PEPNODE;
|
||||
_ ->
|
||||
hd(plugins(ServerHost))
|
||||
end,
|
||||
Type = select_type(ServerHost, Host, Node),
|
||||
case lists:member("auto-create", features(Type)) of
|
||||
true ->
|
||||
case create_node(Host, ServerHost, Node, Publisher, Type) of
|
||||
@ -1712,8 +1712,8 @@ get_items(Host, Node, From, SubId, SMaxItems, ItemIDs) ->
|
||||
end
|
||||
end.
|
||||
|
||||
get_items(Host, Node) ->
|
||||
case node_action(Host, Node, get_items, [Host, Node]) of
|
||||
get_items(Host, Node, From) ->
|
||||
case node_action(Host, Node, get_items, [Host, Node, From]) of
|
||||
{result, Items} -> Items;
|
||||
_ -> []
|
||||
end.
|
||||
@ -1723,15 +1723,15 @@ get_items(Host, Node) ->
|
||||
%% Node = pubsubNode()
|
||||
%% LJID = {U, S, []}
|
||||
%% @doc <p>Resend the items of a node to the user.</p>
|
||||
send_all_items(Host, Node, LJID) ->
|
||||
send_items(Host, Node, LJID, all).
|
||||
%send_all_items(Host, Node, LJID) ->
|
||||
% send_items(Host, Node, LJID, all).
|
||||
|
||||
send_last_item(Host, Node, LJID) ->
|
||||
send_items(Host, Node, LJID, last).
|
||||
|
||||
%% TODO use cache-last-item feature
|
||||
send_items(Host, Node, LJID, Number) ->
|
||||
ToSend = case get_items(Host, Node) of
|
||||
ToSend = case get_items(Host, Node, LJID) of
|
||||
[] ->
|
||||
[];
|
||||
Items ->
|
||||
@ -2411,11 +2411,8 @@ get_configure(Host, Node, From, Lang) ->
|
||||
end,
|
||||
transaction(Host, Node, Action, sync_dirty).
|
||||
|
||||
get_default(Host, _Node, _From, Lang) ->
|
||||
Type = case Host of
|
||||
{_, _, _} -> ?PEPNODE;
|
||||
_ -> hd(plugins(Host))
|
||||
end,
|
||||
get_default(Host, Node, _From, Lang) ->
|
||||
Type=select_type(Host, Host, Node),
|
||||
Options = node_options(Type),
|
||||
{result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB_OWNER}],
|
||||
[{xmlelement, "default", [],
|
||||
@ -2663,6 +2660,19 @@ plugins(Host) ->
|
||||
[{plugins, PL}] -> PL;
|
||||
_ -> [?STDNODE]
|
||||
end.
|
||||
select_type(ServerHost, Host, Node, Type)->
|
||||
?DEBUG("SELECT_TYPE : ~p~n", [Node]),
|
||||
case Host of
|
||||
{_User, _Server, _Resource} ->
|
||||
case ets:lookup(gen_mod:get_module_proc(ServerHost, pubsub_state), pep_mapping) of
|
||||
[{pep_mapping, PM}] -> ?DEBUG("SELECT_TYPE : ~p~n", [PM]), proplists:get_value(Node, PM,?PEPNODE);
|
||||
R -> ?DEBUG("SELECT_TYPE why ?: ~p~n", [R]), ?PEPNODE
|
||||
end;
|
||||
_ ->
|
||||
Type
|
||||
end.
|
||||
select_type(ServerHost, Host, Node) ->
|
||||
select_type(ServerHost, Host, Node,hd(plugins(ServerHost))).
|
||||
|
||||
features() ->
|
||||
[
|
||||
@ -2811,3 +2821,4 @@ uniqid() ->
|
||||
get_item_name(Host, Node, Id) ->
|
||||
{result, Name} = node_action(Host, Node, get_item_name, [Host, Node, Id]),
|
||||
Name.
|
||||
|
||||
|
@ -62,7 +62,7 @@
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_items/3,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1
|
||||
@ -168,8 +168,8 @@ get_state(Host, Node, JID) ->
|
||||
set_state(State) ->
|
||||
node_default:set_state(State).
|
||||
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
get_items(Host, Node, From) ->
|
||||
node_default:get_items(Host, Node, From).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId)
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
@ -63,7 +63,7 @@
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_items/3,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
@ -171,8 +171,8 @@ get_state(Host, Node, JID) ->
|
||||
set_state(State) ->
|
||||
node_default:set_state(State).
|
||||
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
get_items(Host, Node, From) ->
|
||||
node_default:get_items(Host, Node, From).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
@ -63,7 +63,7 @@
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_items/3,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
@ -170,8 +170,8 @@ get_state(Host, Node, JID) ->
|
||||
set_state(State) ->
|
||||
node_default:set_state(State).
|
||||
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
get_items(Host, Node, From) ->
|
||||
node_default:get_items(Host, Node, From).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
@ -70,7 +70,7 @@
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_items/3,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
@ -705,9 +705,9 @@ set_state(_) ->
|
||||
%% relational database), or they can even decide not to persist any items.</p>
|
||||
%% <p>If a PubSub plugin wants to delegate the item storage to the default node,
|
||||
%% they can implement this function like this:
|
||||
%% ```get_items(Host, Node) ->
|
||||
%% node_default:get_items(Host, Node).'''</p>
|
||||
get_items(Host, Node) ->
|
||||
%% ```get_items(Host, Node, From) ->
|
||||
%% node_default:get_items(Host, Node, From).'''</p>
|
||||
get_items(Host, Node, _From) ->
|
||||
Items = mnesia:match_object(
|
||||
#pubsub_item{itemid = {'_', {Host, Node}}, _ = '_'}),
|
||||
{result, Items}.
|
||||
@ -747,7 +747,7 @@ get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, _SubI
|
||||
%% % Payment is required for a subscription
|
||||
%% {error, ?ERR_PAYMENT_REQUIRED};
|
||||
true ->
|
||||
get_items(Host, Node)
|
||||
get_items(Host, Node, JID)
|
||||
end.
|
||||
|
||||
%% @spec (Host, Node, ItemId) -> [Item] | []
|
||||
|
@ -61,7 +61,7 @@
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_items/3,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
@ -173,8 +173,8 @@ get_state(Host, Node, JID) ->
|
||||
set_state(State) ->
|
||||
node_default:set_state(State).
|
||||
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
get_items(Host, Node, From) ->
|
||||
node_default:get_items(Host, Node, From).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
197
src/mod_pubsub/node_mb.erl
Normal file
197
src/mod_pubsub/node_mb.erl
Normal file
@ -0,0 +1,197 @@
|
||||
%%% ====================================================================
|
||||
%%% ``The contents of this file are subject to the Erlang Public License,
|
||||
%%% Version 1.1, (the "License"); you may not use this file except in
|
||||
%%% compliance with the License. You should have received a copy of the
|
||||
%%% Erlang Public License along with this software. If not, it can be
|
||||
%%% retrieved via the world wide web at http://www.erlang.org/.
|
||||
%%%
|
||||
%%% Software distributed under the License is distributed on an "AS IS"
|
||||
%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
%%% the License for the specific language governing rights and limitations
|
||||
%%% under the License.
|
||||
%%%
|
||||
%%% The Initial Developer of the Original Code is ProcessOne.
|
||||
%%% Portions created by ProcessOne are Copyright 2006-2008, ProcessOne
|
||||
%%% All Rights Reserved.''
|
||||
%%% This software is copyright 2006-2008, ProcessOne.
|
||||
%%%
|
||||
%%%
|
||||
%%% @copyright 2006-2008 ProcessOne
|
||||
%%% @author Eric Cestari <eric@ohmforce.com>
|
||||
%%% @version {@vsn}, {@date} {@time}
|
||||
%%% @end
|
||||
%%% ====================================================================
|
||||
|
||||
|
||||
%%% @doc The module <strong>{@module}</strong> is the pep microblog PubSub plugin.
|
||||
%%% <p> To be used, mod_pubsub must be configured :
|
||||
%%% {mod_pubsub, [ % requires mod_caps
|
||||
%%% {access_createnode, pubsub_createnode},
|
||||
%%% {plugins, ["default", "pep","mb"]},
|
||||
%%% {pep_mapping, [{"urn:xmpp:microblog", "mb"}]}
|
||||
%%% ]},
|
||||
%%% <p>PubSub plugin nodes are using the {@link gen_pubsub_node} behaviour.</p>
|
||||
|
||||
-module(node_mb).
|
||||
-author('eric@ohmforce.com').
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("pubsub.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-behaviour(gen_pubsub_node).
|
||||
|
||||
%% API definition
|
||||
-export([init/3, terminate/2,
|
||||
options/0, features/0,
|
||||
create_node_permission/6,
|
||||
create_node/3,
|
||||
delete_node/2,
|
||||
purge_node/3,
|
||||
subscribe_node/8,
|
||||
unsubscribe_node/5,
|
||||
publish_item/7,
|
||||
delete_item/4,
|
||||
remove_extra_items/4,
|
||||
get_entity_affiliations/2,
|
||||
get_node_affiliations/2,
|
||||
get_affiliation/3,
|
||||
set_affiliation/4,
|
||||
get_entity_subscriptions/2,
|
||||
get_node_subscriptions/2,
|
||||
get_subscription/3,
|
||||
set_subscription/4,
|
||||
get_states/2,
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/3,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
]).
|
||||
|
||||
init(Host, ServerHost, Opts) ->
|
||||
node_pep:init(Host, ServerHost, Opts).
|
||||
|
||||
terminate(Host, ServerHost) ->
|
||||
node_pep:terminate(Host, ServerHost),
|
||||
ok.
|
||||
|
||||
options() ->
|
||||
[{node_type, pep},
|
||||
{deliver_payloads, true},
|
||||
{notify_config, false},
|
||||
{notify_delete, false},
|
||||
{notify_retract, false},
|
||||
{persist_items, true},
|
||||
{max_items, ?MAXITEMS},
|
||||
{subscribe, true},
|
||||
{access_model, presence},
|
||||
{roster_groups_allowed, []},
|
||||
{publish_model, publishers},
|
||||
{max_payload_size, ?MAX_PAYLOAD_SIZE},
|
||||
{send_last_published_item, on_sub_and_presence},
|
||||
{deliver_notifications, true},
|
||||
{presence_based_delivery, true}].
|
||||
|
||||
features() ->
|
||||
["create-nodes", %*
|
||||
"auto-create", %*
|
||||
"auto-subscribe", %*
|
||||
"delete-nodes", %*
|
||||
"filtered-notifications", %*
|
||||
"modify-affiliations",
|
||||
"outcast-affiliation",
|
||||
"persistent-items",
|
||||
"publish", %*
|
||||
"purge-nodes",
|
||||
"retract-items",
|
||||
"retrieve-affiliations",
|
||||
"retrieve-items", %*
|
||||
"retrieve-subscriptions",
|
||||
"subscribe" %*
|
||||
].
|
||||
|
||||
create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access) ->
|
||||
node_pep:create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access).
|
||||
|
||||
create_node(Host, Node, Owner) ->
|
||||
node_pep:create_node(Host, Node, Owner).
|
||||
|
||||
delete_node(Host, Removed) ->
|
||||
node_pep:delete_node(Host, Removed).
|
||||
|
||||
subscribe_node(Host, Node, Sender, Subscriber, AccessModel,
|
||||
SendLast, PresenceSubscription, RosterGroup) ->
|
||||
node_pep:subscribe_node(
|
||||
Host, Node, Sender, Subscriber, AccessModel, SendLast,
|
||||
PresenceSubscription, RosterGroup).
|
||||
|
||||
unsubscribe_node(Host, Node, Sender, Subscriber, SubID) ->
|
||||
node_pep:unsubscribe_node(Host, Node, Sender, Subscriber, SubID).
|
||||
|
||||
publish_item(Host, Node, Publisher, Model, MaxItems, ItemId, Payload) ->
|
||||
node_pep:publish_item(Host, Node, Publisher, Model, MaxItems, ItemId, Payload).
|
||||
|
||||
remove_extra_items(Host, Node, MaxItems, ItemIds) ->
|
||||
node_pep:remove_extra_items(Host, Node, MaxItems, ItemIds).
|
||||
|
||||
delete_item(Host, Node, JID, ItemId) ->
|
||||
node_pep:delete_item(Host, Node, JID, ItemId).
|
||||
|
||||
purge_node(Host, Node, Owner) ->
|
||||
node_pep:purge_node(Host, Node, Owner).
|
||||
|
||||
get_entity_affiliations(Host, Owner) ->
|
||||
node_pep:get_entity_affiliations(Host, Owner).
|
||||
|
||||
get_node_affiliations(Host, Node) ->
|
||||
node_pep:get_node_affiliations(Host, Node).
|
||||
|
||||
get_affiliation(Host, Node, Owner) ->
|
||||
node_pep:get_affiliation(Host, Node, Owner).
|
||||
|
||||
set_affiliation(Host, Node, Owner, Affiliation) ->
|
||||
node_pep:set_affiliation(Host, Node, Owner, Affiliation).
|
||||
|
||||
get_entity_subscriptions(Host,Owner) ->
|
||||
node_pep:get_entity_subscriptions(Host, Owner).
|
||||
|
||||
get_node_subscriptions(Host, Node) ->
|
||||
node_pep:get_node_subscriptions(Host, Node).
|
||||
|
||||
get_subscription(Host,Node,Owner) ->
|
||||
node_pep:get_subscription(Host,Node,Owner).
|
||||
|
||||
set_subscription(Host, Node, Owner, Subscription) ->
|
||||
node_pep:set_subscription(Host, Node, Owner, Subscription).
|
||||
|
||||
get_states(Host, Node) ->
|
||||
node_pep:get_states(Host, Node).
|
||||
|
||||
get_state(Host, Node, JID) ->
|
||||
node_pep:get_state(Host, Node, JID).
|
||||
|
||||
set_state(State) ->
|
||||
node_pep:set_state(State).
|
||||
|
||||
get_items(Host, Node, From) ->
|
||||
node_pep:get_items(Host, Node, From).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_pep:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
get_item(Host, Node, ItemId) ->
|
||||
node_pep:get_item(Host, Node, ItemId).
|
||||
|
||||
get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_pep:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
set_item(Item) ->
|
||||
node_pep:set_item(Item).
|
||||
|
||||
get_item_name(Host, Node, Id) ->
|
||||
node_pep:get_item_name(Host, Node, Id).
|
||||
|
@ -59,7 +59,7 @@
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_items/3,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
@ -123,7 +123,8 @@ create_node_permission(Host, ServerHost, _Node, _ParentNode, Owner, Access) ->
|
||||
{User, Server, _} -> true;
|
||||
_ -> false
|
||||
end;
|
||||
_ ->
|
||||
E ->
|
||||
?DEBUG("Create not allowed : ~p~n", [E]),
|
||||
false
|
||||
end
|
||||
end,
|
||||
@ -215,8 +216,8 @@ get_state(Host, Node, JID) ->
|
||||
set_state(State) ->
|
||||
node_default:set_state(State).
|
||||
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
get_items(Host, Node, From) ->
|
||||
node_default:get_items(Host, Node, From).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
@ -63,7 +63,7 @@
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_items/3,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
@ -173,8 +173,8 @@ get_state(Host, Node, JID) ->
|
||||
set_state(State) ->
|
||||
node_default:set_state(State).
|
||||
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
get_items(Host, Node, From) ->
|
||||
node_default:get_items(Host, Node, From).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
@ -63,7 +63,7 @@
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_items/3,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
@ -170,8 +170,8 @@ get_state(Host, Node, JID) ->
|
||||
set_state(State) ->
|
||||
node_default:set_state(State).
|
||||
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
get_items(Host, Node, From) ->
|
||||
node_default:get_items(Host, Node, From).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
@ -54,7 +54,7 @@
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_items/3,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
@ -163,8 +163,8 @@ get_state(Host, Node, JID) ->
|
||||
set_state(State) ->
|
||||
node_default:set_state(State).
|
||||
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
get_items(Host, Node, From) ->
|
||||
node_default:get_items(Host, Node, From).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
@ -638,7 +638,7 @@ set_items(User, Server, #xmlel{children = Els}) ->
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
catch odbc_queries:sql_transaction(
|
||||
LServer,
|
||||
lists:map(fun(El) ->
|
||||
lists:flatmap(fun(El) ->
|
||||
process_item_set_t(LUser, LServer, El)
|
||||
end, Els))
|
||||
catch
|
||||
@ -1060,4 +1060,3 @@ us_to_list({User, Server}) ->
|
||||
|
||||
webadmin_user(Acc, _User, _Server, Lang) ->
|
||||
Acc ++ [?XE("h3", [?ACT("roster/", "Roster")])].
|
||||
|
||||
|
@ -161,6 +161,7 @@ get_user_roster(Items, US) ->
|
||||
process_item(RosterItem, Host) ->
|
||||
USFrom = {UserFrom, ServerFrom} = RosterItem#roster.us,
|
||||
{UserTo, ServerTo, ResourceTo} = RosterItem#roster.jid,
|
||||
NameTo = RosterItem#roster.name,
|
||||
USTo = {UserTo, ServerTo},
|
||||
DisplayedGroups = get_user_displayed_groups(USFrom),
|
||||
CommonGroups = lists:filter(fun(Group) ->
|
||||
@ -188,24 +189,24 @@ process_item(RosterItem, Host) ->
|
||||
PersonalGroups ->
|
||||
%% Store roster items in From and To rosters
|
||||
set_new_rosteritems(UserFrom, ServerFrom,
|
||||
UserTo, ServerTo, ResourceTo,
|
||||
UserTo, ServerTo, ResourceTo, NameTo,
|
||||
PersonalGroups)
|
||||
end
|
||||
end.
|
||||
|
||||
build_roster_record(User1, Server1, User2, Server2, Groups) ->
|
||||
build_roster_record(User1, Server1, User2, Server2, Name2, Groups) ->
|
||||
USR2 = {User2, Server2, undefined},
|
||||
#roster{usj = {User1, Server1, USR2},
|
||||
us = {User1, Server1},
|
||||
jid = USR2,
|
||||
name = User2,
|
||||
name = Name2,
|
||||
subscription = both,
|
||||
ask = none,
|
||||
groups = Groups
|
||||
}.
|
||||
|
||||
set_new_rosteritems(UserFrom, ServerFrom,
|
||||
UserTo, ServerTo, ResourceTo, GroupsFrom) ->
|
||||
UserTo, ServerTo, ResourceTo, NameTo, GroupsFrom) ->
|
||||
Mod = case lists:member(mod_roster_odbc,
|
||||
gen_mod:loaded_modules(ServerFrom)) of
|
||||
true -> mod_roster_odbc;
|
||||
@ -213,13 +214,13 @@ set_new_rosteritems(UserFrom, ServerFrom,
|
||||
end,
|
||||
|
||||
RIFrom = build_roster_record(UserFrom, ServerFrom,
|
||||
UserTo, ServerTo, GroupsFrom),
|
||||
UserTo, ServerTo, NameTo, GroupsFrom),
|
||||
set_item(UserFrom, ServerFrom, ResourceTo, RIFrom),
|
||||
JIDTo = exmpp_jid:make_bare_jid(UserTo, ServerTo),
|
||||
|
||||
JIDFrom = exmpp_jid:make_bare_jid(UserFrom, ServerFrom),
|
||||
RITo = build_roster_record(UserTo, ServerTo,
|
||||
UserFrom, ServerFrom, []),
|
||||
UserFrom, ServerFrom, UserFrom,[]),
|
||||
set_item(UserTo, ServerTo, undefined, RITo),
|
||||
|
||||
%% From requests
|
||||
|
@ -131,10 +131,7 @@ process_local_iq(_From, _To, #iq{type = set} = IQ_Rec) ->
|
||||
process_sm_iq(_From, To, #iq{type = get} = IQ_Rec) ->
|
||||
#jid{lnode = LUser, ldomain = LServer} = To,
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
case catch ejabberd_odbc:sql_query(
|
||||
LServer,
|
||||
["select vcard from vcard "
|
||||
"where username='", Username, "';"]) of
|
||||
case catch odbc_queries:get_vcard(LServer, Username) of
|
||||
{selected, ["vcard"], [{SVCARD}]} ->
|
||||
try exmpp_xml:parse_document(SVCARD,
|
||||
[namespace, name_as_atom, autoload_known]) of
|
||||
@ -233,30 +230,13 @@ set_vcard(User, LServer, VCARD) ->
|
||||
SOrgUnit = ejabberd_odbc:escape(OrgUnit),
|
||||
SLOrgUnit = ejabberd_odbc:escape(LOrgUnit),
|
||||
|
||||
ejabberd_odbc:sql_transaction(
|
||||
LServer,
|
||||
[["delete from vcard where username='", LUsername, "';"],
|
||||
["insert into vcard(username, vcard) "
|
||||
"values ('", LUsername, "', '", SVCARD, "');"],
|
||||
["delete from vcard_search where lusername='", LUsername, "';"],
|
||||
["insert into vcard_search("
|
||||
" username, lusername, fn, lfn, family, lfamily,"
|
||||
" given, lgiven, middle, lmiddle, nickname, lnickname,"
|
||||
" bday, lbday, ctry, lctry, locality, llocality,"
|
||||
" email, lemail, orgname, lorgname, orgunit, lorgunit)"
|
||||
"values (",
|
||||
" '", Username, "', '", LUsername, "',"
|
||||
" '", SFN, "', '", SLFN, "',"
|
||||
" '", SFamily, "', '", SLFamily, "',"
|
||||
" '", SGiven, "', '", SLGiven, "',"
|
||||
" '", SMiddle, "', '", SLMiddle, "',"
|
||||
" '", SNickname, "', '", SLNickname, "',"
|
||||
" '", SBDay, "', '", SLBDay, "',"
|
||||
" '", SCTRY, "', '", SLCTRY, "',"
|
||||
" '", SLocality, "', '", SLLocality, "',"
|
||||
" '", SEMail, "', '", SLEMail, "',"
|
||||
" '", SOrgName, "', '", SLOrgName, "',"
|
||||
" '", SOrgUnit, "', '", SLOrgUnit, "');"]])
|
||||
odbc_queries:set_vcard(LServer, LUsername, SBDay, SCTRY, SEMail,
|
||||
SFN, SFamily, SGiven, SLBDay, SLCTRY,
|
||||
SLEMail, SLFN, SLFamily, SLGiven,
|
||||
SLLocality, SLMiddle, SLNickname,
|
||||
SLOrgName, SLOrgUnit, SLocality,
|
||||
SMiddle, SNickname, SOrgName,
|
||||
SOrgUnit, SVCARD, Username)
|
||||
catch
|
||||
_ ->
|
||||
{error, badarg}
|
||||
@ -643,5 +623,3 @@ remove_user(User, Server) ->
|
||||
LServer,
|
||||
[["delete from vcard where username='", Username, "';"],
|
||||
["delete from vcard_search where lusername='", Username, "';"]]).
|
||||
|
||||
|
||||
|
@ -4,8 +4,7 @@ include ..\Makefile.inc
|
||||
EFLAGS = -I .. -pz ..
|
||||
|
||||
OUTDIR = ..
|
||||
SOURCES = $(wildcard *.erl)
|
||||
BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
|
||||
BEAMS = ..\ejabberd_odbc.beam ..\ejabberd_odbc_sup.beam ..\odbc_queries.beam
|
||||
|
||||
ALL : $(BEAMS)
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
-behaviour(gen_server).
|
||||
|
||||
%% External exports
|
||||
-export([start/1, start_link/1,
|
||||
-export([start/1, start_link/2,
|
||||
sql_query/2,
|
||||
sql_query_t/1,
|
||||
sql_transaction/2,
|
||||
@ -63,8 +63,8 @@
|
||||
start(Host) ->
|
||||
gen_server:start(ejabberd_odbc, [Host], []).
|
||||
|
||||
start_link(Host) ->
|
||||
gen_server:start_link(ejabberd_odbc, [Host], []).
|
||||
start_link(Host, StartInterval) ->
|
||||
gen_server:start_link(ejabberd_odbc, [Host, StartInterval], []).
|
||||
|
||||
sql_query(Host, Query) ->
|
||||
gen_server:call(ejabberd_odbc_sup:get_random_pid(Host),
|
||||
@ -131,10 +131,10 @@ escape_like(C) -> odbc_queries:escape(C).
|
||||
%% ignore |
|
||||
%% {stop, Reason}
|
||||
%%----------------------------------------------------------------------
|
||||
init([Host]) ->
|
||||
init([Host, StartInterval]) ->
|
||||
case ejabberd_config:get_local_option({odbc_keepalive_interval, Host}) of
|
||||
Interval when is_integer(Interval) ->
|
||||
timer:apply_interval(Interval*1000, ?MODULE, keep_alive, [self()]);
|
||||
KeepaliveInterval when is_integer(KeepaliveInterval) ->
|
||||
timer:apply_interval(KeepaliveInterval*1000, ?MODULE, keep_alive, [self()]);
|
||||
undefined ->
|
||||
ok;
|
||||
_Other ->
|
||||
@ -144,16 +144,16 @@ init([Host]) ->
|
||||
case SQLServer of
|
||||
%% Default pgsql port
|
||||
{pgsql, Server, DB, Username, Password} ->
|
||||
pgsql_connect(Server, ?PGSQL_PORT, DB, Username, Password);
|
||||
pgsql_connect(Server, ?PGSQL_PORT, DB, Username, Password, StartInterval);
|
||||
{pgsql, Server, Port, DB, Username, Password} when is_integer(Port) ->
|
||||
pgsql_connect(Server, Port, DB, Username, Password);
|
||||
pgsql_connect(Server, Port, DB, Username, Password, StartInterval);
|
||||
%% Default mysql port
|
||||
{mysql, Server, DB, Username, Password} ->
|
||||
mysql_connect(Server, ?MYSQL_PORT, DB, Username, Password);
|
||||
mysql_connect(Server, ?MYSQL_PORT, DB, Username, Password, StartInterval);
|
||||
{mysql, Server, Port, DB, Username, Password} when is_integer(Port) ->
|
||||
mysql_connect(Server, Port, DB, Username, Password);
|
||||
mysql_connect(Server, Port, DB, Username, Password, StartInterval);
|
||||
_ when is_list(SQLServer) ->
|
||||
odbc_connect(SQLServer)
|
||||
odbc_connect(SQLServer, StartInterval)
|
||||
end.
|
||||
|
||||
%%----------------------------------------------------------------------
|
||||
@ -259,7 +259,7 @@ execute_transaction(State, F, NRestarts) ->
|
||||
|
||||
%% part of init/1
|
||||
%% Open an ODBC database connection
|
||||
odbc_connect(SQLServer) ->
|
||||
odbc_connect(SQLServer, StartInterval) ->
|
||||
application:start(odbc),
|
||||
case odbc:connect(SQLServer,[{scrollable_cursors, off}]) of
|
||||
{ok, Ref} ->
|
||||
@ -268,8 +268,8 @@ odbc_connect(SQLServer) ->
|
||||
{error, Reason} ->
|
||||
?ERROR_MSG("ODBC connection (~s) failed: ~p~n",
|
||||
[SQLServer, Reason]),
|
||||
%% If we can't connect we wait for 30 seconds before retrying
|
||||
timer:sleep(30000),
|
||||
%% If we can't connect we wait before retrying
|
||||
timer:sleep(StartInterval),
|
||||
{stop, odbc_connection_failed}
|
||||
end.
|
||||
|
||||
@ -278,15 +278,15 @@ odbc_connect(SQLServer) ->
|
||||
|
||||
%% part of init/1
|
||||
%% Open a database connection to PostgreSQL
|
||||
pgsql_connect(Server, Port, DB, Username, Password) ->
|
||||
pgsql_connect(Server, Port, DB, Username, Password, StartInterval) ->
|
||||
case pgsql:connect(Server, DB, Username, Password, Port) of
|
||||
{ok, Ref} ->
|
||||
erlang:monitor(process, Ref),
|
||||
{ok, #state{db_ref = Ref, db_type = pgsql}};
|
||||
{error, Reason} ->
|
||||
?ERROR_MSG("PostgreSQL connection failed: ~p~n", [Reason]),
|
||||
%% If we can't connect we wait for 30 seconds before retrying
|
||||
timer:sleep(30000),
|
||||
%% If we can't connect we wait before retrying
|
||||
timer:sleep(StartInterval),
|
||||
{stop, pgsql_connection_failed}
|
||||
end.
|
||||
|
||||
@ -317,7 +317,7 @@ pgsql_item_to_odbc(_) ->
|
||||
|
||||
%% part of init/1
|
||||
%% Open a database connection to MySQL
|
||||
mysql_connect(Server, Port, DB, Username, Password) ->
|
||||
mysql_connect(Server, Port, DB, Username, Password, StartInterval) ->
|
||||
NoLogFun = fun(_Level,_Format,_Argument) -> ok end,
|
||||
case mysql_conn:start(Server, Port, Username, Password, DB, NoLogFun) of
|
||||
{ok, Ref} ->
|
||||
@ -330,9 +330,10 @@ mysql_connect(Server, Port, DB, Username, Password) ->
|
||||
"SERIALIZABLE;"], self()),
|
||||
{ok, #state{db_ref = Ref, db_type = mysql}};
|
||||
{error, Reason} ->
|
||||
?ERROR_MSG("MySQL connection failed: ~p~n", [Reason]),
|
||||
%% If we can't connect we wait for 30 seconds before retrying
|
||||
timer:sleep(30000),
|
||||
?ERROR_MSG("MySQL connection failed: ~p~nWaiting ~p seconds before retrying...~n",
|
||||
[Reason, StartInterval div 1000]),
|
||||
%% If we can't connect we wait before retrying
|
||||
timer:sleep(StartInterval),
|
||||
{stop, mysql_connection_failed}
|
||||
end.
|
||||
|
||||
|
@ -37,13 +37,14 @@
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
-define(DEFAULT_POOL_SIZE, 10).
|
||||
-define(DEFAULT_ODBC_START_INTERVAL, 30). % 30 seconds
|
||||
|
||||
start_link(Host) ->
|
||||
supervisor:start_link({local, gen_mod:get_module_proc(Host, ?MODULE)},
|
||||
?MODULE, [Host]).
|
||||
|
||||
init([Host]) ->
|
||||
N = case ejabberd_config:get_local_option({odbc_pool_size, Host}) of
|
||||
PoolSize = case ejabberd_config:get_local_option({odbc_pool_size, Host}) of
|
||||
I when is_integer(I) ->
|
||||
I;
|
||||
undefined ->
|
||||
@ -53,16 +54,27 @@ init([Host]) ->
|
||||
[Other, Host, ?DEFAULT_POOL_SIZE]),
|
||||
?DEFAULT_POOL_SIZE
|
||||
end,
|
||||
{ok, {{one_for_one, 10, 6},
|
||||
StartInterval = case ejabberd_config:get_local_option({odbc_start_interval, Host}) of
|
||||
Interval when is_integer(Interval) ->
|
||||
Interval;
|
||||
undefined ->
|
||||
?DEFAULT_ODBC_START_INTERVAL;
|
||||
_Other2 ->
|
||||
?ERROR_MSG("Wrong odbc_start_interval definition '~p' for host ~p"
|
||||
", defaulting to ~p~n",
|
||||
[_Other2, Host, ?DEFAULT_ODBC_START_INTERVAL]),
|
||||
?DEFAULT_ODBC_START_INTERVAL
|
||||
end,
|
||||
{ok, {{one_for_one, PoolSize+1, StartInterval},
|
||||
lists:map(
|
||||
fun(I) ->
|
||||
{I,
|
||||
{ejabberd_odbc, start_link, [Host]},
|
||||
{ejabberd_odbc, start_link, [Host, StartInterval*1000]},
|
||||
transient,
|
||||
brutal_kill,
|
||||
worker,
|
||||
[?MODULE]}
|
||||
end, lists:seq(1, N))}}.
|
||||
end, lists:seq(1, PoolSize))}}.
|
||||
|
||||
get_pids(Host) ->
|
||||
Proc = gen_mod:get_module_proc(Host, ?MODULE),
|
||||
|
@ -104,6 +104,10 @@ if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[vcard]') a
|
||||
drop table [dbo].[vcard]
|
||||
GO
|
||||
|
||||
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[vcard_search]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
|
||||
drop table [dbo].[vcard_search]
|
||||
GO
|
||||
|
||||
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[private_storage]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
|
||||
drop table [dbo].[private_storage]
|
||||
GO
|
||||
@ -160,25 +164,35 @@ GO
|
||||
|
||||
CREATE TABLE [dbo].[vcard] (
|
||||
[username] [varchar] (250) NOT NULL ,
|
||||
[full_name] [varchar] (250) NULL ,
|
||||
[first_name] [varchar] (50) NULL ,
|
||||
[last_name] [varchar] (50) NULL ,
|
||||
[nick_name] [varchar] (50) NULL ,
|
||||
[url] [varchar] (1024) NULL ,
|
||||
[address1] [varchar] (50) NULL ,
|
||||
[address2] [varchar] (50) NULL ,
|
||||
[locality] [varchar] (50) NULL ,
|
||||
[region] [varchar] (50) NULL ,
|
||||
[pcode] [varchar] (50) NULL ,
|
||||
[country] [varchar] (50) NULL ,
|
||||
[telephone] [varchar] (50) NULL ,
|
||||
[email] [varchar] (250) NULL ,
|
||||
[orgname] [varchar] (50) NULL ,
|
||||
[orgunit] [varchar] (50) NULL ,
|
||||
[title] [varchar] (50) NULL ,
|
||||
[role] [varchar] (50) NULL ,
|
||||
[b_day] [datetime] NULL ,
|
||||
[descr] [varchar] (500) NULL
|
||||
[vcard] [text] NOT NULL
|
||||
) ON [PRIMARY]
|
||||
GO
|
||||
|
||||
CREATE TABLE [dbo].[vcard_search] (
|
||||
[username] [varchar] (250) NOT NULL ,
|
||||
[lusername] [varchar] (250) NOT NULL ,
|
||||
[fn] [text] NOT NULL ,
|
||||
[lfn] [varchar] (250) NOT NULL ,
|
||||
[family] [text] NOT NULL ,
|
||||
[lfamily] [varchar] (250) NOT NULL ,
|
||||
[given] [text] NOT NULL ,
|
||||
[lgiven] [varchar] (250) NOT NULL ,
|
||||
[middle] [text] NOT NULL ,
|
||||
[lmiddle] [varchar] (250) NOT NULL ,
|
||||
[nickname] [text] NOT NULL ,
|
||||
[lnickname] [varchar] (250) NOT NULL ,
|
||||
[bday] [text] NOT NULL ,
|
||||
[lbday] [varchar] (250) NOT NULL ,
|
||||
[ctry] [text] NOT NULL ,
|
||||
[lctry] [varchar] (250) NOT NULL ,
|
||||
[locality] [text] NOT NULL ,
|
||||
[llocality] [varchar] (250) NOT NULL ,
|
||||
[email] [text] NOT NULL ,
|
||||
[lemail] [varchar] (250) NOT NULL ,
|
||||
[orgname] [text] NOT NULL ,
|
||||
[lorgname] [varchar] (250) NOT NULL ,
|
||||
[orgunit] [text] NOT NULL ,
|
||||
[lorgunit] [varchar] (250) NOT NULL
|
||||
) ON [PRIMARY]
|
||||
GO
|
||||
|
||||
@ -262,6 +276,31 @@ ALTER TABLE [dbo].[vcard] WITH NOCHECK ADD
|
||||
) WITH FILLFACTOR = 90 ON [PRIMARY]
|
||||
GO
|
||||
|
||||
|
||||
CREATE INDEX [IX_vcard_search_lfn] ON [dbo].[vcard_search]([lfn]) WITH FILLFACTOR = 90 ON [PRIMARY]
|
||||
GO
|
||||
CREATE INDEX [IX_vcard_search_lfamily] ON [dbo].[vcard_search]([lfamily]) WITH FILLFACTOR = 90 ON [PRIMARY]
|
||||
GO
|
||||
CREATE INDEX [IX_vcard_search_lgiven] ON [dbo].[vcard_search]([lgiven]) WITH FILLFACTOR = 90 ON [PRIMARY]
|
||||
GO
|
||||
CREATE INDEX [IX_vcard_search_lmiddle] ON [dbo].[vcard_search]([lmiddle]) WITH FILLFACTOR = 90 ON [PRIMARY]
|
||||
GO
|
||||
CREATE INDEX [IX_vcard_search_lnickname] ON [dbo].[vcard_search]([lnickname]) WITH FILLFACTOR = 90 ON [PRIMARY]
|
||||
GO
|
||||
CREATE INDEX [IX_vcard_search_lbday] ON [dbo].[vcard_search]([lbday]) WITH FILLFACTOR = 90 ON [PRIMARY]
|
||||
GO
|
||||
CREATE INDEX [IX_vcard_search_lctry] ON [dbo].[vcard_search]([lctry]) WITH FILLFACTOR = 90 ON [PRIMARY]
|
||||
GO
|
||||
CREATE INDEX [IX_vcard_search_llocality] ON [dbo].[vcard_search]([llocality]) WITH FILLFACTOR = 90 ON [PRIMARY]
|
||||
GO
|
||||
CREATE INDEX [IX_vcard_search_lemail] ON [dbo].[vcard_search]([lemail]) WITH FILLFACTOR = 90 ON [PRIMARY]
|
||||
GO
|
||||
CREATE INDEX [IX_vcard_search_lorgname] ON [dbo].[vcard_search]([lorgname]) WITH FILLFACTOR = 90 ON [PRIMARY]
|
||||
GO
|
||||
CREATE INDEX [IX_vcard_search_lorgunit] ON [dbo].[vcard_search]([lorgunit]) WITH FILLFACTOR = 90 ON [PRIMARY]
|
||||
GO
|
||||
|
||||
|
||||
CREATE CLUSTERED INDEX [IX_rosterusers_user] ON [dbo].[rosterusers]([username]) WITH FILLFACTOR = 90 ON [PRIMARY]
|
||||
GO
|
||||
|
||||
@ -1050,4 +1089,151 @@ END
|
||||
GO
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
/****** Object: StoredProcedure [dbo].[set_vcard] **/
|
||||
/** Set the user's vCard **/
|
||||
/******************************************************************/
|
||||
CREATE PROCEDURE [dbo].[set_vcard]
|
||||
@VCard varchar(8000),
|
||||
@Username varchar(250),
|
||||
@Lusername varchar(250),
|
||||
@Fn varchar(8000),
|
||||
@Lfn varchar(250),
|
||||
@Family varchar(8000),
|
||||
@Lfamily varchar(250),
|
||||
@Given varchar(8000),
|
||||
@Lgiven varchar(250),
|
||||
@Middle varchar(8000),
|
||||
@Lmiddle varchar(250),
|
||||
@Nickname varchar(8000),
|
||||
@Lnickname varchar(250),
|
||||
@Bday varchar(8000),
|
||||
@Lbday varchar(250),
|
||||
@Ctry varchar(8000),
|
||||
@Lctry varchar(250),
|
||||
@Locality varchar(8000),
|
||||
@Llocality varchar(250),
|
||||
@Email varchar(8000),
|
||||
@Lemail varchar(250),
|
||||
@Orgname varchar(8000),
|
||||
@Lorgname varchar(250),
|
||||
@Orgunit varchar(8000),
|
||||
@Lorgunit varchar(250)
|
||||
AS
|
||||
BEGIN
|
||||
IF EXISTS (SELECT username FROM vcard with (nolock) WHERE vcard.username = @Username)
|
||||
BEGIN
|
||||
UPDATE [vcard]
|
||||
SET [vcard].username = @LUsername,
|
||||
[vcard].vcard = @Vcard
|
||||
WHERE vcard.username = @LUsername;
|
||||
|
||||
UPDATE [vcard_search]
|
||||
SET [vcard_search].username = @Username,
|
||||
[vcard_search].lusername = @Lusername,
|
||||
[vcard_search].fn = @Fn,
|
||||
[vcard_search].lfn = @Lfn,
|
||||
[vcard_search].family = @Family,
|
||||
[vcard_search].lfamily = @Lfamily,
|
||||
[vcard_search].given = @Given,
|
||||
[vcard_search].lgiven = @Lgiven,
|
||||
[vcard_search].middle = @Middle,
|
||||
[vcard_search].lmiddle = @Lmiddle,
|
||||
[vcard_search].nickname = @Nickname,
|
||||
[vcard_search].lnickname = @Lnickname,
|
||||
[vcard_search].bday = @Bday,
|
||||
[vcard_search].lbday = @Lbday,
|
||||
[vcard_search].ctry = @Ctry,
|
||||
[vcard_search].lctry = @Lctry,
|
||||
[vcard_search].locality = @Locality,
|
||||
[vcard_search].llocality = @Llocality,
|
||||
[vcard_search].email = @Email,
|
||||
[vcard_search].lemail = @Lemail,
|
||||
[vcard_search].orgname = @Orgname,
|
||||
[vcard_search].lorgname = @Lorgname,
|
||||
[vcard_search].orgunit = @Orgunit,
|
||||
[vcard_search].lorgunit = @Lorgunit
|
||||
WHERE vcard_search.lusername = @LUsername;
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
INSERT INTO [vcard]
|
||||
( [vcard].username,
|
||||
[vcard].vcard
|
||||
)
|
||||
VALUES
|
||||
( @lUsername,
|
||||
@Vcard
|
||||
);
|
||||
|
||||
INSERT INTO [vcard_search]
|
||||
(
|
||||
[vcard_search].username ,
|
||||
[vcard_search].lusername ,
|
||||
[vcard_search].fn ,
|
||||
[vcard_search].lfn ,
|
||||
[vcard_search].family ,
|
||||
[vcard_search].lfamily ,
|
||||
[vcard_search].given ,
|
||||
[vcard_search].lgiven ,
|
||||
[vcard_search].middle ,
|
||||
[vcard_search].lmiddle ,
|
||||
[vcard_search].nickname,
|
||||
[vcard_search].lnickname,
|
||||
[vcard_search].bday,
|
||||
[vcard_search].lbday,
|
||||
[vcard_search].ctry,
|
||||
[vcard_search].lctry,
|
||||
[vcard_search].locality,
|
||||
[vcard_search].llocality,
|
||||
[vcard_search].email,
|
||||
[vcard_search].lemail,
|
||||
[vcard_search].orgname,
|
||||
[vcard_search].lorgname,
|
||||
[vcard_search].orgunit,
|
||||
[vcard_search].lorgunit
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
@Username,
|
||||
@Lusername,
|
||||
@Fn,
|
||||
@Lfn,
|
||||
@Family,
|
||||
@Lfamily,
|
||||
@Given,
|
||||
@Lgiven,
|
||||
@Middle,
|
||||
@Lmiddle,
|
||||
@Nickname,
|
||||
@Lnickname,
|
||||
@Bday,
|
||||
@Lbday,
|
||||
@Ctry,
|
||||
@Lctry,
|
||||
@Locality,
|
||||
@Llocality,
|
||||
@Email,
|
||||
@Lemail,
|
||||
@Orgname,
|
||||
@Lorgname,
|
||||
@Orgunit,
|
||||
@Lorgunit
|
||||
)
|
||||
END
|
||||
END
|
||||
GO
|
||||
|
||||
/******************************************************************/
|
||||
/****** Object: StoredProcedure [dbo].[get_vcard] **/
|
||||
/** Retrive the user's vCard **/
|
||||
/******************************************************************/
|
||||
CREATE PROCEDURE [dbo].[get_vcard]
|
||||
@Username varchar(250)
|
||||
AS
|
||||
BEGIN
|
||||
SELECT vcard.vcard as vcard
|
||||
FROM vcard WITH (NOLOCK)
|
||||
WHERE username=@Username;
|
||||
END
|
||||
GO
|
||||
|
@ -61,6 +61,8 @@
|
||||
set_private_data_sql/3,
|
||||
get_private_data/3,
|
||||
del_user_private_storage/2,
|
||||
set_vcard/26,
|
||||
get_vcard/2,
|
||||
escape/1,
|
||||
count_records_where/3]).
|
||||
|
||||
@ -327,11 +329,11 @@ update_roster_sql(Username, SJID, ItemVals, ItemGroups) ->
|
||||
" values (", ItemVals, ");"],
|
||||
["delete from rostergroups "
|
||||
" where username='", Username, "' "
|
||||
" and jid='", SJID, "';"],
|
||||
" and jid='", SJID, "';"]] ++
|
||||
[["insert into rostergroups("
|
||||
" username, jid, grp) "
|
||||
" values (", ItemGroup, ");"] ||
|
||||
ItemGroup <- ItemGroups]].
|
||||
ItemGroup <- ItemGroups].
|
||||
|
||||
roster_subscribe(_LServer, Username, SJID, ItemVals) ->
|
||||
ejabberd_odbc:sql_query_t(
|
||||
@ -378,6 +380,42 @@ del_user_private_storage(LServer, Username) ->
|
||||
LServer,
|
||||
["delete from private_storage where username='", Username, "';"]).
|
||||
|
||||
|
||||
set_vcard(LServer, LUsername, SBDay, SCTRY, SEMail, SFN, SFamily, SGiven,
|
||||
SLBDay, SLCTRY, SLEMail, SLFN, SLFamily, SLGiven, SLLocality,
|
||||
SLMiddle, SLNickname, SLOrgName, SLOrgUnit, SLocality, SMiddle,
|
||||
SNickname, SOrgName, SOrgUnit, SVCARD, Username) ->
|
||||
ejabberd_odbc:sql_transaction(
|
||||
LServer,
|
||||
[["delete from vcard where username='", LUsername, "';"],
|
||||
["insert into vcard(username, vcard) "
|
||||
"values ('", LUsername, "', '", SVCARD, "');"],
|
||||
["delete from vcard_search where lusername='", LUsername, "';"],
|
||||
["insert into vcard_search("
|
||||
" username, lusername, fn, lfn, family, lfamily,"
|
||||
" given, lgiven, middle, lmiddle, nickname, lnickname,"
|
||||
" bday, lbday, ctry, lctry, locality, llocality,"
|
||||
" email, lemail, orgname, lorgname, orgunit, lorgunit)"
|
||||
"values (",
|
||||
" '", Username, "', '", LUsername, "',"
|
||||
" '", SFN, "', '", SLFN, "',"
|
||||
" '", SFamily, "', '", SLFamily, "',"
|
||||
" '", SGiven, "', '", SLGiven, "',"
|
||||
" '", SMiddle, "', '", SLMiddle, "',"
|
||||
" '", SNickname, "', '", SLNickname, "',"
|
||||
" '", SBDay, "', '", SLBDay, "',"
|
||||
" '", SCTRY, "', '", SLCTRY, "',"
|
||||
" '", SLocality, "', '", SLLocality, "',"
|
||||
" '", SEMail, "', '", SLEMail, "',"
|
||||
" '", SOrgName, "', '", SLOrgName, "',"
|
||||
" '", SOrgUnit, "', '", SLOrgUnit, "');"]]).
|
||||
|
||||
get_vcard(LServer, Username) ->
|
||||
ejabberd_odbc:sql_query(
|
||||
LServer,
|
||||
["select vcard from vcard "
|
||||
"where username='", Username, "';"]).
|
||||
|
||||
%% Characters to escape
|
||||
escape($\0) -> "\\0";
|
||||
escape($\n) -> "\\n";
|
||||
@ -597,6 +635,25 @@ del_user_private_storage(LServer, Username) ->
|
||||
LServer,
|
||||
["EXECUTE dbo.del_user_storage '", Username, "'"]).
|
||||
|
||||
set_vcard(LServer, LUsername, SBDay, SCTRY, SEMail, SFN, SFamily, SGiven,
|
||||
SLBDay, SLCTRY, SLEMail, SLFN, SLFamily, SLGiven, SLLocality,
|
||||
SLMiddle, SLNickname, SLOrgName, SLOrgUnit, SLocality, SMiddle,
|
||||
SNickname, SOrgName, SOrgUnit, SVCARD, Username) ->
|
||||
ejabberd_odbc:sql_query(
|
||||
LServer,
|
||||
["EXECUTE dbo.set_vcard '", SVCARD, "' , '", Username, "' , '", LUsername, "' , '",
|
||||
SFN, "' , '", SLFN, "' , '", SFamily, "' , '", SLFamily, "' , '",
|
||||
SGiven, "' , '", SLGiven, "' , '", SMiddle, "' , '", SLMiddle, "' , '",
|
||||
SNickname, "' , '", SLNickname, "' , '", SBDay, "' , '", SLBDay, "' , '",
|
||||
SCTRY, "' , '", SLCTRY, "' , '", SLocality, "' , '", SLLocality, "' , '",
|
||||
SEMail, "' , '", SLEMail, "' , '", SOrgName, "' , '", SLOrgName, "' , '",
|
||||
SOrgUnit, "' , '", SLOrgUnit, "'"]).
|
||||
|
||||
get_vcard(LServer, Username) ->
|
||||
ejabberd_odbc:sql_query(
|
||||
LServer,
|
||||
["EXECUTE dbo.get_vcard '", Username, "'"]).
|
||||
|
||||
%% Characters to escape
|
||||
escape($\0) -> "\\0";
|
||||
escape($\t) -> "\\t";
|
||||
|
@ -4,8 +4,7 @@ include ..\Makefile.inc
|
||||
EFLAGS = -I .. -pz ..
|
||||
|
||||
OUTDIR = ..
|
||||
SOURCES = $(wildcard *.erl)
|
||||
BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
|
||||
BEAMS = ..\stringprep.beam ..\stringprep_sup.beam
|
||||
|
||||
SOURCE = stringprep_drv.c
|
||||
AUXIL = uni_data.c uni_norm.c
|
||||
|
@ -4,8 +4,7 @@ include ..\Makefile.inc
|
||||
EFLAGS = -I .. -pz ..
|
||||
|
||||
OUTDIR = ..
|
||||
SOURCES = $(wildcard *.erl)
|
||||
BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
|
||||
BEAMS = ..\tls.beam
|
||||
|
||||
SOURCE = tls_drv.c
|
||||
OBJECT = tls_drv.o
|
||||
|
@ -4,8 +4,7 @@ include ..\Makefile.inc
|
||||
EFLAGS = -I .. -pz ..
|
||||
|
||||
OUTDIR = ..
|
||||
SOURCES = $(wildcard *.erl)
|
||||
BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
|
||||
BEAMS = ..\ejabberd_http.beam ..\ejabberd_http_bind.beam ..\ejabberd_http_poll.beam ..\ejabberd_web.beam ..\ejabberd_web_admin.beam ..\mod_http_bind.beam ..\mod_http_fileserver.beam
|
||||
|
||||
ALL : $(BEAMS)
|
||||
|
||||
@ -21,5 +20,14 @@ $(OUTDIR)\ejabberd_web.beam : ejabberd_web.erl
|
||||
$(OUTDIR)\ejabberd_web_admin.beam : ejabberd_web_admin.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_web_admin.erl
|
||||
|
||||
$(OUTDIR)\ejabberd_http_bind.beam : ejabberd_http_bind.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_http_bind.erl
|
||||
|
||||
$(OUTDIR)\ejabberd_http_poll.beam : ejabberd_http_poll.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_http_poll.erl
|
||||
|
||||
$(OUTDIR)\mod_http_bind.beam : mod_http_bind.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) mod_http_bind.erl
|
||||
|
||||
$(OUTDIR)\mod_http_fileserver.beam : mod_http_fileserver.erl
|
||||
erlc -W $(EFLAGS) -o $(OUTDIR) mod_http_fileserver.erl
|
||||
|
Loading…
Reference in New Issue
Block a user