]> granicus.if.org Git - ejabberd/commitdiff
Simplify MSSQL configuration
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Sun, 13 Sep 2015 14:41:54 +0000 (17:41 +0300)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Sun, 13 Sep 2015 15:34:10 +0000 (18:34 +0300)
src/ejabberd_odbc.erl
src/ejabberd_odbc_sup.erl
src/ejabberd_rdbms.erl
src/odbc_queries.erl

index 5cbd3e931d40c1922df5f38819476c85edb97348..df49d0e8ba7ca7f0663c40689cb53290db5a88e8 100644 (file)
         sqlite_file/1,
          encode_term/1,
          decode_term/1,
+        odbc_config/0,
+        freetds_config/0,
+        odbcinst_config/0,
+        init_mssql/1,
         keep_alive/1]).
 
 %% gen_fsm callbacks
@@ -62,7 +66,7 @@
 
 -record(state,
        {db_ref = self()                     :: pid(),
-         db_type = odbc                      :: pgsql | mysql | sqlite | odbc,
+         db_type = odbc                      :: pgsql | mysql | sqlite | odbc | mssql,
          start_interval = 0                  :: non_neg_integer(),
          host = <<"">>                       :: binary(),
         max_pending_requests_len            :: non_neg_integer(),
@@ -78,6 +82,8 @@
 
 -define(MYSQL_PORT, 3306).
 
+-define(MSSQL_PORT, 1433).
+
 -define(MAX_TRANSACTION_RESTARTS, 10).
 
 -define(TRANSACTION_TIMEOUT, 60000).
@@ -665,6 +671,7 @@ db_opts(Host) ->
                                       fun(mysql) -> mysql;
                                          (pgsql) -> pgsql;
                                          (sqlite) -> sqlite;
+                                        (mssql) -> mssql;
                                          (odbc) -> odbc
                                       end, odbc),
     Server = ejabberd_config:get_option({odbc_server, Host},
@@ -680,6 +687,7 @@ db_opts(Host) ->
                      {odbc_port, Host},
                      fun(P) when is_integer(P), P > 0, P < 65536 -> P end,
                      case Type of
+                        mssql -> ?MSSQL_PORT;
                          mysql -> ?MYSQL_PORT;
                          pgsql -> ?PGSQL_PORT
                      end),
@@ -692,9 +700,96 @@ db_opts(Host) ->
             Pass = ejabberd_config:get_option({odbc_password, Host},
                                               fun iolist_to_binary/1,
                                               <<"">>),
+           case Type of
+               mssql ->
+                   Username = get_mssql_user(Server, User),
+                   [odbc, <<"DSN=", Host/binary, ";UID=", Username/binary,
+                            ";PWD=", Pass/binary>>];
+               _ ->
             [Type, Server, Port, DB, User, Pass]
+           end
+    end.
+
+init_mssql(Host) ->
+    Server = ejabberd_config:get_option({odbc_server, Host},
+                                        fun iolist_to_binary/1,
+                                        <<"localhost">>),
+    Port = ejabberd_config:get_option(
+            {odbc_port, Host},
+            fun(P) when is_integer(P), P > 0, P < 65536 -> P end,
+            ?MSSQL_PORT),
+    DB = ejabberd_config:get_option({odbc_database, Host},
+                                   fun iolist_to_binary/1,
+                                   <<"ejabberd">>),
+    FreeTDS = io_lib:fwrite("[~s]~n"
+                           "\thost = ~s~n"
+                           "\tport = ~p~n"
+                           "\ttds version = 7.1~n",
+                           [Host, Server, Port]),
+    ODBCINST = io_lib:fwrite("[freetds]~n"
+                            "Description = MSSQL connection~n"
+                            "Driver = libtdsodbc.so~n"
+                            "Setup = libtdsS.so~n"
+                            "UsageCount = 1~n"
+                            "FileUsage = 1~n", []),
+    ODBCINI = io_lib:fwrite("[~s]~n"
+                           "Description = MS SQL~n"
+                           "Driver = freetds~n"
+                           "Servername = ~s~n"
+                           "Database = ~s~n"
+                           "Port = ~p~n",
+                           [Host, Host, DB, Port]),
+    ?DEBUG("~s:~n~s", [freetds_config(), FreeTDS]),
+    ?DEBUG("~s:~n~s", [odbcinst_config(), ODBCINST]),
+    ?DEBUG("~s:~n~s", [odbc_config(), ODBCINI]),
+    case filelib:ensure_dir(freetds_config()) of
+       ok ->
+           try
+               ok = file:write_file(freetds_config(), FreeTDS, [append]),
+               ok = file:write_file(odbcinst_config(), ODBCINST),
+               ok = file:write_file(odbc_config(), ODBCINI, [append]),
+               os:putenv("ODBCSYSINI", tmp_dir()),
+               os:putenv("FREETDS", freetds_config()),
+               os:putenv("FREETDSCONF", freetds_config()),
+               ok
+           catch error:{badmatch, {error, Reason} = Err} ->
+                   ?ERROR_MSG("failed to create temporary files in ~s: ~s",
+                              [tmp_dir(), file:format_error(Reason)]),
+                   Err
+           end;
+       {error, Reason} = Err ->
+           ?ERROR_MSG("failed to create temporary directory ~s: ~s",
+                      [tmp_dir(), file:format_error(Reason)]),
+           Err
     end.
 
+get_mssql_user(Server, User) ->
+    HostName = case inet_parse:address(binary_to_list(Server)) of
+                  {ok, _} ->
+                      Server;
+                  {error, _} ->
+                      hd(str:tokens(Server, <<".">>))
+              end,
+    UserName = case str:chr(User, $@) of
+                  0 ->
+                      <<User/binary, $@, HostName/binary>>;
+                  _ ->
+                      User
+              end,
+    UserName.
+
+tmp_dir() ->
+    filename:join(["/tmp", "ejabberd"]).
+
+odbc_config() ->
+    filename:join(tmp_dir(), "odbc.ini").
+
+freetds_config() ->
+    filename:join(tmp_dir(), "freetds.conf").
+
+odbcinst_config() ->
+    filename:join(tmp_dir(), "odbcinst.ini").
+
 max_fsm_queue() ->
     ejabberd_config:get_option(
       max_fsm_queue,
@@ -719,6 +814,7 @@ opt_type(odbc_type) ->
     fun (mysql) -> mysql;
        (pgsql) -> pgsql;
        (sqlite) -> sqlite;
+       (mssql) -> mssql;
        (odbc) -> odbc
     end;
 opt_type(odbc_username) -> fun iolist_to_binary/1;
index 4a1498964d5186d7f142f15dedbab8334f2972b1..fa44853487c5c09529c955bdf1b45c84839d411b 100644 (file)
@@ -73,11 +73,14 @@ init([Host]) ->
                                       fun(mysql) -> mysql;
                                          (pgsql) -> pgsql;
                                          (sqlite) -> sqlite;
+                                        (mssql) -> mssql;
                                          (odbc) -> odbc
                                       end, odbc),
     case Type of
         sqlite ->
             check_sqlite_db(Host);
+       mssql ->
+           ejabberd_odbc:init_mssql(Host);
         _ ->
             ok
     end,
@@ -216,6 +219,7 @@ opt_type(odbc_type) ->
     fun (mysql) -> mysql;
        (pgsql) -> pgsql;
        (sqlite) -> sqlite;
+       (mssql) -> mssql;
        (odbc) -> odbc
     end;
 opt_type(_) ->
index 23f1a857e1a4d407d94d5fed3a2170f1d434a3ca..f4bfbd6000c3dcef4a8cb4cd65c2c2c8bb2e8f3d 100644 (file)
@@ -35,6 +35,9 @@
 -include("logger.hrl").
 
 start() ->
+    file:delete(ejabberd_odbc:freetds_config()),
+    file:delete(ejabberd_odbc:odbc_config()),
+    file:delete(ejabberd_odbc:odbcinst_config()),
     case lists:any(fun(H) -> needs_odbc(H) /= false end,
                    ?MYHOSTS) of
         true ->
@@ -77,11 +80,13 @@ needs_odbc(Host) ->
                                     fun(mysql) -> mysql;
                                        (pgsql) -> pgsql;
                                        (sqlite) -> sqlite;
+                                      (mssql) -> mssql;
                                        (odbc) -> odbc
                                     end, undefined) of
         mysql -> {true, p1_mysql};
         pgsql -> {true, p1_pgsql};
         sqlite -> {true, sqlite3};
+       mssql -> {true, odbc};
         odbc -> {true, odbc};
         undefined -> false
     end.
@@ -90,6 +95,7 @@ opt_type(odbc_type) ->
     fun (mysql) -> mysql;
        (pgsql) -> pgsql;
        (sqlite) -> sqlite;
+       (mssql) -> mssql;
        (odbc) -> odbc
     end;
 opt_type(_) -> [odbc_type].
index b90c2f2d554b3f1fcb434b49f9cf86d6be9e81b1..e33af54e2583013b8aea4e2f5bcba012b3127aae 100644 (file)
@@ -651,6 +651,7 @@ opt_type(odbc_type) ->
     fun (pgsql) -> pgsql;
        (mysql) -> mysql;
        (sqlite) -> sqlite;
+       (mssql) -> mssql;
        (odbc) -> odbc
     end;
 opt_type(pgsql_users_number_estimate) ->