From 3e4163cbfec2842738201ef76afd8bf07627550a Mon Sep 17 00:00:00 2001
From: Dmitriy Simushev <simushevds@ossg.ru>
Date: Fri, 13 Jul 2012 12:56:50 +0000
Subject: [PATCH] Replace database functions with Database class methods

---
 src/messenger/webim/b.php                     |   6 +-
 src/messenger/webim/client.php                |  28 +-
 src/messenger/webim/install/dbinfo.php        |   7 +-
 src/messenger/webim/leavemessage.php          |  16 +-
 src/messenger/webim/libs/canned.php           |  63 +--
 src/messenger/webim/libs/chat.php             | 309 ++++++++------
 src/messenger/webim/libs/common.php           | 131 +-----
 src/messenger/webim/libs/getcode.php          |   4 +-
 src/messenger/webim/libs/groups.php           |  45 +-
 src/messenger/webim/libs/invitation.php       |  72 ++--
 src/messenger/webim/libs/notify.php           |   2 +-
 src/messenger/webim/libs/operator.php         | 400 ++++++++++--------
 src/messenger/webim/libs/pagination.php       |  38 +-
 src/messenger/webim/libs/settings.php         |  11 +-
 src/messenger/webim/libs/track.php            | 120 +++---
 src/messenger/webim/mail.php                  |   4 +-
 src/messenger/webim/operator/ban.php          |  48 ++-
 src/messenger/webim/operator/blocked.php      |  12 +-
 src/messenger/webim/operator/canned.php       |   9 +-
 src/messenger/webim/operator/group.php        | 105 +++--
 src/messenger/webim/operator/groupmembers.php |  37 +-
 src/messenger/webim/operator/groups.php       |  13 +-
 src/messenger/webim/operator/history.php      |  54 +--
 src/messenger/webim/operator/index.php        |   6 +-
 .../webim/operator/invitationstate.php        |   4 +-
 src/messenger/webim/operator/invite.php       |   4 +-
 src/messenger/webim/operator/operators.php    |  22 +-
 src/messenger/webim/operator/opgroups.php     |  19 +-
 src/messenger/webim/operator/permissions.php  |  11 +-
 src/messenger/webim/operator/redirect.php     |  24 +-
 src/messenger/webim/operator/resetpwd.php     |  10 +-
 src/messenger/webim/operator/restore.php      |  12 +-
 src/messenger/webim/operator/statistics.php   |  62 ++-
 .../webim/operator/threadprocessor.php        |  19 +-
 src/messenger/webim/operator/tracked.php      |   8 +-
 src/messenger/webim/operator/update.php       | 132 +++---
 src/messenger/webim/operator/userhistory.php  |  22 +-
 src/messenger/webim/operator/users.php        |   6 +-
 src/messenger/webim/request.php               |  11 +-
 src/messenger/webim/thread.php                |   6 +-
 40 files changed, 1003 insertions(+), 909 deletions(-)
 mode change 100755 => 100644 src/messenger/webim/libs/operator.php

diff --git a/src/messenger/webim/b.php b/src/messenger/webim/b.php
index fc8faf39..93610209 100644
--- a/src/messenger/webim/b.php
+++ b/src/messenger/webim/b.php
@@ -22,13 +22,11 @@ require_once('libs/groups.php');
 
 $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : "";
 if($referer && isset($_SESSION['threadid'])) {
-	$link = connect();
-	$thread = thread_by_id_($_SESSION['threadid'], $link);
+	$thread = thread_by_id($_SESSION['threadid']);
     if ($thread && $thread['istate'] != $state_closed) {
         $msg = getstring2_("chat.client.visited.page", array($referer), $thread['locale']);
-        post_message_($thread['threadid'], $kind_for_agent,$msg,$link);
+        post_message_($thread['threadid'], $kind_for_agent,$msg);
     }
-    close_connection($link);
 }
 
 $image = verifyparam(isset($_GET['image']) ? "image" : "i", "/^\w+$/", "webim");
diff --git a/src/messenger/webim/client.php b/src/messenger/webim/client.php
index b12f4aaf..210c988d 100644
--- a/src/messenger/webim/client.php
+++ b/src/messenger/webim/client.php
@@ -94,50 +94,46 @@ if( !isset($_GET['token']) || !isset($_GET['thread']) ) {
 			exit;
 		}
 
-		$link = connect();
-		$invitation_state = invitation_state($_SESSION['visitorid'], $link);
+		$invitation_state = invitation_state($_SESSION['visitorid']);
 		$visitor_is_invited = $settings['enabletracking'] && $invitation_state['invited'] && !$invitation_state['threadid'];
 		if($settings['enablepresurvey'] == '1' && !(isset($_POST['survey']) && $_POST['survey'] == 'on') && !$visitor_is_invited) {
 			$page = array();
 			setup_logo($group);
 			setup_survey($visitor['name'], $email, $groupid, $info, $referrer);
 			expand("styles/dialogs", getchatstyle(), "survey.tpl");
-			close_connection($link);
 			exit;
 		}
 
 		$remoteHost = get_remote_host();
 		$userbrowser = $_SERVER['HTTP_USER_AGENT'];
 
-		if(!check_connections_from_remote($remoteHost, $link)) {
-			close_connection($link);
+		if(!check_connections_from_remote($remoteHost)) {
 			die("number of connections from your IP is exceeded, try again later");
 		}
-		$thread = create_thread($groupid,$visitor['name'], $remoteHost, $referrer,$current_locale,$visitor['id'], $userbrowser,$state_loading,$link);
+		$thread = create_thread($groupid,$visitor['name'], $remoteHost, $referrer,$current_locale,$visitor['id'], $userbrowser,$state_loading);
 		$_SESSION['threadid'] = $thread['threadid'];
 
-		$operator = invitation_accept($_SESSION['visitorid'], $thread['threadid'], $link);
+		$operator = invitation_accept($_SESSION['visitorid'], $thread['threadid']);
 		if ($operator) {
-		    $operator = operator_by_id_($operator, $link);
+		    $operator = operator_by_id($operator);
 		    $operatorName = ($current_locale == $home_locale) ? $operator['vclocalename'] : $operator['vccommonname'];
-		    post_message_($thread['threadid'], $kind_for_agent, getstring2('chat.visitor.invitation.accepted', array($operatorName)), $link);
+		    post_message_($thread['threadid'], $kind_for_agent, getstring2('chat.visitor.invitation.accepted', array($operatorName)));
 		}
 
 		if( $referrer ) {
-			post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.came.from',array($referrer)),$link);
+			post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.came.from',array($referrer)));
 		}
-		post_message_($thread['threadid'],$kind_info,getstring('chat.wait'),$link);
+		post_message_($thread['threadid'],$kind_info,getstring('chat.wait'));
 		if($email) {
-			post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.visitor.email',array($email)),$link);
+			post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.visitor.email',array($email)));
 		}
 		if($info) {
-			post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.visitor.info',array($info)),$link);
+			post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.visitor.info',array($info)));
 		}
 		if($firstmessage) {
-			$postedid = post_message_($thread['threadid'],$kind_user,$firstmessage,$link,$visitor['name']);
-			commit_thread( $thread['threadid'], array('shownmessageid' => $postedid), $link);
+			$postedid = post_message_($thread['threadid'],$kind_user,$firstmessage,$visitor['name']);
+			commit_thread( $thread['threadid'], array('shownmessageid' => $postedid));
 		}
-		close_connection($link);
 	}
 	$threadid = $thread['threadid'];
 	$token = $thread['ltoken'];
diff --git a/src/messenger/webim/install/dbinfo.php b/src/messenger/webim/install/dbinfo.php
index ee4ac0b6..79a2208e 100644
--- a/src/messenger/webim/install/dbinfo.php
+++ b/src/messenger/webim/install/dbinfo.php
@@ -231,9 +231,12 @@ function create_table($id, $link)
 	mysql_query($query, $link) or show_install_err(' Query failed: ' . mysql_error($link));
 
 	if ($id == "${mysqlprefix}chatoperator") {
-		create_operator_("admin", "", "", "Administrator", "Administrator", "", $link);
+		create_operator("admin", "", "", "Administrator", "Administrator", "");
 	} else if ($id == "${mysqlprefix}chatrevision") {
-		perform_query("INSERT INTO ${mysqlprefix}chatrevision VALUES (1)", $link);
+		$result = mysql_query("INSERT INTO ${mysqlprefix}chatrevision VALUES (1)", $link);
+		if (! $result) {
+			die(' Query failed: ' . mysql_error($link));
+		}
 	}
 }
 
diff --git a/src/messenger/webim/leavemessage.php b/src/messenger/webim/leavemessage.php
index 0a516dd5..94da339d 100644
--- a/src/messenger/webim/leavemessage.php
+++ b/src/messenger/webim/leavemessage.php
@@ -30,19 +30,17 @@ function store_message($name, $email, $info, $message,$groupid,$referrer) {
 	$remoteHost = get_remote_host();
 	$userbrowser = $_SERVER['HTTP_USER_AGENT'];
 	$visitor = visitor_from_request();
-	$link = connect();
-	$thread = create_thread($groupid,$name,$remoteHost,$referrer,$current_locale,$visitor['id'], $userbrowser,$state_left,$link);
+	$thread = create_thread($groupid,$name,$remoteHost,$referrer,$current_locale,$visitor['id'], $userbrowser,$state_left);
 	if( $referrer ) {
-		post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.came.from',array($referrer)),$link);
+		post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.came.from',array($referrer)));
 	}
 	if($email) {
-		post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.visitor.email',array($email)),$link);
+		post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.visitor.email',array($email)));
 	}
 	if($info) {
-		post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.visitor.info',array($info)),$link);
+		post_message_($thread['threadid'],$kind_for_agent,getstring2('chat.visitor.info',array($info)));
 	}
-	post_message_($thread['threadid'],$kind_user,$message,$link,$name);
-	close_connection($link);
+	post_message_($thread['threadid'],$kind_user,$message,$name);
 }
 
 $groupid = "";
@@ -121,9 +119,7 @@ if (empty($inbox_mail)) {
 }
 
 if($inbox_mail) {
-	$link = connect();
-	webim_mail($inbox_mail, $email, $subject, $body, $link);
-	close_connection($link);
+	webim_mail($inbox_mail, $email, $subject, $body);
 }
 
 setup_logo($group);
diff --git a/src/messenger/webim/libs/canned.php b/src/messenger/webim/libs/canned.php
index 309adc06..603e1678 100644
--- a/src/messenger/webim/libs/canned.php
+++ b/src/messenger/webim/libs/canned.php
@@ -17,47 +17,54 @@
 
 function load_canned_messages($locale, $groupid)
 {
-	global $mysqlprefix;
-	$link = connect();
-	$query = "select id, vctitle, vcvalue from ${mysqlprefix}chatresponses " .
-			 "where locale = '" . $locale . "' AND (" .
-			 ($groupid
-					 ? "groupid = $groupid"
-					 : "groupid is NULL OR groupid = 0") .
-			 ") order by vcvalue";
-	$result = select_multi_assoc($query, $link);
-	close_connection($link);
-	return $result;
+	$db = Database::getInstance();
+	$values = array(':locale' => $locale);
+	if ($groupid) {
+		$values[':groupid'] = $groupid;
+	}
+	return $db->query(
+		"select id, vctitle, vcvalue from {chatresponses} " .
+		"where locale = :locale AND (" .
+		($groupid ? "groupid = :groupid" : "groupid is NULL OR groupid = 0") .
+		") order by vcvalue",
+		$values,
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
 }
 
 function load_canned_message($key)
 {
-	global $mysqlprefix;
-	$link = connect();
-	$result = select_one_row("select vctitle, vcvalue from ${mysqlprefix}chatresponses where id = $key", $link);
-	close_connection($link);
+	$db = Database::getInstance();
+	$result = $db->query(
+		"select vctitle, vcvalue from {chatresponses} where id = ?",
+		array($key),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 	return $result ? $result : null;
 }
 
 function save_canned_message($key, $title, $message)
 {
-	global $mysqlprefix;
-	$link = connect();
-	perform_query("update ${mysqlprefix}chatresponses set vcvalue = '" . db_escape_string($message, $link) . "', " .
-				"vctitle = '" . db_escape_string($title, $link) . "' " .
-				"where id = $key", $link);
-	close_connection($link);
+	$db = Database::getInstance();
+	$db->query(
+		"update {chatresponses} set vcvalue = ?, vctitle = ? where id = ?",
+		array($message, $title, $key)
+	);
 }
 
 function add_canned_message($locale, $groupid, $title, $message)
 {
-	global $mysqlprefix;
-	$link = connect();
-	perform_query("insert into ${mysqlprefix}chatresponses (locale,groupid,vctitle,vcvalue) values ('$locale'," .
-				($groupid ? "$groupid, " : "null, ") .
-				"'" . db_escape_string($title, $link) . "', " .
-				"'" . db_escape_string($message, $link) . "')", $link);
-	close_connection($link);
+	$db = Database::getInstance();
+	$db->query(
+		"insert into {chatresponses} (locale,groupid,vctitle,vcvalue) " .
+		"values (?, ?, ?, ?)",
+		array(
+			$locale,
+			($groupid ? $groupid : "null"),
+			$title,
+			$message
+		)
+	);
 }
 
 ?>
\ No newline at end of file
diff --git a/src/messenger/webim/libs/chat.php b/src/messenger/webim/libs/chat.php
index 64fde723..83702360 100644
--- a/src/messenger/webim/libs/chat.php
+++ b/src/messenger/webim/libs/chat.php
@@ -50,36 +50,40 @@ function next_token()
 	return rand(99999, 99999999);
 }
 
-function next_revision($link)
+function next_revision()
 {
-	global $mysqlprefix;
-	perform_query("update ${mysqlprefix}chatrevision set id=LAST_INSERT_ID(id+1)", $link);
-	$val = db_insert_id($link);
+	$db = Database::getInstance();
+	$db->query("update {chatrevision} set id=LAST_INSERT_ID(id+1)");
+	$val = $db->insertedId();
 	return $val;
 }
 
-function post_message_($threadid, $kind, $message, $link, $from = null, $utime = null, $opid = null)
+/**
+ * @todo Think about post_message_ and post_message diffrence
+ */
+function post_message_($threadid, $kind, $message, $from = null, $utime = null, $opid = null)
 {
-	global $mysqlprefix;
-	$query = sprintf(
-		"insert into ${mysqlprefix}chatmessage (threadid,ikind,tmessage,tname,agentId,dtmcreated) values (%s, %s,'%s',%s,%s,%s)",
+	$db = Database::getInstance();
+	$query = "insert into {chatmessage} " .
+		"(threadid,ikind,tmessage,tname,agentId,dtmcreated) " .
+		"values (?,?,?,?,?,".($utime?"FROM_UNIXTIME(?)":"CURRENT_TIMESTAMP").")";
+	 $values = array(
 		$threadid,
 		$kind,
-		db_escape_string($message, $link),
-		$from ? "'" . db_escape_string($from, $link) . "'" : "null",
-		$opid ? $opid : "0",
-		$utime ? "FROM_UNIXTIME($utime)" : "CURRENT_TIMESTAMP");
-
-	perform_query($query, $link);
-	return db_insert_id($link);
+		$message,
+		($from ? $from : "null"),
+		($opid ? $opid : 0)
+	);
+	if ($utime) {
+		$values[] = $utime;
+	}
+	 $db->query($query, $values);
+	return $db->insertedId();
 }
 
 function post_message($threadid, $kind, $message, $from = null, $agentid = null)
 {
-	$link = connect();
-	$id = post_message_($threadid, $kind, $message, $link, $from, null, $agentid);
-	close_connection($link);
-	return $id;
+	return post_message_($threadid, $kind, $message, $from, null, $agentid);
 }
 
 function prepare_html_message($text, $allow_formating)
@@ -127,16 +131,23 @@ function message_to_text($msg)
 
 function get_messages($threadid, $meth, $isuser, &$lastid)
 {
-	global $kind_for_agent, $kind_avatar, $webim_encoding, $mysqlprefix;
-	$link = connect();
+	global $kind_for_agent, $kind_avatar, $webim_encoding;
+	$db = Database::getInstance();
 
-	$query = sprintf(
-		"select messageid,ikind,unix_timestamp(dtmcreated) as created,tname,tmessage from ${mysqlprefix}chatmessage " .
-		"where threadid = %s and messageid > %s %s order by messageid",
-		$threadid, $lastid, $isuser ? "and ikind <> $kind_for_agent" : "");
+	$msgs = $db->query(
+		"select messageid,ikind,unix_timestamp(dtmcreated) as created,tname,tmessage from {chatmessage} " .
+		"where threadid = :threadid and messageid > :lastid " .
+		($isuser ? "and ikind <> {$kind_for_agent} " : "") .
+		"order by messageid",
+		array(
+			':threadid' => $threadid,
+			':lastid' => $lastid,
+		),
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+		
+	);
 
 	$messages = array();
-	$msgs = select_multi_assoc($query, $link);
 	foreach ($msgs as $msg) {
 		$message = "";
 		if ($meth == 'xml') {
@@ -159,7 +170,6 @@ function get_messages($threadid, $meth, $isuser, &$lastid)
 		}
 	}
 
-	close_connection($link);
 	return $messages;
 }
 
@@ -355,15 +365,12 @@ function setup_groups_select($groupid, $markoffline)
 {
 	global $settings;
 
-	$link = connect();
-	$showgroups = ($groupid == '')?true:group_has_children($groupid, $link);
+	$showgroups = ($groupid == '')?true:group_has_children($groupid);
 	if (!$showgroups) {
-		close_connection($link);
 		return false;
 	}
 
-	$allgroups = get_groups($link, false);
-	close_connection($link);
+	$allgroups = get_groups(false);
 
 	if (empty($allgroups)) {
 		return false;
@@ -404,7 +411,7 @@ function setup_chatview_for_user($thread, $level)
 	global $page, $webimroot, $settings;
 	loadsettings();
 	$page = array();
-	if (! is_null($thread['groupid'])) {
+	if (! empty($thread['groupid'])) {
 		$group = group_by_id($thread['groupid']);
 		$group = get_top_level_group($group);
 	} else {
@@ -483,11 +490,9 @@ function setup_chatview_for_operator($thread, $operator)
 	$page['historyParams'] = array("userid" => "" . $thread['userid']);
 	$page['historyParamsLink'] = add_params($webimroot . "/operator/userhistory.php", $page['historyParams']);
 	if ($settings['enabletracking']) {
-	    $link = connect();
-	    $visitor = track_get_visitor_by_threadid($thread['threadid'], $link);
+	    $visitor = track_get_visitor_by_threadid($thread['threadid']);
 	    $page['trackedParams'] = array("visitor" => "" . $visitor['visitorid']);
 	    $page['trackedParamsLink'] = add_params($webimroot . "/operator/tracked.php", $page['trackedParams']);
-	    close_connection($link);
 	}
 	$predefinedres = "";
 	$canned_messages = load_canned_messages($thread['locale'], 0);
@@ -510,24 +515,29 @@ function setup_chatview_for_operator($thread, $operator)
 	$page['frequency'] = $settings['updatefrequency_chat'];
 }
 
-function update_thread_access($threadid, $params, $link)
+function update_thread_access($threadid, $params)
 {
-	global $mysqlprefix;
+	$db = Database::getInstance();
 	$clause = "";
+	$values = array();
 	foreach ($params as $k => $v) {
 		if (strlen($clause) > 0)
 			$clause .= ", ";
-		$clause .= $k . "=" . $v;
+		$clause .= $k . "=?";
+		$values[] = $v;
 	}
-	perform_query(
-		"update ${mysqlprefix}chatthread set $clause " .
-		"where threadid = $threadid", $link);
+	$values[] = $threadid;
+
+	$db->query(
+		"update {chatthread} set {$clause} where threadid = ?",
+		$values
+	);
 }
 
 function ping_thread($thread, $isuser, $istyping)
 {
 	global $kind_for_agent, $state_queue, $state_loading, $state_chatting, $state_waiting, $kind_conn, $connection_timeout;
-	$link = connect();
+
 	$params = array(($isuser ? "lastpinguser" : "lastpingagent") => "CURRENT_TIMESTAMP",
 					($isuser ? "userTyping" : "agentTyping") => ($istyping ? "1" : "0"));
 
@@ -536,8 +546,7 @@ function ping_thread($thread, $isuser, $istyping)
 
 	if ($thread['istate'] == $state_loading && $isuser) {
 		$params['istate'] = $state_queue;
-		commit_thread($thread['threadid'], $params, $link);
-		close_connection($link);
+		commit_thread($thread['threadid'], $params);
 		return;
 	}
 
@@ -545,161 +554,176 @@ function ping_thread($thread, $isuser, $istyping)
 		$params[$isuser ? "lastpingagent" : "lastpinguser"] = "0";
 		if (!$isuser) {
 			$message_to_post = getstring_("chat.status.user.dead", $thread['locale']);
-			post_message_($thread['threadid'], $kind_for_agent, $message_to_post, $link, null, $lastping + $connection_timeout);
+			post_message_($thread['threadid'], $kind_for_agent, $message_to_post, null, $lastping + $connection_timeout);
 		} else if ($thread['istate'] == $state_chatting) {
 
 			$message_to_post = getstring_("chat.status.operator.dead", $thread['locale']);
-			post_message_($thread['threadid'], $kind_conn, $message_to_post, $link, null, $lastping + $connection_timeout);
+			post_message_($thread['threadid'], $kind_conn, $message_to_post, null, $lastping + $connection_timeout);
 			$params['istate'] = $state_waiting;
 			$params['nextagent'] = 0;
-			commit_thread($thread['threadid'], $params, $link);
-			close_connection($link);
+			commit_thread($thread['threadid'], $params);
 			return;
 		}
 	}
 
-	update_thread_access($thread['threadid'], $params, $link);
-	close_connection($link);
+	update_thread_access($thread['threadid'], $params);
 }
 
-function commit_thread($threadid, $params, $link)
+function commit_thread($threadid, $params)
 {
-	global $mysqlprefix;
-	$query = "update ${mysqlprefix}chatthread t set lrevision = " . next_revision($link) . ", dtmmodified = CURRENT_TIMESTAMP";
-	foreach ($params as $k => $v) {
-		$query .= ", " . $k . "=" . $v;
-	}
-	$query .= " where threadid = $threadid";
+	$db = Database::getInstance();
 
-	perform_query($query, $link);
+	$query = "update {chatthread} t " .
+		"set lrevision = ?, dtmmodified = CURRENT_TIMESTAMP";
+		$values = array(next_revision());
+	foreach ($params as $k => $v) {
+		$query .= ", " . $k . "=?";
+		$values[] = $v;
+	}
+	$query .= " where threadid = ?";
+	$values[] = $threadid;
+
+	$db->query($query, $values);
 }
 
 function rename_user($thread, $newname)
 {
 	global $kind_events;
 
-	$link = connect();
-	commit_thread($thread['threadid'], array('userName' => "'" . db_escape_string($newname, $link) . "'"), $link);
+	commit_thread($thread['threadid'], array('userName' => $newname));
 
 	if ($thread['userName'] != $newname) {
 		post_message_($thread['threadid'], $kind_events,
-					  getstring2_("chat.status.user.changedname", array($thread['userName'], $newname), $thread['locale']), $link);
+					  getstring2_("chat.status.user.changedname", array($thread['userName'], $newname), $thread['locale']));
 	}
-	close_connection($link);
 }
 
 function close_thread($thread, $isuser)
 {
-	global $state_closed, $kind_events, $mysqlprefix;
+	global $state_closed, $kind_events;
 
-	$link = connect();
 	if ($thread['istate'] != $state_closed) {
-		commit_thread($thread['threadid'], array('istate' => $state_closed,
-												'messageCount' => "(SELECT COUNT(*) FROM ${mysqlprefix}chatmessage WHERE ${mysqlprefix}chatmessage.threadid = t.threadid AND ikind = 1)"), $link);
+		commit_thread(
+			$thread['threadid'],
+			array(
+				'istate' => $state_closed,
+				'messageCount' => "(SELECT COUNT(*) FROM {chatmessage} WHERE {chatmessage}.threadid = t.threadid AND ikind = 1)"
+			)
+		);
 	}
 
 	$message = $isuser ? getstring2_("chat.status.user.left", array($thread['userName']), $thread['locale'])
 			: getstring2_("chat.status.operator.left", array($thread['agentName']), $thread['locale']);
-	post_message_($thread['threadid'], $kind_events, $message, $link);
-	close_connection($link);
+	post_message_($thread['threadid'], $kind_events, $message);
 }
 
-function close_old_threads($link)
+function close_old_threads()
 {
-	global $state_closed, $state_left, $state_chatting, $mysqlprefix, $settings;
+	global $state_closed, $state_left, $state_chatting, $settings;
 	if ($settings['thread_lifetime'] == 0) {
 		return;
 	}
-	$next_revision = next_revision($link);
-	$query = "update ${mysqlprefix}chatthread set lrevision =  $next_revision, dtmmodified = CURRENT_TIMESTAMP, istate = $state_closed " .
-			"where istate <> $state_closed and istate <> $state_left and lastpingagent <> 0 and lastpinguser <> 0 and " .
-			"(ABS(UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(lastpinguser)) > " . $settings['thread_lifetime'] . " and " .
-			"ABS(UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(lastpingagent)) > " . $settings['thread_lifetime'] . ")";
 
-	perform_query($query, $link);
-}
+	$db = Database::getInstance();
 
-function close_old_threads($link)
-{
-	global $state_closed, $state_left, $state_chatting, $mysqlprefix, $settings;
-	if ($settings['thread_lifetime'] == 0) {
-		return;
-	}
-	$next_revision = next_revision($link);
-	$query = "update ${mysqlprefix}chatthread set lrevision =  $next_revision, dtmmodified = CURRENT_TIMESTAMP, istate = $state_closed " .
-			"where istate <> $state_closed and istate <> $state_left and lastpingagent <> 0 and lastpinguser <> 0 and " .
-			"(ABS(UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(lastpinguser)) > " . $settings['thread_lifetime'] . " and " .
-			"ABS(UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(lastpingagent)) > " . $settings['thread_lifetime'] . ")";
+	$query = "update {chatthread} set lrevision = :next_revision, " .
+		"dtmmodified = CURRENT_TIMESTAMP, istate = :state_closed " .
+		"where istate <> :state_closed and istate <> :state_left " .
+		"and lastpingagent <> 0 and lastpinguser <> 0 and " .
+		"(ABS(UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(lastpinguser)) > ".
+		":thread_lifetime and " .
+		"ABS(UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(lastpingagent)) > ".
+		":thread_lifetime)";
 
-	perform_query($query, $link);
-}
-
-function thread_by_id_($id, $link)
-{
-	global $mysqlprefix;
-	return select_one_row("select threadid,userName,agentName,agentId,lrevision,istate,ltoken,userTyping,agentTyping" .
-						  ",unix_timestamp(dtmmodified) as modified, unix_timestamp(dtmcreated) as created, unix_timestamp(dtmchatstarted) as chatstarted" .
-						  ",remote,referer,locale,unix_timestamp(lastpinguser) as lpuser,unix_timestamp(lastpingagent) as lpagent, unix_timestamp(CURRENT_TIMESTAMP) as current,nextagent,shownmessageid,userid,userAgent,groupid" .
-						  " from ${mysqlprefix}chatthread where threadid = " . $id, $link);
-}
-
-function ban_for_addr_($addr, $link)
-{
-	global $mysqlprefix;
-	return select_one_row("select banid,comment from ${mysqlprefix}chatban where unix_timestamp(dtmtill) > unix_timestamp(CURRENT_TIMESTAMP) AND address = '" . db_escape_string($addr, $link) . "'", $link);
+	$db->query(
+		$query,
+		array(
+			':next_revision' => next_revision(),
+			':state_closed' => $state_closed,
+			':state_left' => $state_left,
+			':thread_lifetime' => $settings['thread_lifetime']
+		)
+	);
 }
 
 function thread_by_id($id)
 {
-	$link = connect();
-	$thread = thread_by_id_($id, $link);
-	close_connection($link);
-	return $thread;
+	$db = Database::getInstance();
+	return $db->query(
+		"select threadid,userName,agentName,agentId,lrevision,istate,ltoken,userTyping, " .
+		"agentTyping,unix_timestamp(dtmmodified) as modified, " .
+		"unix_timestamp(dtmcreated) as created, " .
+		"unix_timestamp(dtmchatstarted) as chatstarted,remote,referer,locale," .
+		"unix_timestamp(lastpinguser) as lpuser,unix_timestamp(lastpingagent) as lpagent," .
+		"unix_timestamp(CURRENT_TIMESTAMP) as current,nextagent,shownmessageid,userid, " .
+		"userAgent,groupid from {chatthread} where threadid = ?",
+		array($id),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 }
 
-function create_thread($groupid, $username, $remoteHost, $referer, $lang, $userid, $userbrowser, $initialState, $link)
+function ban_for_addr($addr)
 {
-	global $mysqlprefix;
-	$query = sprintf(
-		"insert into ${mysqlprefix}chatthread (userName,userid,ltoken,remote,referer,lrevision,locale,userAgent,dtmcreated,dtmmodified,istate" . ($groupid ? ",groupid" : "") . ") values " .
-		"('%s','%s',%s,'%s','%s',%s,'%s','%s',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP,$initialState" . ($groupid ? ",$groupid" : "") . ")",
-		db_escape_string($username, $link),
-		db_escape_string($userid, $link),
+	$db = Database::getInstance();
+	return $db->query(
+		"select banid,comment from {chatban} " .
+		"where unix_timestamp(dtmtill) > unix_timestamp(CURRENT_TIMESTAMP) AND address = ?",
+		array($addr),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
+}
+
+function create_thread($groupid, $username, $remoteHost, $referer, $lang, $userid, $userbrowser, $initialState)
+{
+	$db = Database::getInstance();
+
+	$query = "insert into {chatthread} (userName,userid,ltoken,remote,referer, " .
+		"lrevision,locale,userAgent,dtmcreated,dtmmodified,istate" .
+		($groupid ? ",groupid" : "") . ") values " .
+		"(?,?,?,?,?,?,?,?,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP,?" .
+		($groupid ? ", ?" : "") . ")";
+
+	$values = array(
+		$username,
+		$userid,
 		next_token(),
-		db_escape_string($remoteHost, $link),
-		db_escape_string($referer, $link),
-		next_revision($link),
-		db_escape_string($lang, $link),
-		db_escape_string($userbrowser, $link));
+		$remoteHost,
+		$referer,
+		next_revision(),
+		$lang,
+		$userbrowser,
+		$initialState
+	);
 
-	perform_query($query, $link);
-	$id = db_insert_id($link);
+	if ($groupid) {
+		$values[] = $groupid;
+	}
 
-	$newthread = thread_by_id_($id, $link);
+	$db->query($query, $values);
+	$id = $db->insertedId();
+
+	$newthread = thread_by_id($id);
 	return $newthread;
 }
 
 function do_take_thread($threadid, $operatorId, $operatorName, $chatstart = false)
 {
 	global $state_chatting;
-	$link = connect();
 	$params = array("istate" => $state_chatting,
 			"nextagent" => 0,
 			"agentId" => $operatorId,
-			"agentName" => "'" . db_escape_string($operatorName, $link) . "'");
+			"agentName" => $operatorName);
 	if ($chatstart){
 		$params['dtmchatstarted'] = "CURRENT_TIMESTAMP";
 	}
-	commit_thread($threadid, $params, $link);
-	close_connection($link);
+	commit_thread($threadid, $params);
 }
 
 function reopen_thread($threadid)
 {
 	global $state_queue, $state_loading, $state_waiting, $state_chatting, $state_closed, $state_left, $kind_events, $settings;
-	$link = connect();
 
-	$thread = thread_by_id_($threadid, $link);
+	$thread = thread_by_id($threadid);
 
 	if (!$thread)
 		return FALSE;
@@ -712,12 +736,13 @@ function reopen_thread($threadid)
 		return FALSE;
 
 	if ($thread['istate'] != $state_chatting && $thread['istate'] != $state_queue && $thread['istate'] != $state_loading) {
-		commit_thread($threadid,
-					  array("istate" => $state_waiting, "nextagent" => 0), $link);
+		commit_thread(
+			$threadid,
+			array("istate" => $state_waiting, "nextagent" => 0)
+		);
 	}
 
-	post_message_($thread['threadid'], $kind_events, getstring_("chat.status.user.reopenedthread", $thread['locale']), $link);
-	close_connection($link);
+	post_message_($thread['threadid'], $kind_events, getstring_("chat.status.user.reopenedthread", $thread['locale']));
 	return $thread;
 }
 
@@ -779,15 +804,21 @@ function check_for_reassign($thread, $operator)
 	}
 }
 
-function check_connections_from_remote($remote, $link)
+function check_connections_from_remote($remote)
 {
-	global $settings, $state_closed, $state_left, $mysqlprefix;
+	global $settings, $state_closed, $state_left;
 	if ($settings['max_connections_from_one_host'] == 0) {
 		return true;
 	}
-	$result = select_one_row(
-		"select count(*) as opened from ${mysqlprefix}chatthread " .
-		"where remote = '" . db_escape_string($remote, $link) . "' AND istate <> $state_closed AND istate <> $state_left", $link);
+
+	$db = Database::getInstance();
+	$result = $db->query(
+		"select count(*) as opened from {chatthread} " .
+		"where remote = ? AND istate <> ? AND istate <> ?",
+		array($remote, $state_closed, $state_left),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
+
 	if ($result && isset($result['opened'])) {
 		return $result['opened'] < $settings['max_connections_from_one_host'];
 	}
diff --git a/src/messenger/webim/libs/common.php b/src/messenger/webim/libs/common.php
index e9482607..28f8d52f 100644
--- a/src/messenger/webim/libs/common.php
+++ b/src/messenger/webim/libs/common.php
@@ -19,6 +19,7 @@ session_start();
 
 require_once(dirname(__FILE__) . '/converter.php');
 require_once(dirname(__FILE__) . '/config.php');
+require_once(dirname(__FILE__) . '/database.php');
 
 $version = '1.6.5';
 $jsver = "165";
@@ -350,111 +351,6 @@ function cutstring($string, $length = 75, $ellipsis = '')
 	return $result;
 }
 
-function connect()
-{
-	global $mysqlhost, $mysqllogin, $mysqlpass, $mysqldb, $dbencoding, $force_charset_in_connection, $use_persistent_connection;
-	if (!extension_loaded("mysql")) {
-		die('Mysql extension is not loaded');
-	}
-	if ($use_persistent_connection) {
-		$link = @mysql_pconnect($mysqlhost, $mysqllogin, $mysqlpass);
-	}else{
-		$link = @mysql_connect($mysqlhost, $mysqllogin, $mysqlpass);
-	}
-	if (! $link) {
-		die('Could not connect: ' . mysql_error());
-	}
-	mysql_select_db($mysqldb, $link) or die('Could not select database');
-	if ($force_charset_in_connection) {
-		perform_query("SET NAMES '$dbencoding'", $link);
-	}
-	return $link;
-}
-
-function close_connection($link)
-{
-	global $use_persistent_connection;
-	if (! $use_persistent_connection) {
-		mysql_close($link);
-	}
-}
-
-function db_escape_string($string, $link = NULL)
-{
-	if ( is_null($link) ) {
-		return mysql_real_escape_string($string);
-	}
-	return mysql_real_escape_string($string, $link);
-}
-
-function db_error($link)
-{
-	return mysql_error($link);
-}
-
-function db_insert_id($link)
-{
-	return mysql_insert_id($link);
-}
-
-function db_fetch_row($result)
-{
-	return mysql_fetch_row($result);
-}
-
-function db_fetch_assoc($result){
-	return mysql_fetch_assoc($result);
-}
-
-function perform_query($query, $link)
-{
-	$result = mysql_query($query, $link);
-	if (! $result) {
-		die(' Query failed: ' . db_error($link));
-	}
-	return $result;
-}
-
-function db_free_result($result)
-{
-	mysql_free_result($result);
-}
-
-function select_one_row($query, $link)
-{
-	$result = perform_query($query, $link);
-	$line = db_fetch_assoc($result);
-	db_free_result($result);
-	return $line;
-}
-
-function select_multi_assoc($query, $link)
-{
-	$sqlresult = perform_query($query, $link);
-
-	$result = array();
-	while ($row = db_fetch_assoc($sqlresult)) {
-		$result[] = $row;
-	}
-	db_free_result($sqlresult);
-	return $result;
-}
-
-function db_build_select($fields, $table, $conditions, $orderandgroup)
-{
-	$condition = count($conditions) > 0 ? " where " . implode(" and ", $conditions) : "";
-	if ($orderandgroup) $orderandgroup = " " . $orderandgroup;
-	return "select $fields from $table$condition$orderandgroup";
-}
-
-function db_rows_count($table, $conditions, $countfields, $link)
-{
-	$result = perform_query(db_build_select("count(" . ($countfields ? $countfields : "*") . ")", $table, $conditions, ""), $link);
-	$line = db_fetch_row($result);
-	db_free_result($result);
-	return $line[0];
-}
-
 function start_xml_output()
 {
 	header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
@@ -716,32 +612,25 @@ $settings = array(
 $settingsloaded = false;
 $settings_in_db = array();
 
-function loadsettings_($link)
+function loadsettings()
 {
-	global $settingsloaded, $settings_in_db, $settings, $mysqlprefix;
+	global $settingsloaded, $settings_in_db, $settings;
 	if ($settingsloaded) {
 		return;
 	}
 	$settingsloaded = true;
 
-	$sqlresult = perform_query("select vckey,vcvalue from ${mysqlprefix}chatconfig", $link);
-
-	while ($row = db_fetch_assoc($sqlresult)) {
+	$db = Database::getInstance();
+	$rows = $db->query(
+		"select vckey,vcvalue from {chatconfig}",
+		NULL,
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
+	foreach ($rows as $row) {
 		$name = $row['vckey'];
 		$settings[$name] = $row['vcvalue'];
 		$settings_in_db[$name] = true;
 	}
-	db_free_result($sqlresult);
-}
-
-function loadsettings()
-{
-	global $settingsloaded;
-	if (!$settingsloaded) {
-		$link = connect();
-		loadsettings_($link);
-		close_connection($link);
-	}
 }
 
 function getchatstyle()
diff --git a/src/messenger/webim/libs/getcode.php b/src/messenger/webim/libs/getcode.php
index 3a2a652e..1f5305f6 100644
--- a/src/messenger/webim/libs/getcode.php
+++ b/src/messenger/webim/libs/getcode.php
@@ -65,9 +65,7 @@ function verifyparam_groupid($paramid)
 function get_groups_list()
 {
 	$result = array();
-	$link = connect();
-	$allgroups = get_all_groups($link);
-	close_connection($link);
+	$allgroups = get_all_groups();
 	$result[] = array('groupid' => '', 'vclocalname' => getlocal("page.gen_button.default_group"), 'level' => 0);
 	foreach ($allgroups as $g) {
 		$result[] = $g;
diff --git a/src/messenger/webim/libs/groups.php b/src/messenger/webim/libs/groups.php
index 1762b440..e4d77a17 100644
--- a/src/messenger/webim/libs/groups.php
+++ b/src/messenger/webim/libs/groups.php
@@ -17,11 +17,12 @@
 
 function group_by_id($id)
 {
-	global $mysqlprefix;
-	$link = connect();
-	$group = select_one_row(
-		"select * from ${mysqlprefix}chatgroup where groupid = $id", $link);
-	close_connection($link);
+	$db = Database::getInstance();
+	$group = $db->query(
+		"select * from {chatgroup} where groupid = ?",
+		array($id),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 	return $group;
 }
 
@@ -47,12 +48,17 @@ function setup_group_settings_tabs($gid, $active)
 	}
 }
 
-function get_operator_groupslist($operatorid, $link)
+function get_operator_groupslist($operatorid)
 {
-	global $settings, $mysqlprefix;
+	global $settings;
+	$db = Database::getInstance();
 	if ($settings['enablegroups'] == '1') {
 		$groupids = array(0);
-		$allgroups = select_multi_assoc("select groupid from ${mysqlprefix}chatgroupoperator where operatorid = $operatorid order by groupid", $link);
+		$allgroups = $db->query(
+			"select groupid from {chatgroupoperator} where operatorid = ? order by groupid",
+			array($operatorid),
+			array('return_rows' => Database::RETURN_ALL_ROWS)
+		);
 		foreach ($allgroups as $g) {
 			$groupids[] = $g['groupid'];
 		}
@@ -64,10 +70,13 @@ function get_operator_groupslist($operatorid, $link)
 
 function get_available_parent_groups($skipgroup)
 {
-	global $mysqlprefix;
-	$link = connect();
-	$query = "select ${mysqlprefix}chatgroup.groupid as groupid, parent, vclocalname from ${mysqlprefix}chatgroup order by vclocalname";
-	$groupslist = select_multi_assoc($query, $link);
+	$db = Database::getInstance();
+	$groupslist = $db->query(
+		"select {chatgroup}.groupid as groupid, parent, vclocalname " .
+		"from {chatgroup} order by vclocalname",
+		NULL,
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
 	$result = array(array('groupid' => '', 'level' => '', 'vclocalname' => getlocal("form.field.groupparent.root")));
 
 	if ($skipgroup) {
@@ -77,15 +86,17 @@ function get_available_parent_groups($skipgroup)
 	}
 
 	$result = array_merge($result, get_sorted_child_groups_($groupslist, $skipgroup, 0) );
-	close_connection($link);
 	return $result;
 }
 
-function group_has_children($groupid, $link)
+function group_has_children($groupid)
 {
-	global $mysqlprefix;
-	$children = select_one_row(sprintf("select COUNT(*) as count from ${mysqlprefix}chatgroup where parent = %u", $groupid),
-					$link);
+	$db = Database::getInstance();
+	$children = $db->query(
+		"select COUNT(*) as count from {chatgroup} where parent = ?",
+		array($groupid),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 	return ($children['count'] > 0);
 }
 
diff --git a/src/messenger/webim/libs/invitation.php b/src/messenger/webim/libs/invitation.php
index 1c7b1ece..a9749ca6 100644
--- a/src/messenger/webim/libs/invitation.php
+++ b/src/messenger/webim/libs/invitation.php
@@ -15,11 +15,14 @@
  * limitations under the License.
  */
 
-function invitation_state($visitorid, $link)
+function invitation_state($visitorid)
 {
-	global $mysqlprefix;
-	$query = "select invited, threadid from ${mysqlprefix}chatsitevisitor where visitorid = '" . db_escape_string($visitorid) . "'";
-	$result = select_one_row($query, $link);
+	$db = Database::getInstance();
+	$result = $db->query(
+		"select invited, threadid from {chatsitevisitor} where visitorid = ?",
+		array($visitorid),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 	if (!$result) {
 	    $result['invited'] = 0;
 	    $result['threadid'] = 0;
@@ -27,46 +30,51 @@ function invitation_state($visitorid, $link)
 	return $result;
 }
 
-function invitation_invite($visitorid, $operatorid, $link)
+function invitation_invite($visitorid, $operatorid)
 {
-	global $mysqlprefix;
-
-	if (!invitation_check($visitorid, $link)) {
-	    $query = "update ${mysqlprefix}chatsitevisitor set invited = 1, invitedby = '" . db_escape_string($operatorid) . "', invitationtime = now(), invitations = invitations + 1 where visitorid = '" . db_escape_string($visitorid) . "'";
-	    perform_query($query, $link);
-	    return invitation_check($visitorid, $link);
-	}
-	else {
-	    return FALSE;
+	if (!invitation_check($visitorid)) {
+		$db = Database::getInstance();
+		$db->query(
+			"update {chatsitevisitor} set invited = 1, invitedby = ?, " .
+			"invitationtime = now(), invitations = invitations + 1 where visitorid = ?",
+			array($operatorid, $visitorid)
+		);
+		return invitation_check($visitorid);
+	} else {
+		return FALSE;
 	}
 }
 
-function invitation_check($visitorid, $link)
+function invitation_check($visitorid)
 {
-	global $mysqlprefix;
-
-	$query = "select invitedby from ${mysqlprefix}chatsitevisitor where invited and visitorid = '" . db_escape_string($visitorid) . "'" .
-		 " and lasttime < invitationtime and threadid is null";
-	$result = select_one_row($query, $link);
-
+	$db = Database::getInstance();
+	$result = $db->query(
+		"select invitedby from {chatsitevisitor} where invited and visitorid = ? " .
+		 " and lasttime < invitationtime and threadid is null",
+		array($visitorid),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 	return ($result && isset($result['invitedby']) && $result['invitedby']) ? $result['invitedby'] : FALSE;
 }
 
-function invitation_accept($visitorid, $threadid, $link)
+function invitation_accept($visitorid, $threadid)
 {
-	global $mysqlprefix;
+	$db = Database::getInstance();
+	$db->query(
+		"update {chatsitevisitor} set threadid = ?, chats = chats + 1 where visitorid = ?",
+		array($threadid, $visitorid)
+	);
 
-	$query = "update ${mysqlprefix}chatsitevisitor set threadid = " . $threadid . ", chats = chats + 1 where visitorid = " . db_escape_string($visitorid) . "";
-	perform_query($query, $link);
-
-	$query = "select invitedby from ${mysqlprefix}chatsitevisitor where visitorid = '" . db_escape_string($visitorid) . "'";
-	$result = select_one_row($query, $link);
+	$result = $db->query(
+		"select invitedby from {chatsitevisitor} where visitorid = ?",
+		array($visitorid),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 
 	if ($result && isset($result['invitedby']) && $result['invitedby']) {
-	    return $result['invitedby'];
-	}
-	else {
-	    return FALSE;
+		return $result['invitedby'];
+	} else {
+		return FALSE;
 	}
 }
 
diff --git a/src/messenger/webim/libs/notify.php b/src/messenger/webim/libs/notify.php
index 48e400d3..a9b17c21 100644
--- a/src/messenger/webim/libs/notify.php
+++ b/src/messenger/webim/libs/notify.php
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-function webim_mail($toaddr, $reply_to, $subject, $body, $link)
+function webim_mail($toaddr, $reply_to, $subject, $body)
 {
 	global $webim_encoding, $webim_mailbox, $mail_encoding, $current_locale;
 
diff --git a/src/messenger/webim/libs/operator.php b/src/messenger/webim/libs/operator.php
old mode 100755
new mode 100644
index 262ff428..fcbe184f
--- a/src/messenger/webim/libs/operator.php
+++ b/src/messenger/webim/libs/operator.php
@@ -31,37 +31,32 @@ $permission_ids = array(
 
 function operator_by_login($login)
 {
-	global $mysqlprefix;
-	$link = connect();
-	$operator = select_one_row(
-		"select * from ${mysqlprefix}chatoperator where vclogin = '" . db_escape_string($login) . "'", $link);
-	close_connection($link);
-	return $operator;
+	$db = Database::getInstance();
+	return $db->query(
+		"select * from {chatoperator} where vclogin = ?",
+		array($login),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 }
 
 function operator_by_email($mail)
 {
-	global $mysqlprefix;
-	$link = connect();
-	$operator = select_one_row(
-		"select * from ${mysqlprefix}chatoperator where vcemail = '" . db_escape_string($mail) . "'", $link);
-	close_connection($link);
-	return $operator;
-}
-
-function operator_by_id_($id, $link)
-{
-	global $mysqlprefix;
-	return select_one_row(
-		"select * from ${mysqlprefix}chatoperator where operatorid = $id", $link);
+	$db = Database::getInstance();
+	return $db->query(
+		"select * from {chatoperator} where vcemail = ?",
+		array($mail),
+		array('return_rows', Database::RETURN_ONE_ROW)
+	);
 }
 
 function operator_by_id($id)
 {
-	$link = connect();
-	$operator = operator_by_id_($id, $link);
-	close_connection($link);
-	return $operator;
+	$db = Database::getInstance();
+	return $db->query(
+		"select * from {chatoperator} where operatorid = ?",
+		array($id),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 }
 
 /**
@@ -80,8 +75,7 @@ function operator_by_id($id)
  */
 function get_operators_list($options)
 {
-	global $mysqlprefix;
-	$link = connect();
+	$db = Database::getInstance();
 
 	if ( !empty($options['sort']) && isset($options['sort']['by']) && isset($options['sort']['desc'])) {
 		switch ($options['sort']['by']) {
@@ -103,54 +97,67 @@ function get_operators_list($options)
 		$orderby = "vclogin";
 	}
 
-	$query = "select distinct ${mysqlprefix}chatoperator.operatorid, vclogin, vclocalename, vccommonname, istatus, idisabled, (unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time " .
-		 "from ${mysqlprefix}chatoperator" .
+	$query = "select distinct {chatoperator}.operatorid, vclogin, vclocalename, vccommonname, istatus, idisabled, (unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time " .
+		 "from {chatoperator}" .
 		 (
 		 empty($options['isolated_operator_id']) ? "" :
-			sprintf(", ${mysqlprefix}chatgroupoperator " .
-				" where ${mysqlprefix}chatoperator.operatorid = ${mysqlprefix}chatgroupoperator.operatorid and ${mysqlprefix}chatgroupoperator.groupid in " .
-				"(select g.groupid from ${mysqlprefix}chatgroup g, " .
-				"(select distinct parent from ${mysqlprefix}chatgroup, ${mysqlprefix}chatgroupoperator " .
-				"where ${mysqlprefix}chatgroup.groupid = ${mysqlprefix}chatgroupoperator.groupid and ${mysqlprefix}chatgroupoperator.operatorid = %u) i " .
-				"where g.groupid = i.parent or g.parent = i.parent " .
-				")", $options['isolated_operator_id'])
+			", {chatgroupoperator} " .
+			" where {chatoperator}.operatorid = {chatgroupoperator}.operatorid and {chatgroupoperator}.groupid in " .
+			"(select g.groupid from {chatgroup} g, " .
+			"(select distinct parent from {chatgroup}, {chatgroupoperator} " .
+			"where {chatgroup}.groupid = {chatgroupoperator}.groupid and {chatgroupoperator}.operatorid = :operatorid) i " .
+			"where g.groupid = i.parent or g.parent = i.parent " .
+			")"
 		 ) .
 		 " order by " . $orderby;
 
-	$operators = select_multi_assoc($query, $link);
-	close_connection($link);
+	$operators = $db->query(
+		$query,
+		(
+			empty($options['isolated_operator_id']) 
+			? array()
+			: array(':operatorid' => $options['isolated_operator_id'])
+		),
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
+
 	return $operators;
 }
 
 function operator_get_all()
 {
-	global $mysqlprefix;
-	$link = connect();
-
-	$query = "select operatorid, vclogin, vclocalename, vccommonname, istatus, idisabled, (unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time " .
-			 "from ${mysqlprefix}chatoperator order by vclogin";
-	$operators = select_multi_assoc($query, $link);
-	close_connection($link);
-	return $operators;
+	$db = Database::getInstance();
+	return $operators = $db->query(
+		"select operatorid, vclogin, vclocalename, vccommonname, istatus, idisabled, " .
+		"(unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time " .
+		"from {chatoperator} order by vclogin",
+		NULL,
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
 }
 
 function get_operators_from_adjacent_groups($operator)
 {
-	global $mysqlprefix;
-	$link = connect();
-
-	$query = "select distinct ${mysqlprefix}chatoperator.operatorid, vclogin, vclocalename, vccommonname, istatus, idisabled, (unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time " .
-		 "from ${mysqlprefix}chatoperator, ${mysqlprefix}chatgroupoperator " .
-		 " where ${mysqlprefix}chatoperator.operatorid = ${mysqlprefix}chatgroupoperator.operatorid and ${mysqlprefix}chatgroupoperator.groupid in " .
-		 "(select g.groupid from ${mysqlprefix}chatgroup g, " .
-		 "(select distinct parent from ${mysqlprefix}chatgroup, ${mysqlprefix}chatgroupoperator " .
-		 "where ${mysqlprefix}chatgroup.groupid = ${mysqlprefix}chatgroupoperator.groupid and ${mysqlprefix}chatgroupoperator.operatorid = ".$operator['operatorid'].") i " .
-		 "where g.groupid = i.parent or g.parent = i.parent " .
-		 ") order by vclogin";
-
-	$operators = select_multi_assoc($query, $link);
-	close_connection($link);
-	return $operators;
+	$db = Database::getInstance();
+	$query = "select distinct {chatoperator}.operatorid, vclogin, vclocalename,vccommonname, " .
+		"istatus, idisabled, " .
+		"(unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time " .
+		"from {chatoperator}, {chatgroupoperator} " .
+		"where {chatoperator}.operatorid = {chatgroupoperator}.operatorid " .
+		"and {chatgroupoperator}.groupid in " .
+		"(select g.groupid from {chatgroup} g, " .
+		"(select distinct parent from {chatgroup}, {chatgroupoperator} " .
+		"where {chatgroup}.groupid = {chatgroupoperator}.groupid " .
+		"and {chatgroupoperator}.operatorid = ?) i " .
+		"where g.groupid = i.parent or g.parent = i.parent " .
+		") order by vclogin";
+	
+	
+	return $db->query(
+		$query,
+		array($operator['operatorid']),
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
 }
 
 function operator_is_online($operator)
@@ -178,100 +185,116 @@ function operator_is_disabled($operator)
 
 function update_operator($operatorid, $login, $email, $password, $localename, $commonname)
 {
-	global $mysqlprefix;
-	$link = connect();
-	$query = sprintf(
-		"update ${mysqlprefix}chatoperator set vclogin = '%s',%s vclocalename = '%s', vccommonname = '%s'" .
-		", vcemail = '%s', vcjabbername= '%s'" .
-		" where operatorid = %s",
-		db_escape_string($login),
-		($password ? " vcpassword='" . md5($password) . "'," : ""),
-		db_escape_string($localename),
-		db_escape_string($commonname),
-		db_escape_string($email),
-		'',
-		$operatorid);
-
-	perform_query($query, $link);
-	close_connection($link);
+	$db = Database::getInstance();
+	$db->query(
+		"update {chatoperator} set vclogin = :login, " .
+		($password ? " vcpassword=:password, " : "") .
+		"vclocalename = :localname, vccommonname = :commonname, " .
+		"vcemail = :email, vcjabbername= :jabbername " .
+		"where operatorid = :operatorid",
+		array(
+			':login' => $login,
+			':password' => $password,
+			':localname' => $localename,
+			':commonname' => $commonname,
+			':email' => $email,
+			':jabbername' => '',
+			':operatorid' => $operatorid
+		)
+	);
 }
 
 function update_operator_avatar($operatorid, $avatar)
 {
-	global $mysqlprefix;
-	$link = connect();
-	$query = sprintf(
-		"update ${mysqlprefix}chatoperator set vcavatar = '%s' where operatorid = %s",
-		db_escape_string($avatar), $operatorid);
-
-	perform_query($query, $link);
-	close_connection($link);
-}
-
-function create_operator_($login, $email, $password, $localename, $commonname, $avatar, $link)
-{
-	global $mysqlprefix;
-	$query = sprintf(
-		"insert into ${mysqlprefix}chatoperator (vclogin,vcpassword,vclocalename,vccommonname,vcavatar,vcemail,vcjabbername) values ('%s','%s','%s','%s','%s','%s','%s')",
-		db_escape_string($login),
-		md5($password),
-		db_escape_string($localename),
-		db_escape_string($commonname),
-		db_escape_string($avatar),
-		db_escape_string($email), '');
-
-	perform_query($query, $link);
-	$id = db_insert_id($link);
-
-	return select_one_row("select * from ${mysqlprefix}chatoperator where operatorid = $id", $link);
+	$db = Database::getInstance();
+	$db->query(
+		"update {chatoperator} set vcavatar = ? where operatorid = ?",
+		array($avatar, $operatorid)
+	);
 }
 
+/**
+ * @todo Rename create_operator_ function to create_operator and remove any usage of create_operator_
+ */
 function create_operator($login, $email, $password, $localename, $commonname, $avatar)
 {
-	$link = connect();
-	$newop = create_operator_($login, $email, $password, $localename, $commonname, $avatar, $link);
-	close_connection($link);
-	return $newop;
+	$db = Database::getInstance();
+	$db->query(
+		"insert into {chatoperator} " .
+		"(vclogin,vcpassword,vclocalename,vccommonname,vcavatar,vcemail,vcjabbername) " .
+		"values (?, ?, ?, ?, ?, ?, ?)",
+		array(
+			$login,
+			md5($password),
+			$localename,
+			$commonname,
+			$avatar,
+			$email,
+			''
+		)
+	);
+
+	$id = $db->insertedId();
+
+	return $db->query(
+		"select * from {chatoperator} where operatorid = ?",
+		array($id),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 }
 
 function notify_operator_alive($operatorid, $istatus)
 {
-	global $mysqlprefix;
-	$link = connect();
-	perform_query("update ${mysqlprefix}chatoperator set istatus = $istatus, dtmlastvisited = CURRENT_TIMESTAMP where operatorid = $operatorid", $link);
-	close_connection($link);
+	$db = Database::getInstance();
+	$db->query(
+		"update {chatoperator} set istatus = ?, dtmlastvisited = CURRENT_TIMESTAMP " .
+		"where operatorid = ?",
+		array($istatus, $operatorid)
+	);
 }
 
 function has_online_operators($groupid = "")
 {
-	global $settings, $mysqlprefix;
+	global $settings;
 	loadsettings();
-	$link = connect();
-	$query = "select count(*) as total, min(unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time from ${mysqlprefix}chatoperator";
+	$db = Database::getInstance();
+
+	$query = "select count(*) as total, min(unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time from {chatoperator}";
 	if ($groupid) {
-		$query .= ", ${mysqlprefix}chatgroupoperator, ${mysqlprefix}chatgroup where ${mysqlprefix}chatgroup.groupid = ${mysqlprefix}chatgroupoperator.groupid and " .
-				  "(${mysqlprefix}chatgroup.groupid = $groupid or ${mysqlprefix}chatgroup.parent = $groupid) and ${mysqlprefix}chatoperator.operatorid = " .
-				  "${mysqlprefix}chatgroupoperator.operatorid and istatus = 0";
+		$query .= ", {chatgroupoperator}, {chatgroup} where {chatgroup}.groupid = {chatgroupoperator}.groupid and " .
+			"({chatgroup}.groupid = :groupid or {chatgroup}.parent = :groupid) and {chatoperator}.operatorid = " .
+			"{chatgroupoperator}.operatorid and istatus = 0";
 	} else {
 		if ($settings['enablegroups'] == 1) {
-			$query .= ", ${mysqlprefix}chatgroupoperator where ${mysqlprefix}chatoperator.operatorid = " .
-				"${mysqlprefix}chatgroupoperator.operatorid and istatus = 0";
+			$query .= ", {chatgroupoperator} where {chatoperator}.operatorid = " .
+				"{chatgroupoperator}.operatorid and istatus = 0";
 		} else {
 			$query .= " where istatus = 0";
 		}
 	}
-	$row = select_one_row($query, $link);
-	close_connection($link);
+
+	$row = $db->query(
+		$query,
+		array(':groupid'=>$groupid),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 	return $row['time'] < $settings['online_timeout'] && $row['total'] > 0;
 }
 
-function is_operator_online($operatorid, $link)
+function is_operator_online($operatorid)
 {
-	global $settings, $mysqlprefix;
-	loadsettings_($link);
-	$query = "select count(*) as total, min(unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time " .
-			 "from ${mysqlprefix}chatoperator where operatorid = $operatorid";
-	$row = select_one_row($query, $link);
+	global $settings;
+	loadsettings();
+	
+	$db = Database::getInstance();
+	$row = $db->query(
+		"select count(*) as total, " .
+		"min(unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time " .
+		"from {chatoperator} where operatorid = ?",
+		array($operatorid),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
+	
 	return $row['time'] < $settings['online_timeout'] && $row['total'] == 1;
 }
 
@@ -361,7 +384,7 @@ function logout_operator()
 
 function setup_redirect_links($threadid, $operator, $token)
 {
-	global $page, $webimroot, $settings, $mysqlprefix;
+	global $page, $webimroot, $settings;
 	loadsettings();
 
 	$operator_in_isolation = in_isolation($operator);
@@ -370,12 +393,10 @@ function setup_redirect_links($threadid, $operator, $token)
 	$operators = get_operators_list($list_options);
 	$operatorscount = count($operators);
 
-	$link = connect();
-
 	$groupscount = 0;
 	$groups = array();
 	if ($settings['enablegroups'] == "1") {
-		$groupslist = $operator_in_isolation?get_groups_for_operator($link, $operator, true):get_groups($link, true);
+		$groupslist = $operator_in_isolation?get_groups_for_operator($operator, true):get_groups(true);
 		foreach ($groupslist as $group) {
 			if ($group['inumofagents'] == 0) {
 				continue;
@@ -384,7 +405,6 @@ function setup_redirect_links($threadid, $operator, $token)
 		}
 		$groupscount = count($groups);
 	}
-	close_connection($link);
 
 	prepare_pagination(max($operatorscount, $groupscount), 8);
 	$p = $page['pagination'];
@@ -471,23 +491,35 @@ function prepare_menu($operator, $hasright = true)
 	}
 }
 
-function get_all_groups($link)
+function get_all_groups()
 {
-	global $mysqlprefix;
-	$query = "select ${mysqlprefix}chatgroup.groupid as groupid, parent, vclocalname, vclocaldescription from ${mysqlprefix}chatgroup order by vclocalname";
-	return get_sorted_child_groups_(select_multi_assoc($query, $link));
+	$db = Database::getInstance();
+	$groups = $db->query(
+		"select {chatgroup}.groupid as groupid, parent, vclocalname, vclocaldescription " .
+		"from {chatgroup} order by vclocalname",
+		NULL,
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
+	return get_sorted_child_groups_($groups);
 }
 
-function get_all_groups_for_operator($operator, $link)
+function get_all_groups_for_operator($operator)
 {
-	global $mysqlprefix;
+	$db = Database::getInstance();
 	$query = "select g.groupid as groupid, g.parent, g.vclocalname, g.vclocaldescription " .
-		 "from ${mysqlprefix}chatgroup g, " .
-		 "(select distinct parent from ${mysqlprefix}chatgroup, ${mysqlprefix}chatgroupoperator " .
-		 "where ${mysqlprefix}chatgroup.groupid = ${mysqlprefix}chatgroupoperator.groupid and ${mysqlprefix}chatgroupoperator.operatorid = ".$operator['operatorid'].") i " .
-		 "where g.groupid = i.parent or g.parent = i.parent " .
-		 "order by vclocalname";
-	return get_sorted_child_groups_(select_multi_assoc($query, $link));
+		"from {chatgroup} g, " .
+		"(select distinct parent from {chatgroup}, {chatgroupoperator} " .
+		"where {chatgroup}.groupid = {chatgroupoperator}.groupid " .
+		"and {chatgroupoperator}.operatorid = ?) i " .
+		"where g.groupid = i.parent or g.parent = i.parent " .
+		"order by vclocalname";
+	
+	$groups = $db->query(
+		$query,
+		array($operator['operatorid']),
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
+	return get_sorted_child_groups_($groups);
 }
 
 function get_sorted_child_groups_($groupslist, $skipgroups = array(), $maxlevel = -1, $groupid = NULL, $level = 0)
@@ -505,10 +537,9 @@ function get_sorted_child_groups_($groupslist, $skipgroups = array(), $maxlevel
 	return $child_groups;
 }
 
-function get_groups_($link, $checkaway, $operator, $order = NULL)
+function get_groups_($checkaway, $operator, $order = NULL)
 {
-	global $mysqlprefix;
-
+	$db = Database::getInstance();
 	if($order){
 		switch($order['by']){
 			case 'weight':
@@ -518,63 +549,68 @@ function get_groups_($link, $checkaway, $operator, $order = NULL)
 				$orderby = "ilastseen";
 				break;
 			default:
-				$orderby = "${mysqlprefix}chatgroup.vclocalname";
+				$orderby = "{chatgroup}.vclocalname";
 		}
-		$orderby = sprintf(" IF(ISNULL(${mysqlprefix}chatgroup.parent),CONCAT('_',%s),'') %s, ${mysqlprefix}chatgroup.iweight ",
+		$orderby = sprintf(" IF(ISNULL({chatgroup}.parent),CONCAT('_',%s),'') %s, {chatgroup}.iweight ",
 					$orderby,
 					($order['desc']?'DESC':'ASC'));
 	}else{
 		$orderby = "iweight, vclocalname";
 	}
 
-	$query = "select ${mysqlprefix}chatgroup.groupid as groupid, ${mysqlprefix}chatgroup.parent as parent, vclocalname, vclocaldescription, iweight" .
-			 ", (SELECT count(*) from ${mysqlprefix}chatgroupoperator where ${mysqlprefix}chatgroup.groupid = " .
-			 "${mysqlprefix}chatgroupoperator.groupid) as inumofagents" .
-			 ", (SELECT min(unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time " .
-			 "from ${mysqlprefix}chatgroupoperator, ${mysqlprefix}chatoperator where istatus = 0 and " .
-			 "${mysqlprefix}chatgroup.groupid = ${mysqlprefix}chatgroupoperator.groupid " .
-			 "and ${mysqlprefix}chatgroupoperator.operatorid = ${mysqlprefix}chatoperator.operatorid) as ilastseen" .
-			 ($checkaway
-					 ? ", (SELECT min(unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time " .
-					   "from ${mysqlprefix}chatgroupoperator, ${mysqlprefix}chatoperator where istatus <> 0 and " .
-					   "${mysqlprefix}chatgroup.groupid = ${mysqlprefix}chatgroupoperator.groupid " .
-					   "and ${mysqlprefix}chatgroupoperator.operatorid = ${mysqlprefix}chatoperator.operatorid) as ilastseenaway"
-					 : ""
-			 ) .
-			 " from ${mysqlprefix}chatgroup" .
-			 ($operator
-					 ? ", (select distinct parent from ${mysqlprefix}chatgroup, ${mysqlprefix}chatgroupoperator " .
-					   "where ${mysqlprefix}chatgroup.groupid = ${mysqlprefix}chatgroupoperator.groupid and ${mysqlprefix}chatgroupoperator.operatorid = ".$operator['operatorid'].") i " .
-					   "where ${mysqlprefix}chatgroup.groupid = i.parent or ${mysqlprefix}chatgroup.parent = i.parent "
-					 : ""
-			 ) .
-			 " order by " . $orderby;
-	return get_sorted_child_groups_(select_multi_assoc($query, $link));
+	$query = "select {chatgroup}.groupid as groupid, {chatgroup}.parent as parent, vclocalname, vclocaldescription, iweight" .
+		", (SELECT count(*) from {chatgroupoperator} where {chatgroup}.groupid = " .
+		"{chatgroupoperator}.groupid) as inumofagents" .
+		", (SELECT min(unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time " .
+		"from {chatgroupoperator}, {chatoperator} where istatus = 0 and " .
+		"{chatgroup}.groupid = {chatgroupoperator}.groupid " .
+		"and {chatgroupoperator}.operatorid = {chatoperator}.operatorid) as ilastseen" .
+		($checkaway
+			? ", (SELECT min(unix_timestamp(CURRENT_TIMESTAMP)-unix_timestamp(dtmlastvisited)) as time " .
+			"from {chatgroupoperator}, {chatoperator} where istatus <> 0 and " .
+			"{chatgroup}.groupid = {chatgroupoperator}.groupid " .
+			"and {chatgroupoperator}.operatorid = {chatoperator}.operatorid) as ilastseenaway"
+			: ""
+		) .
+		" from {chatgroup} " .
+		($operator
+			? ", (select distinct parent from {chatgroup}, {chatgroupoperator} " .
+			"where {chatgroup}.groupid = {chatgroupoperator}.groupid and {chatgroupoperator}.operatorid = ?) i " .
+			"where {chatgroup}.groupid = i.parent or {chatgroup}.parent = i.parent "
+			: ""
+		) .
+		" order by " . $orderby;
+	$groups = $db->query(
+		$query,
+		array($operator['operatorid']),
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
+	return get_sorted_child_groups_($groups);
 }
 
-function get_groups($link, $checkaway)
+function get_groups($checkaway)
 {
-	return get_groups_($link, $checkaway, NULL);
+	return get_groups_($checkaway, NULL);
 }
 
-function get_groups_for_operator($link, $operator, $checkaway)
+function get_groups_for_operator($operator, $checkaway)
 {
-	return get_groups_($link, $checkaway, $operator);
+	return get_groups_($checkaway, $operator);
 }
 
-function get_sorted_groups($link, $order)
+function get_sorted_groups($order)
 {
-	return get_groups_($link, true, NULL, $order);
+	return get_groups_(true, NULL, $order);
 }
 
 function get_operator_groupids($operatorid)
 {
-	global $mysqlprefix;
-	$link = connect();
-	$query = "select groupid from ${mysqlprefix}chatgroupoperator where operatorid = $operatorid";
-	$result = select_multi_assoc($query, $link);
-	close_connection($link);
-	return $result;
+	$db = Database::getInstance();
+	return $db->query(
+		"select groupid from {chatgroupoperator} where operatorid = ?",
+		array($operatorid),
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
 }
 
 ?>
\ No newline at end of file
diff --git a/src/messenger/webim/libs/pagination.php b/src/messenger/webim/libs/pagination.php
index cb16732f..1a1c65cb 100644
--- a/src/messenger/webim/libs/pagination.php
+++ b/src/messenger/webim/libs/pagination.php
@@ -72,15 +72,47 @@ function setup_pagination($items, $default_items_per_page = 15)
 	}
 }
 
-function select_with_pagintation($fields, $table, $conditions, $order, $countfields, $link)
+/**
+ * Selects rows from database taking pagination into account.
+ * 
+ * @global array $page
+ * @param string $fields Selected fields
+ * @param string $table Table name in database
+ * @param string $conditions Where close
+ * @param string $order Order clause
+ * @param string $countfields Field, substituted in SQL COUNT function
+ * @param array $values Associative array of substituted values. Keys are named placeholders in the 
+ *   query(see Database::query() and its $values parameter description)
+ * 
+ * @see Database::query()
+ */
+function select_with_pagintation($fields, $table, $conditions, $order, $countfields, $values)
 {
 	global $page;
-	$count = db_rows_count($table, $conditions, $countfields, $link);
+	$db = Database::getInstance();
+
+	list($count) = $db->query(
+		"select count(". ($countfields ? $countfieds : "*") .") from {$table} " .
+		"where " . (count($conditions)  ? implode(" and ", $conditions) : "") .
+		($order ? " " . $order : ""),
+		$values,
+		array(
+			'return_rows' => Database::RETURN_ONE_ROW,
+			'fetch_type' => Database::FETCH_NUM
+		)
+	);
+
 	prepare_pagination($count);
 	if ($count) {
 		$p = $page['pagination'];
 		$limit = $p['limit'];
-		$page['pagination.items'] = select_multi_assoc(db_build_select($fields, $table, $conditions, $order) . " " . $limit, $link);
+		$page['pagination.items'] = $db->query(
+			"select {$fields} from {$table} " .
+			"where " . (count($conditions)  ? implode(" and ", $conditions) : "") .
+			($order ? " " . $order : "") . " " . $limit,
+			$values,
+			array('return_rows' => Database::RETURN_ALL_ROWS)
+		);
 	} else {
 		$page['pagination.items'] = false;
 	}
diff --git a/src/messenger/webim/libs/settings.php b/src/messenger/webim/libs/settings.php
index 79df493b..7be27ca6 100644
--- a/src/messenger/webim/libs/settings.php
+++ b/src/messenger/webim/libs/settings.php
@@ -17,17 +17,14 @@
 
 function update_settings()
 {
-	global $settings, $settings_in_db, $mysqlprefix;
-	$link = connect();
+	global $settings, $settings_in_db;
+	$db = Database::getInstance();
 	foreach ($settings as $key => $value) {
 		if (!isset($settings_in_db[$key])) {
-			perform_query("insert into ${mysqlprefix}chatconfig (vckey) values ('$key')", $link);
+			$db->query("insert into {chatconfig} (vckey) values (?)", array($key));
 		}
-		$query = sprintf("update ${mysqlprefix}chatconfig set vcvalue='%s' where vckey='$key'", db_escape_string($value));
-		perform_query($query, $link);
+		$db->query("update {chatconfig} set vcvalue=? where vckey=?", array($value, $key));
 	}
-
-	close_connection($link);
 }
 
 function setup_settings_tabs($active)
diff --git a/src/messenger/webim/libs/track.php b/src/messenger/webim/libs/track.php
index d7392af1..a2437cb5 100644
--- a/src/messenger/webim/libs/track.php
+++ b/src/messenger/webim/libs/track.php
@@ -17,88 +17,108 @@
 
 require_once(dirname(__FILE__).'/chat.php');
 
-function track_visitor($visitorid, $entry, $referer, $link)
+function track_visitor($visitorid, $entry, $referer)
 {
-	global $mysqlprefix;
-
-	$visitor = track_get_visitor_by_id($visitorid, $link);
+	$visitor = track_get_visitor_by_id($visitorid);
 
 	if (FALSE === $visitor) {
-	    $visitor = track_visitor_start($entry, $referer, $link);
-	    return $visitor;
-	}
-	else {
-	    perform_query("update ${mysqlprefix}chatsitevisitor set lasttime = CURRENT_TIMESTAMP where visitorid=" . $visitor['visitorid'], $link);
-	    track_visit_page($visitor['visitorid'], $referer, $link);
-	    return $visitor['visitorid'];
+		$visitor = track_visitor_start($entry, $referer);
+		return $visitor;
+	} else {
+		$db = Database::getInstance();
+		$db->query(
+			"update {chatsitevisitor} set lasttime = CURRENT_TIMESTAMP " .
+			"where visitorid=?",
+			array($visitor['visitorid'])
+		);
+		track_visit_page($visitor['visitorid'], $referer);
+		return $visitor['visitorid'];
 	}
 }
 
-function track_visitor_start($entry, $referer, $link)
+function track_visitor_start($entry, $referer)
 {
-	global $mysqlprefix;
-
 	$visitor = visitor_from_request();
 
-	perform_query(sprintf("insert into ${mysqlprefix}chatsitevisitor (userid, username, firsttime, lasttime, entry, details) values ('%s', '%s', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '%s', '%s')",
-			db_escape_string($visitor['id']),
-			db_escape_string($visitor['name']),
-			db_escape_string($entry),
-			db_escape_string(track_build_details())), $link);
-	$id = db_insert_id($link);
+	$db = Database::getInstance();
+	$db->query(
+		"insert into {chatsitevisitor} (userid,username,firsttime,lasttime,entry,details) ".
+		"values (?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, ?, ?)",
+		array(
+			$visitor['id'],
+			$visitor['name'],
+			$entry,
+			track_build_details()
+		)
+	);
+
+	$id = $db->insertedId();
 
 	if ($id) {
-		track_visit_page($id, $referer, $link);
+		track_visit_page($id, $referer);
 	}
 
 	return $id ? $id : 0;
 }
 
-function track_get_visitor_by_id($visitorid, $link)
+function track_get_visitor_by_id($visitorid)
 {
-	global $mysqlprefix;
-
-	$visitor = select_one_row(
-		"select * from ${mysqlprefix}chatsitevisitor where visitorid = $visitorid", $link);
-
-	return $visitor;
+	$db = Database::getInstance();
+	return $db->query(
+		"select * from {chatsitevisitor} where visitorid = ?",
+		array($visitorid),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 }
 
-function track_get_visitor_by_threadid($threadid, $link)
+function track_get_visitor_by_threadid($threadid)
 {
-	global $mysqlprefix;
-
-	$visitor = select_one_row(
-		"select * from ${mysqlprefix}chatsitevisitor where threadid = $threadid", $link);
-
-	return $visitor;
+	$db = Database::getInstance();
+	return $db->query(
+		"select * from {chatsitevisitor} where threadid = ?",
+		array($threadid),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 }
 
-function track_visit_page($visitorid, $page, $link)
+function track_visit_page($visitorid, $page)
 {
-	global $mysqlprefix;
-	
+	$db = Database::getInstance();
+
 	if (empty($page)) {
 		return;
 	}
-	$lastpage = select_one_row(sprintf("select address from ${mysqlprefix}visitedpage where visitorid = '%s' order by visittime desc limit 1",
-				db_escape_string($visitorid)), $link);
+	$lastpage = $db->query(
+		"select address from {visitedpage} where visitorid = ? " .
+		"order by visittime desc limit 1",
+		array($visitorid),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 	if ( $lastpage['address'] != $page ) {
-		perform_query(sprintf("insert into ${mysqlprefix}visitedpage (visitorid, address, visittime) values ('%s', '%s', CURRENT_TIMESTAMP)",
-					db_escape_string($visitorid),
-					db_escape_string($page)), $link);
-		perform_query(sprintf("insert into ${mysqlprefix}visitedpagestatistics (address, visittime) values ('%s', CURRENT_TIMESTAMP)",
-					db_escape_string($page)), $link);
+		$db->query(
+			"insert into {visitedpage} (visitorid, address, visittime) " .
+			"values (?, ?, CURRENT_TIMESTAMP)",
+			array($visitorid, $page)
+		);
+		$db->query(
+			"insert into {visitedpagestatistics} (address, visittime) " .
+			"values (?, CURRENT_TIMESTAMP)",
+			array($page)
+		);
 	}
 }
 
-function track_get_path($visitor, $link)
+function track_get_path($visitor)
 {
-	global $mysqlprefix;
-	$query_result = perform_query(sprintf("select address, UNIX_TIMESTAMP(visittime) as visittime from ${mysqlprefix}visitedpage where visitorid = '%s'",
-				db_escape_string($visitor['visitorid'])), $link);
+	$db = Database::getInstance();
+	$query_result = $db->query(
+		"select address, UNIX_TIMESTAMP(visittime) as visittime from {visitedpage} " .
+		"where visitorid = ?",
+		array($visitor['visitorid']),
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
 	$result = array();
-	while( $page = db_fetch_assoc($query_result) ){
+	foreach ($query_result as $page) {
 		$result[$page['visittime']] = $page['address'];
 	}
 	return $result;
diff --git a/src/messenger/webim/mail.php b/src/messenger/webim/mail.php
index bcdf01f7..ac2a6f7b 100644
--- a/src/messenger/webim/mail.php
+++ b/src/messenger/webim/mail.php
@@ -63,9 +63,7 @@ loadsettings();
 $subject = getstring("mail.user.history.subject");
 $body = getstring2("mail.user.history.body", array($thread['userName'],$history,$settings['title'],$settings['hosturl']) );
 
-$link = connect();
-webim_mail($email, $webim_mailbox, $subject, $body, $link);
-close_connection($link);
+webim_mail($email, $webim_mailbox, $subject, $body);
 
 setup_logo($group);
 expand("styles/dialogs", getchatstyle(), "mailsent.tpl");
diff --git a/src/messenger/webim/operator/ban.php b/src/messenger/webim/operator/ban.php
index 0f1df186..29b0d2dd 100644
--- a/src/messenger/webim/operator/ban.php
+++ b/src/messenger/webim/operator/ban.php
@@ -46,9 +46,7 @@ if (isset($_POST['address'])) {
 		$errors[] = no_field("form.field.ban_comment");
 	}
 
-	$link = connect();
-	$existing_ban = ban_for_addr_($address, $link);
-	close_connection($link);
+	$existing_ban = ban_for_addr($address);
 
 	if ((!$banId && $existing_ban) ||
 		($banId && $existing_ban && $banId != $existing_ban['banid'])) {
@@ -56,24 +54,30 @@ if (isset($_POST['address'])) {
 	}
 
 	if (count($errors) == 0) {
-		$link = connect();
+		$db = Database::getInstance();
 		$utime = time() + $days * 24 * 60 * 60;
 		if (!$banId) {
-			$query = sprintf(
-				"insert into ${mysqlprefix}chatban (dtmcreated,dtmtill,address,comment) values (CURRENT_TIMESTAMP,%s,'%s','%s')",
-				"FROM_UNIXTIME($utime)",
-				db_escape_string($address, $link),
-				db_escape_string($comment, $link));
-			perform_query($query, $link);
+			$db->query(
+				"insert into {chatban} (dtmcreated,dtmtill,address,comment) " .
+				"values (CURRENT_TIMESTAMP,FROM_UNIXTIME(?),?,?)",
+				array(
+					$utime,
+					$address,
+					 $comment
+				)
+			);
 		} else {
-			$query = sprintf(
-				"update ${mysqlprefix}chatban set dtmtill = %s,address = '%s',comment = '%s' where banid = $banId",
-				"FROM_UNIXTIME($utime)",
-				db_escape_string($address, $link),
-				db_escape_string($comment, $link));
-			perform_query($query, $link);
+			$db->query(
+				"update {chatban} set dtmtill = FROM_UNIXTIME(?),address = ?, " .
+				"comment = ? where banid = ?",
+				array(
+					$utime,
+					$address,
+					$comment,
+					$banId
+				)
+			);
 		}
-		close_connection($link);
 
 		if (!$threadid) {
 			header("Location: $webimroot/operator/blocked.php");
@@ -91,9 +95,13 @@ if (isset($_POST['address'])) {
 	}
 } else if (isset($_GET['id'])) {
 	$banId = verifyparam('id', "/^\d{1,9}$/");
-	$link = connect();
-	$ban = select_one_row("select banid,(unix_timestamp(dtmtill)-unix_timestamp(CURRENT_TIMESTAMP)) as days,address,comment from ${mysqlprefix}chatban where banid = $banId", $link);
-	close_connection($link);
+	$db = Database::getInstance();
+	$ban = $db->query(
+		"select banid,(unix_timestamp(dtmtill)-unix_timestamp(CURRENT_TIMESTAMP))" .
+		" as days,address,comment from {chatban} where banid = ?",
+		array($banId),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 
 	if ($ban) {
 		$page['banId'] = topage($ban['banid']);
diff --git a/src/messenger/webim/operator/blocked.php b/src/messenger/webim/operator/blocked.php
index 8bf373ea..62b727e4 100644
--- a/src/messenger/webim/operator/blocked.php
+++ b/src/messenger/webim/operator/blocked.php
@@ -26,7 +26,7 @@ $errors = array();
 
 setlocale(LC_TIME, getstring("time.locale"));
 
-$link = connect();
+$db = Database::getInstance();
 
 if (isset($_GET['act']) && $_GET['act'] == 'del') {
 	$banId = isset($_GET['id']) ? $_GET['id'] : "";
@@ -36,15 +36,17 @@ if (isset($_GET['act']) && $_GET['act'] == 'del') {
 	}
 
 	if (count($errors) == 0) {
-		perform_query("delete from ${mysqlprefix}chatban where banid = $banId", $link);
+		$db->query("delete from {chatban} where banid = ?", array($banId));
 		header("Location: $webimroot/operator/blocked.php");
 		exit;
 	}
 }
 
-$blockedList = select_multi_assoc("select banid,unix_timestamp(dtmtill) as till,address,comment from ${mysqlprefix}chatban", $link);
-
-close_connection($link);
+$blockedList = $db->query(
+	"select banid,unix_timestamp(dtmtill) as till,address,comment from {chatban}",
+	NULL,
+	array('return_rows' => Database::RETURN_ONE_ROW)
+);
 
 setup_pagination($blockedList);
 
diff --git a/src/messenger/webim/operator/canned.php b/src/messenger/webim/operator/canned.php
index 13d003f7..11fe3332 100644
--- a/src/messenger/webim/operator/canned.php
+++ b/src/messenger/webim/operator/canned.php
@@ -57,9 +57,7 @@ if ($groupid) {
 	}
 }
 
-$link = connect();
-$allgroups = in_isolation($operator)?get_all_groups_for_operator($operator, $link):get_all_groups($link);
-close_connection($link);
+$allgroups = in_isolation($operator)?get_all_groups_for_operator($operator):get_all_groups();
 $page['groups'] = array();
 $page['groups'][] = array('groupid' => '', 'vclocalname' => getlocal("page.gen_button.default_group"));
 foreach ($allgroups as $g) {
@@ -76,9 +74,8 @@ if (isset($_GET['act']) && $_GET['act'] == 'delete') {
 	}
 
 	if (count($errors) == 0) {
-		$link = connect();
-		perform_query("delete from ${mysqlprefix}chatresponses where id = $key", $link);
-		close_connection($link);
+		$db = Database::getInstance();
+		$db->query("delete from {chatresponses} where id = ?", array($key));
 		header("Location: $webimroot/operator/canned.php?lang=$lang&group=$groupid");
 		exit;
 	}
diff --git a/src/messenger/webim/operator/group.php b/src/messenger/webim/operator/group.php
index 797968c1..3db09f99 100644
--- a/src/messenger/webim/operator/group.php
+++ b/src/messenger/webim/operator/group.php
@@ -27,11 +27,12 @@ $groupid = '';
 
 function group_by_name($name)
 {
-	global $mysqlprefix;
-	$link = connect();
-	$group = select_one_row(
-		"select * from ${mysqlprefix}chatgroup where vclocalname = '" . db_escape_string($name) . "'", $link);
-	close_connection($link);
+	$db = Database::getInstance();
+	$group = $db->query(
+		"select * from {chatgroup} where vclocalname = ?",
+		array($name),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 	return $group;
 }
 
@@ -55,39 +56,49 @@ function check_group_params($group, $extra_params = NULL)
 }
 
 /**
+ * Creates group
+ *
  * @param array $group Operators' group.
  * The $group array must contains following keys:
  * name, description, commonname, commondescription,
  * email, weight, parent, title, chattitle, hosturl, logo
+ * @return array Created group
  */
 function create_group($group)
 {
-	global $mysqlprefix;
+	$db = Database::getInstance();
 	check_group_params($group);
-	$link = connect();
-	$query = sprintf(
-		"insert into ${mysqlprefix}chatgroup (parent, vclocalname,vclocaldescription,vccommonname,vccommondescription,vcemail,vctitle,vcchattitle,vchosturl,vclogo,iweight) values (%s, '%s','%s','%s','%s','%s','%s','%s','%s','%s',%u)",
-		($group['parent']?(int)$group['parent']:'NULL'),
-		db_escape_string($group['name']),
-		db_escape_string($group['description']),
-		db_escape_string($group['commonname']),
-		db_escape_string($group['commondescription']),
-		db_escape_string($group['email']),
-		db_escape_string($group['title']),
-		db_escape_string($group['chattitle']),
-		db_escape_string($group['hosturl']),
-		db_escape_string($group['logo']),
-		$group['weight']);
+	$db->query(
+		"insert into {chatgroup} (parent, vclocalname,vclocaldescription,vccommonname, " .
+		"vccommondescription,vcemail,vctitle,vcchattitle,vchosturl,vclogo,iweight) " .
+		"values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+		array(
+			($group['parent'] ? (int)$group['parent'] : 'NULL'),
+			$group['name'],
+			$group['description'],
+			$group['commonname'],
+			$group['commondescription'],
+			$group['email'],
+			$group['title'],
+			$group['chattitle'],
+			$group['hosturl'],
+			$group['logo'],
+			$group['weight']
+		)
+	);
+	$id = $db->insertedId();
 
-	perform_query($query, $link);
-	$id = db_insert_id($link);
-
-	$newdep = select_one_row("select * from ${mysqlprefix}chatgroup where groupid = $id", $link);
-	close_connection($link);
+	$newdep = $db->query(
+		"select * from {chatgroup} where groupid = ?",
+		array($id),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 	return $newdep;
 }
 
 /**
+ * Updates group info
+ *
  * @param array $group Operators' group.
  * The $group array must contains following keys:
  * id, name, description, commonname, commondescription,
@@ -95,30 +106,34 @@ function create_group($group)
  */
 function update_group($group)
 {
-	global $mysqlprefix;
+	$db = Database::getInstance();
 	check_group_params($group, array('id'));
-	$link = connect();
-	$query = sprintf(
-		"update ${mysqlprefix}chatgroup set parent = %s, vclocalname = '%s', vclocaldescription = '%s', vccommonname = '%s', vccommondescription = '%s', vcemail = '%s', vctitle = '%s', vcchattitle = '%s', vchosturl = '%s', vclogo = '%s', iweight = %u where groupid = %s",
-		($group['parent']?(int)$group['parent']:'NULL'),
-		db_escape_string($group['name']),
-		db_escape_string($group['description']),
-		db_escape_string($group['commonname']),
-		db_escape_string($group['commondescription']),
-		db_escape_string($group['email']),
-		db_escape_string($group['title']),
-		db_escape_string($group['chattitle']),
-		db_escape_string($group['hosturl']),
-		db_escape_string($group['logo']),
-		$group['weight'],
-		$group['id']);
-	perform_query($query, $link);
+	$db->query(
+		"update {chatgroup} set parent = ?, vclocalname = ?, vclocaldescription = ?, " .
+		"vccommonname = ?, vccommondescription = ?, vcemail = ?, vctitle = ?, " .
+		"vcchattitle = ?, vchosturl = ?, vclogo = ?, iweight = ? where groupid = ?",
+		array(
+			($group['parent'] ? (int)$group['parent'] : 'NULL'),
+			$group['name'],
+			$group['description'],
+			$group['commonname'],
+			$group['commondescription'],
+			$group['email'],
+			$group['title'],
+			$group['chattitle'],
+			$group['hosturl'],
+			$group['logo'],
+			$group['weight'],
+			$group['id']
+		)
+	);
 
 	if ($group['parent']) {
-		$query = sprintf("update ${mysqlprefix}chatgroup set parent = NULL where parent = %u", $group['id']);
-		perform_query($query, $link);
+		$db->query(
+			"update {chatgroup} set parent = NULL where parent = ?",
+			array($group['id'])
+		);
 	}
-	close_connection($link);
 }
 
 if (isset($_POST['name'])) {
diff --git a/src/messenger/webim/operator/groupmembers.php b/src/messenger/webim/operator/groupmembers.php
index f0e0182d..deff3840 100644
--- a/src/messenger/webim/operator/groupmembers.php
+++ b/src/messenger/webim/operator/groupmembers.php
@@ -23,34 +23,35 @@ $operator = check_login();
 
 function get_group_members($groupid)
 {
-	global $mysqlprefix;
-	$link = connect();
-	$query = "select operatorid from ${mysqlprefix}chatgroupoperator where groupid = $groupid";
-	$result = select_multi_assoc($query, $link);
-	close_connection($link);
-	return $result;
+	$db = Database::getInstance();
+	return $db->query(
+		"select operatorid from {chatgroupoperator} where groupid = ?",
+		array($groupid),
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
 }
 
 function update_group_members($groupid, $newvalue)
 {
-	global $mysqlprefix;
-	$link = connect();
-	perform_query("delete from ${mysqlprefix}chatgroupoperator where groupid = $groupid", $link);
+	$db = Database::getInstance();
+	$db->query("delete from {chatgroupoperator} where groupid = ?", array($groupid));
+
 	foreach ($newvalue as $opid) {
-		perform_query("insert into ${mysqlprefix}chatgroupoperator (groupid, operatorid) values ($groupid,$opid)", $link);
+		$db->query(
+			"insert into {chatgroupoperator} (groupid, operatorid) values (?, ?)",
+			array($groupid,$opid)
+		);
 	}
-	close_connection($link);
 }
 
 function get_operators()
 {
-	global $mysqlprefix;
-	$link = connect();
-
-	$query = "select * from ${mysqlprefix}chatoperator order by vclogin";
-	$result = select_multi_assoc($query, $link);
-	close_connection($link);
-	return $result;
+	$db = Database::getInstance();
+	return $db->query(
+		"select * from {chatoperator} order by vclogin",
+		NULL,
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
 }
 
 $groupid = verifyparam("gid", "/^\d{1,9}$/");
diff --git a/src/messenger/webim/operator/groups.php b/src/messenger/webim/operator/groups.php
index bf60f2d4..2949c0d4 100644
--- a/src/messenger/webim/operator/groups.php
+++ b/src/messenger/webim/operator/groups.php
@@ -33,11 +33,10 @@ if (isset($_GET['act']) && $_GET['act'] == 'del') {
 	}
 
 	if (count($errors) == 0) {
-		$link = connect();
-		perform_query("delete from ${mysqlprefix}chatgroup where groupid = $groupid", $link);
-		perform_query("delete from ${mysqlprefix}chatgroupoperator where groupid = $groupid", $link);
-		perform_query("update ${mysqlprefix}chatthread set groupid = 0 where groupid = $groupid", $link);
-		close_connection($link);
+		$db = Database::getInstance();
+		$db->query("delete from {chatgroup} where groupid = ?", array($groupid));
+		$db->query("delete from {chatgroupoperator} where groupid = ?", array($groupid));
+		$db->query("update {chatthread} set groupid = 0 where groupid = ?",array($groupid));
 		header("Location: $webimroot/operator/groups.php");
 		exit;
 	}
@@ -59,9 +58,7 @@ function is_away($group)
 $page = array();
 $sort['by'] = verifyparam("sortby", "/^(name|lastseen|weight)$/", "name");
 $sort['desc'] = (verifyparam("sortdirection", "/^(desc|asc)$/", "desc") == "desc");
-$link = connect();
-$page['groups'] = get_sorted_groups($link, $sort);
-close_connection($link);
+$page['groups'] = get_sorted_groups($sort);
 $page['formsortby'] = $sort['by'];
 $page['formsortdirection'] = $sort['desc']?'desc':'asc';
 $page['canmodify'] = is_capable($can_administrate, $operator);
diff --git a/src/messenger/webim/operator/history.php b/src/messenger/webim/operator/history.php
index f2529297..b2619000 100644
--- a/src/messenger/webim/operator/history.php
+++ b/src/messenger/webim/operator/history.php
@@ -35,44 +35,50 @@ $searchType = verifyparam('type', '/^(all|message|operator|visitor)$/', 'all');
 $searchInSystemMessages = (verifyparam('insystemmessages', '/^on$/', 'off') == 'on') || !$query;
 
 if ($query !== false) {
-	$link = connect();
+	$db = Database::getInstance();
+	$groups = $db->query(
+		"select {chatgroup}.groupid as groupid, vclocalname " .
+		"from {chatgroup} order by vclocalname",
+		NULL,
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
 
-	$result = perform_query("select ${mysqlprefix}chatgroup.groupid as groupid, vclocalname " .
-						  "from ${mysqlprefix}chatgroup order by vclocalname", $link);
 	$groupName = array();
-	while ($group = db_fetch_assoc($result)) {
+	foreach ($groups as $group) {
 		$groupName[$group['groupid']] = $group['vclocalname'];
 	}
-	db_free_result($result);
 	$page['groupName'] = $groupName;
 
-	$escapedQuery = db_escape_string($query, $link);
+	$values = array(
+		':query' => "%{$escapedQuery}%",
+		':kind_user' => $kind_user,
+		':kind_agent' => $kind_agent
+	);
+
 	$searchConditions = array();
 	if ($searchType == 'message' || $searchType == 'all') {
-		$searchConditions[] = "(${mysqlprefix}chatmessage.tmessage LIKE '%%$escapedQuery%%'" .
-					($searchInSystemMessages?'':" AND (${mysqlprefix}chatmessage.ikind = $kind_user OR ${mysqlprefix}chatmessage.ikind = $kind_agent)") .
+		$searchConditions[] = "({chatmessage}.tmessage LIKE :query" .
+					($searchInSystemMessages?'':" AND ({chatmessage}.ikind = :kind_user OR {chatmessage}.ikind = :kind_agent)") .
 					")";
 	}
 	if ($searchType == 'operator' || $searchType == 'all') {
-		$searchConditions[] = "(${mysqlprefix}chatthread.agentName LIKE '%%$escapedQuery%%')";
+		$searchConditions[] = "({chatthread}.agentName LIKE :query)";
 	}
 	if ($searchType == 'visitor' || $searchType == 'all') {
-		$searchConditions[] = "(${mysqlprefix}chatthread.userName LIKE '%%$escapedQuery%%')";
-		$searchConditions[] = "(${mysqlprefix}chatthread.remote LIKE '%%$escapedQuery%%')";
+		$searchConditions[] = "({chatthread}.userName LIKE :query)";
+		$searchConditions[] = "({chatthread}.remote LIKE :query)";
 	}
-	select_with_pagintation("DISTINCT unix_timestamp(${mysqlprefix}chatthread.dtmcreated) as created, " .
-							"unix_timestamp(${mysqlprefix}chatthread.dtmmodified) as modified, ${mysqlprefix}chatthread.threadid, " .
-							"${mysqlprefix}chatthread.remote, ${mysqlprefix}chatthread.agentName, ${mysqlprefix}chatthread.userName, groupid, " .
-							"messageCount as size",
-							"${mysqlprefix}chatthread, ${mysqlprefix}chatmessage",
-							array(
-								 "${mysqlprefix}chatmessage.threadid = ${mysqlprefix}chatthread.threadid",
-								 "(" . implode(' or ', $searchConditions)  .  ")"
-							),
-							"order by created DESC",
-							"DISTINCT ${mysqlprefix}chatthread.dtmcreated", $link);
-
-	close_connection($link);
+	select_with_pagintation("DISTINCT unix_timestamp({chatthread}.dtmcreated) as created, " .
+		"unix_timestamp({chatthread}.dtmmodified) as modified, {chatthread}.threadid, " .
+		"{chatthread}.remote, {chatthread}.agentName, {chatthread}.userName, groupid, " .
+		"messageCount as size",
+		"{chatthread}, {chatmessage}",
+		array(
+			"{chatmessage}.threadid = {chatthread}.threadid",
+			"(" . implode(' or ', $searchConditions)  .  ")"
+		),
+		"order by created DESC",
+		"DISTINCT {chatthread}.dtmcreated", $values);
 
 	$page['formq'] = topage($query);
 } else {
diff --git a/src/messenger/webim/operator/index.php b/src/messenger/webim/operator/index.php
index 4ef0e520..b156eb68 100644
--- a/src/messenger/webim/operator/index.php
+++ b/src/messenger/webim/operator/index.php
@@ -21,10 +21,8 @@ require_once('../libs/operator.php');
 $operator = check_login();
 force_password($operator);
 
-$link = connect();
-loadsettings_($link);
-$isonline = is_operator_online($operator['operatorid'], $link);
-close_connection($link);
+loadsettings();
+$isonline = is_operator_online($operator['operatorid']);
 
 $page = array(
 	'version' => $version,
diff --git a/src/messenger/webim/operator/invitationstate.php b/src/messenger/webim/operator/invitationstate.php
index 7f76e5c6..81359987 100644
--- a/src/messenger/webim/operator/invitationstate.php
+++ b/src/messenger/webim/operator/invitationstate.php
@@ -27,9 +27,7 @@ $visitorid = verifyparam("visitor", "/^\d{1,8}$/");
 
 $errors = array();
 
-$link = connect();
-$invitation = invitation_state($visitorid, $link);
-close_connection($link);
+$invitation = invitation_state($visitorid);
 
 start_xml_output();
 echo '<invitation>';
diff --git a/src/messenger/webim/operator/invite.php b/src/messenger/webim/operator/invite.php
index ee4b88b8..ed975669 100644
--- a/src/messenger/webim/operator/invite.php
+++ b/src/messenger/webim/operator/invite.php
@@ -25,11 +25,9 @@ loadsettings();
 
 $visitorid = verifyparam("visitor", "/^\d{1,8}$/");
 
-$link = connect();
-if (!invitation_invite($visitorid, $operator['operatorid'], $link)) {
+if (!invitation_invite($visitorid, $operator['operatorid'])) {
     die("Invitation failed!");
 }
-close_connection($link);
 
 $page = array();
 $page['visitor'] = $visitorid;
diff --git a/src/messenger/webim/operator/operators.php b/src/messenger/webim/operator/operators.php
index b28267c0..a5bd4b71 100644
--- a/src/messenger/webim/operator/operators.php
+++ b/src/messenger/webim/operator/operators.php
@@ -48,11 +48,15 @@ if (isset($_GET['act'])) {
 		}
 
 		if (count($errors) == 0) {
-			$link = connect();
-			perform_query("delete from ${mysqlprefix}chatgroupoperator where operatorid = $operatorid", $link);
-			perform_query("delete from ${mysqlprefix}chatoperator where operatorid = $operatorid", $link);
-			close_connection($link);
-
+			$db = Database::getInstance();
+			$db->query(
+				"delete from {chatgroupoperator} where operatorid = ?",
+				array($operatorid)
+			);
+			$db->query(
+				"delete from {chatoperator} where operatorid = ?",
+				array($operatorid)
+			);
 			header("Location: $webimroot/operator/operators.php");
 			exit;
 		}
@@ -77,9 +81,11 @@ if (isset($_GET['act'])) {
 		}
 
 		if (count($errors) == 0) {
-			$link = connect();
-			perform_query("update ${mysqlprefix}chatoperator set idisabled = ".($act_disable?'1':'0')." where operatorid = $operatorid", $link);
-			close_connection($link);
+			$db = Database::getInstance();
+			$db->query(
+				"update {chatoperator} set idisabled = ? where operatorid = ?",
+				array(($act_disable ? '1' : '0'), $operatorid)
+			);
 
 			header("Location: $webimroot/operator/operators.php");
 			exit;
diff --git a/src/messenger/webim/operator/opgroups.php b/src/messenger/webim/operator/opgroups.php
index efe9414b..9b76557f 100644
--- a/src/messenger/webim/operator/opgroups.php
+++ b/src/messenger/webim/operator/opgroups.php
@@ -23,22 +23,25 @@ $operator = check_login();
 
 function update_operator_groups($operatorid, $newvalue)
 {
-	global $mysqlprefix;
-	$link = connect();
-	perform_query("delete from ${mysqlprefix}chatgroupoperator where operatorid = $operatorid", $link);
+	$db = Database::getInstance();
+	$db->query(
+		"delete from {chatgroupoperator} where operatorid = ?",
+		array($operatorid)
+	);
+
 	foreach ($newvalue as $groupid) {
-		perform_query("insert into ${mysqlprefix}chatgroupoperator (groupid, operatorid) values ($groupid,$operatorid)", $link);
+		$db->query(
+			"insert into {chatgroupoperator} (groupid, operatorid) values (?,?)",
+			array($groupid, $operatorid)
+		);
 	}
-	close_connection($link);
 }
 
 $operator_in_isolation = in_isolation($operator);
 
 $opId = verifyparam("op", "/^\d{1,9}$/");
 $page = array('opid' => $opId);
-$link = connect();
-$page['groups'] = $operator_in_isolation?get_all_groups_for_operator($operator, $link):get_all_groups($link);
-close_connection($link);
+$page['groups'] = $operator_in_isolation?get_all_groups_for_operator($operator):get_all_groups();
 $errors = array();
 
 $canmodify = is_capable($can_administrate, $operator);
diff --git a/src/messenger/webim/operator/permissions.php b/src/messenger/webim/operator/permissions.php
index ee57c9d2..ad21682d 100644
--- a/src/messenger/webim/operator/permissions.php
+++ b/src/messenger/webim/operator/permissions.php
@@ -24,12 +24,11 @@ csrfchecktoken();
 
 function update_operator_permissions($operatorid, $newvalue)
 {
-	global $mysqlprefix;
-	$link = connect();
-	$query = "update ${mysqlprefix}chatoperator set iperm = $newvalue where operatorid = $operatorid";
-
-	perform_query($query, $link);
-	close_connection($link);
+	$db = Database::getInstance();
+	$db->query(
+		"update {chatoperator} set iperm = ? where operatorid = ?",
+		array($newvalue, $operatorid)
+	);
 }
 
 $opId = verifyparam("op", "/^\d{1,9}$/");
diff --git a/src/messenger/webim/operator/redirect.php b/src/messenger/webim/operator/redirect.php
index 5b4f90eb..e106a21e 100644
--- a/src/messenger/webim/operator/redirect.php
+++ b/src/messenger/webim/operator/redirect.php
@@ -41,13 +41,11 @@ if (isset($_GET['nextGroup'])) {
 	if ($nextGroup) {
 		$page['message'] = getlocal2("chat.redirected.group.content", array(topage(get_group_name($nextGroup))));
 		if ($thread['istate'] == $state_chatting) {
-			$link = connect();
 			commit_thread($threadid,
-						  array("istate" => $state_waiting, "nextagent" => 0, "groupid" => $nextid, "agentId" => 0, "agentName" => "''"), $link);
+						  array("istate" => $state_waiting, "nextagent" => 0, "groupid" => $nextid, "agentId" => 0, "agentName" => "''"));
 			post_message_($thread['threadid'], $kind_events,
 						  getstring2_("chat.status.operator.redirect",
-									  array(get_operator_name($operator)), $thread['locale']), $link);
-			close_connection($link);
+									  array(get_operator_name($operator)), $thread['locale']));
 		} else {
 			$errors[] = getlocal("chat.redirect.cannot");
 		}
@@ -62,18 +60,26 @@ if (isset($_GET['nextGroup'])) {
 	if ($nextOperator) {
 		$page['message'] = getlocal2("chat.redirected.content", array(topage(get_operator_name($nextOperator))));
 		if ($thread['istate'] == $state_chatting) {
-			$link = connect();
 			$threadupdate = array("istate" => $state_waiting, "nextagent" => $nextid, "agentId" => 0);
 			if ($thread['groupid'] != 0) {
-				if (FALSE === select_one_row("select groupid from ${mysqlprefix}chatgroupoperator where operatorid = $nextid and groupid = " . $thread['groupid'], $link)) {
+				$db = Database::getInstance();
+				list($groups_count) = $db->query(
+					"select count(*) AS count from {chatgroupoperator} " .
+					"where operatorid = ? and groupid = ?",
+					array($nextid, $thread['groupid']),
+					array(
+						'return_rows' => Database::RETURN_ONE_ROW, 
+						'fetch_type' => Database::FETCH_NUM
+					)
+				);
+				if ($groups_count === 0) {
 					$threadupdate['groupid'] = 0;
 				}
 			}
-			commit_thread($threadid, $threadupdate, $link);
+			commit_thread($threadid, $threadupdate);
 			post_message_($thread['threadid'], $kind_events,
 						  getstring2_("chat.status.operator.redirect",
-									  array(get_operator_name($operator)), $thread['locale']), $link);
-			close_connection($link);
+									  array(get_operator_name($operator)), $thread['locale']));
 		} else {
 			$errors[] = getlocal("chat.redirect.cannot");
 		}
diff --git a/src/messenger/webim/operator/resetpwd.php b/src/messenger/webim/operator/resetpwd.php
index fe1c5d55..b3a48d4a 100644
--- a/src/messenger/webim/operator/resetpwd.php
+++ b/src/messenger/webim/operator/resetpwd.php
@@ -48,10 +48,12 @@ if (count($errors) == 0 && isset($_POST['password'])) {
 	if (count($errors) == 0) {
 		$page['isdone'] = true;
 
-		$link = connect();
-		$query = "update ${mysqlprefix}chatoperator set vcpassword = '" . md5($password) . "', vcrestoretoken = '' where operatorid = " . $opId;
-		perform_query($query, $link);
-		close_connection($link);
+		$db = Database::getInstance();
+		$db->query(
+			"update {chatoperator} set vcpassword = ?, vcrestoretoken = '' " .
+			"where operatorid = ?",
+			array(md5($password), $opId)
+		);
 
 		$page['loginname'] = $operator['vclogin'];
 		start_html_output();
diff --git a/src/messenger/webim/operator/restore.php b/src/messenger/webim/operator/restore.php
index b96f197c..b47737bd 100644
--- a/src/messenger/webim/operator/restore.php
+++ b/src/messenger/webim/operator/restore.php
@@ -40,13 +40,15 @@ if (isset($_POST['loginoremail'])) {
 	if (count($errors) == 0) {
 		$token = md5((time() + microtime()) . rand(0, 99999999));
 
-		$link = connect();
-		$query = "update ${mysqlprefix}chatoperator set dtmrestore = CURRENT_TIMESTAMP, vcrestoretoken = '$token' where operatorid = " . $torestore['operatorid'];
-		perform_query($query, $link);
+		$db = Database::getInstance();
+		$db->query(
+			"update {chatoperator} set dtmrestore = CURRENT_TIMESTAMP, " .
+			"vcrestoretoken = ? where operatorid = ?",
+			array($token, $torestore['operatorid'])
+		);
 
 		$href = get_app_location(true, false) . "/operator/resetpwd.php?id=" . $torestore['operatorid'] . "&token=$token";
-		webim_mail($email, $email, getstring("restore.mailsubj"), getstring2("restore.mailtext", array(get_operator_name($torestore), $href)), $link);
-		close_connection($link);
+		webim_mail($email, $email, getstring("restore.mailsubj"), getstring2("restore.mailtext", array(get_operator_name($torestore), $href)));
 
 		$page['isdone'] = true;
 		require('../view/restore.php');
diff --git a/src/messenger/webim/operator/statistics.php b/src/messenger/webim/operator/statistics.php
index 356b24e8..4c71c643 100644
--- a/src/messenger/webim/operator/statistics.php
+++ b/src/messenger/webim/operator/statistics.php
@@ -71,31 +71,61 @@ if ($start > $end) {
 }
 
 $activetab = 0;
-$link = connect();
+$db = Database::getInstance();
 if ($statisticstype == 'bydate') {
-	$page['reportByDate'] = select_multi_assoc("select DATE(t.dtmcreated) as date, COUNT(distinct t.threadid) as threads, SUM(m.ikind = $kind_agent) as agents, SUM(m.ikind = $kind_user) as users, ROUND(AVG(unix_timestamp(t.dtmchatstarted)-unix_timestamp(t.dtmcreated)),1) as avgwaitingtime, ROUND(AVG(tmp.lastmsgtime - unix_timestamp(t.dtmchatstarted)),1) as avgchattime " .
-											"from ${mysqlprefix}chatmessage m, ${mysqlprefix}chatthread t, (SELECT i.threadid, unix_timestamp(MAX(i.dtmcreated)) AS lastmsgtime  FROM ${mysqlprefix}chatmessage i WHERE (ikind = $kind_user OR ikind = $kind_agent) GROUP BY i.threadid) tmp " .
-											"where m.threadid = t.threadid AND tmp.threadid = t.threadid AND unix_timestamp(t.dtmchatstarted) <> 0 AND unix_timestamp(m.dtmcreated) >= $start AND unix_timestamp(m.dtmcreated) < $end group by DATE(m.dtmcreated) order by m.dtmcreated desc", $link);
-
-	$page['reportByDateTotal'] = select_one_row("select DATE(t.dtmcreated) as date, COUNT(distinct t.threadid) as threads, SUM(m.ikind = $kind_agent) as agents, SUM(m.ikind = $kind_user) as users, ROUND(AVG(unix_timestamp(t.dtmchatstarted)-unix_timestamp(t.dtmcreated)),1) as avgwaitingtime, ROUND(AVG(tmp.lastmsgtime - unix_timestamp(t.dtmchatstarted)),1) as avgchattime " .
-											"from ${mysqlprefix}chatmessage m, ${mysqlprefix}chatthread t, (SELECT i.threadid, unix_timestamp(MAX(i.dtmcreated)) AS lastmsgtime  FROM ${mysqlprefix}chatmessage i WHERE (ikind = $kind_user OR ikind = $kind_agent) GROUP BY i.threadid) tmp " .
-											"where m.threadid = t.threadid AND tmp.threadid = t.threadid AND unix_timestamp(t.dtmchatstarted) <> 0 AND unix_timestamp(m.dtmcreated) >= $start AND unix_timestamp(m.dtmcreated) < $end", $link);
+	$page['reportByDate'] = $db->query(
+		"select DATE(t.dtmcreated) as date, COUNT(distinct t.threadid) as threads, SUM(m.ikind = :kind_agent) as agents, SUM(m.ikind = :kind_user) as users, ROUND(AVG(unix_timestamp(t.dtmchatstarted)-unix_timestamp(t.dtmcreated)),1) as avgwaitingtime, ROUND(AVG(tmp.lastmsgtime - unix_timestamp(t.dtmchatstarted)),1) as avgchattime " .
+		"from {chatmessage} m, {chatthread} t, (SELECT i.threadid, unix_timestamp(MAX(i.dtmcreated)) AS lastmsgtime  FROM {chatmessage} i WHERE (ikind = :kind_user OR ikind = :kind_agent) GROUP BY i.threadid) tmp " .
+		"where m.threadid = t.threadid AND tmp.threadid = t.threadid AND unix_timestamp(t.dtmchatstarted) <> 0 AND unix_timestamp(m.dtmcreated) >= :start AND unix_timestamp(m.dtmcreated) < :end group by DATE(m.dtmcreated) order by m.dtmcreated desc",
+		array(
+			':kind_agent' => $kind_agent,
+			':kind_user' => $kind_user,
+			':start' => $start,
+			':end' => $end
+		),
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
+	
+	$page['reportByDateTotal'] = $db->query(
+		"select DATE(t.dtmcreated) as date, COUNT(distinct t.threadid) as threads, SUM(m.ikind = :kind_agent) as agents, SUM(m.ikind = :kind_user) as users, ROUND(AVG(unix_timestamp(t.dtmchatstarted)-unix_timestamp(t.dtmcreated)),1) as avgwaitingtime, ROUND(AVG(tmp.lastmsgtime - unix_timestamp(t.dtmchatstarted)),1) as avgchattime " .
+		"from {chatmessage} m, {chatthread} t, (SELECT i.threadid, unix_timestamp(MAX(i.dtmcreated)) AS lastmsgtime FROM {chatmessage} i WHERE (ikind = :kind_user OR ikind = :kind_agent) GROUP BY i.threadid) tmp " .
+		"where m.threadid = t.threadid AND tmp.threadid = t.threadid AND unix_timestamp(t.dtmchatstarted) <> 0 AND unix_timestamp(m.dtmcreated) >= :start AND unix_timestamp(m.dtmcreated) < :end",
+		array(
+			':kind_agent' => $kind_agent,
+			':kind_user' => $kind_user,
+			':start' => $start,
+			':end' => $end
+		),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 	$activetab = 0;
 } elseif($statisticstype == 'byagent') {
-	$page['reportByAgent'] = select_multi_assoc("select vclocalename as name, COUNT(distinct threadid) as threads, SUM(ikind = $kind_agent) as msgs, AVG(CHAR_LENGTH(tmessage)) as avglen " .
-												"from ${mysqlprefix}chatmessage, ${mysqlprefix}chatoperator " .
-												"where agentId = operatorid AND unix_timestamp(dtmcreated) >= $start AND unix_timestamp(dtmcreated) < $end group by operatorid", $link);
+	$page['reportByAgent'] = $db->query(
+		"select vclocalename as name, COUNT(distinct threadid) as threads, " .
+		"SUM(ikind = :kind_agent) as msgs, AVG(CHAR_LENGTH(tmessage)) as avglen " .
+		"from {chatmessage}, {chatoperator} " .
+		"where agentId = operatorid AND unix_timestamp(dtmcreated) >= :start " .
+		"AND unix_timestamp(dtmcreated) < :end group by operatorid",
+		array(
+			':kind_agent' => $kind_agent,
+			':start' => $start,
+			':end' => $end
+		),
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
 	$activetab = 1;
 } elseif($statisticstype == 'bypage') {
-	$page['reportByPage'] = select_multi_assoc("SELECT COUNT(DISTINCT p.pageid) as visittimes, p.address, COUNT(DISTINCT t.threadid) as chattimes " .
-							"FROM ${mysqlprefix}visitedpagestatistics p LEFT OUTER JOIN ${mysqlprefix}chatthread t ON (p.address = t.referer AND DATE(p.visittime) = DATE(t.dtmcreated)) " .
-							"WHERE unix_timestamp(p.visittime) >= $start AND unix_timestamp(p.visittime) < $end GROUP BY p.address", $link);
+	$page['reportByPage'] = $db->query(
+		"SELECT COUNT(DISTINCT p.pageid) as visittimes, p.address, COUNT(DISTINCT t.threadid) as chattimes " .
+		"FROM {visitedpagestatistics} p LEFT OUTER JOIN {chatthread} t ON (p.address = t.referer AND DATE(p.visittime) = DATE(t.dtmcreated)) " .
+		"WHERE unix_timestamp(p.visittime) >= :start AND unix_timestamp(p.visittime) < :end GROUP BY p.address",
+		array(':start' => $start, ':end' => $end),
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
 	$activetab = 2;
 }
 $page['showresults'] = count($errors) == 0;
 
-close_connection($link);
-
 prepare_menu($operator);
 setup_statistics_tabs($activetab);
 start_html_output();
diff --git a/src/messenger/webim/operator/threadprocessor.php b/src/messenger/webim/operator/threadprocessor.php
index 820c7a76..eb8488e4 100644
--- a/src/messenger/webim/operator/threadprocessor.php
+++ b/src/messenger/webim/operator/threadprocessor.php
@@ -29,15 +29,16 @@ setlocale(LC_TIME, getstring("time.locale"));
 
 function thread_info($id)
 {
-	global $mysqlprefix;
-	$link = connect();
-	$thread = select_one_row("select userName,agentName,remote,userAgent," .
-							 "unix_timestamp(dtmmodified) as modified, unix_timestamp(dtmcreated) as created," .
-							 "vclocalname as groupName " .
-							 "from ${mysqlprefix}chatthread left join ${mysqlprefix}chatgroup on ${mysqlprefix}chatthread.groupid = ${mysqlprefix}chatgroup.groupid " .
-							 "where threadid = " . $id, $link);
-	close_connection($link);
-	return $thread;
+	$db = Database::getInstance();
+	return $db->query(
+		"select userName,agentName,remote,userAgent," .
+		"unix_timestamp(dtmmodified) as modified, unix_timestamp(dtmcreated) as created," .
+		"vclocalname as groupName " .
+		"from {chatthread} left join {chatgroup} on {chatthread}.groupid = {chatgroup}.groupid " .
+		"where threadid = ?",
+		array($id),
+		array('return_rows' => Database::RETURN_ONE_ROW)
+	);
 }
 
 
diff --git a/src/messenger/webim/operator/tracked.php b/src/messenger/webim/operator/tracked.php
index 716d2c14..ce6104d8 100644
--- a/src/messenger/webim/operator/tracked.php
+++ b/src/messenger/webim/operator/tracked.php
@@ -36,21 +36,19 @@ else {
     $visitorid = verifyparam("visitor", "/^\d{1,8}$/");
 }
 
-$link = connect();
 if (isset($threadid)) {
-    $visitor = track_get_visitor_by_threadid($threadid, $link);
+    $visitor = track_get_visitor_by_threadid($threadid);
     if (!$visitor) {
 	die("Wrong thread!");
     }
 }
 else {
-    $visitor = track_get_visitor_by_id($visitorid, $link);
+    $visitor = track_get_visitor_by_id($visitorid);
     if (!$visitor) {
 	die("Wrong visitor!");
     }
 }
-$path = track_get_path($visitor, $link);
-close_connection($link);
+$path = track_get_path($visitor);
 
 $page['entry'] = htmlspecialchars($visitor['entry']);
 $page['history'] = array();
diff --git a/src/messenger/webim/operator/update.php b/src/messenger/webim/operator/update.php
index 8f777669..ae4b4aef 100644
--- a/src/messenger/webim/operator/update.php
+++ b/src/messenger/webim/operator/update.php
@@ -46,18 +46,18 @@ $threadstate_key = array(
 	$state_loading => "chat.thread.state_loading"
 );
 
-function thread_to_xml($thread, $link)
+function thread_to_xml($thread)
 {
 	global $state_chatting, $threadstate_to_string, $threadstate_key,
-$webim_encoding, $operator, $settings,
-$can_viewthreads, $can_takeover, $mysqlprefix;
+		$webim_encoding, $operator, $settings,
+		$can_viewthreads, $can_takeover;
 	$state = $threadstate_to_string[$thread['istate']];
 	$result = "<thread id=\"" . $thread['threadid'] . "\" stateid=\"$state\"";
 	if ($state == "closed")
 		return $result . "/>";
 
 	$state = getstring($threadstate_key[$thread['istate']]);
-	$nextagent = $thread['nextagent'] != 0 ? operator_by_id_($thread['nextagent'], $link) : null;
+	$nextagent = $thread['nextagent'] != 0 ? operator_by_id($thread['nextagent']) : null;
 	$threadoperator = $nextagent ? get_operator_name($nextagent)
 			: ($thread['agentName'] ? $thread['agentName'] : "-");
 
@@ -76,7 +76,7 @@ $can_viewthreads, $can_takeover, $mysqlprefix;
 		$result .= " canban=\"true\"";
 	}
 
-	$banForThread = $settings['enableban'] == "1" ? ban_for_addr_($thread['remote'], $link) : false;
+	$banForThread = $settings['enableban'] == "1" ? ban_for_addr($thread['remote']) : false;
 	if ($banForThread) {
 		$result .= " ban=\"blocked\" banid=\"" . $banForThread['banid'] . "\"";
 	}
@@ -99,8 +99,12 @@ $can_viewthreads, $can_takeover, $mysqlprefix;
 	$userAgent = get_useragent_version($thread['userAgent']);
 	$result .= "<useragent>" . $userAgent . "</useragent>";
 	if ($thread["shownmessageid"] != 0) {
-		$query = "select tmessage from ${mysqlprefix}chatmessage where messageid = " . $thread["shownmessageid"];
-		$line = select_one_row($query, $link);
+		$db = Database::getInstance();
+		$line = $db->query(
+			"select tmessage from {chatmessage} where messageid = ?",
+			array($thread["shownmessageid"]),
+			array('return_rows' => Database::RETURN_ONE_ROW)
+		);
 		if ($line) {
 			$message = preg_replace("/[\r\n\t]+/", " ", $line["tmessage"]);
 			$result .= "<message>" . htmlspecialchars(htmlspecialchars($message)) . "</message>";
@@ -112,34 +116,42 @@ $can_viewthreads, $can_takeover, $mysqlprefix;
 
 function print_pending_threads($groupids, $since)
 {
-	global $webim_encoding, $settings, $state_closed, $state_left, $mysqlprefix;
-	$link = connect();
+	global $webim_encoding, $settings, $state_closed, $state_left;
+	$db = Database::getInstance();
 
 	$revision = $since;
-	$output = array();
 	$query = "select threadid, userName, agentName, unix_timestamp(dtmcreated), userTyping, " .
-			 "unix_timestamp(dtmmodified), lrevision, istate, remote, nextagent, agentId, userid, shownmessageid, userAgent, (select vclocalname from ${mysqlprefix}chatgroup where ${mysqlprefix}chatgroup.groupid = ${mysqlprefix}chatthread.groupid) as groupname " .
-			 "from ${mysqlprefix}chatthread where lrevision > $since " .
-			 ($since <= 0
-					 ? "AND istate <> $state_closed AND istate <> $state_left "
-					 : "") .
-			 ($settings['enablegroups'] == '1'
-					 ? "AND (groupid is NULL" . ($groupids
-							 ? " OR groupid IN ($groupids) OR groupid IN (SELECT parent FROM ${mysqlprefix}chatgroup WHERE groupid IN ($groupids)) "
-							 : "") .
-					   ") "
-					 : "") .
-			 "ORDER BY threadid";
-	$rows = select_multi_assoc($query, $link);
+		"unix_timestamp(dtmmodified), lrevision, istate, remote, nextagent, agentId, " .
+		"userid, shownmessageid, userAgent, (select vclocalname from {chatgroup} where {chatgroup}.groupid = {chatthread}.groupid) as groupname " .
+		"from {chatthread} where lrevision > :since " .
+		($since <= 0
+			? "AND istate <> :state_closed AND istate <> :state_left "
+			: "") .
+		($settings['enablegroups'] == '1'
+			? "AND (groupid is NULL" . ($groupids
+				? " OR groupid IN ($groupids) OR groupid IN (SELECT parent FROM {chatgroup} WHERE groupid IN ($groupids)) "
+				: "") .
+			") "
+			: "") .
+		"ORDER BY threadid";
+	$rows = $db->query(
+		$query,
+		array(
+			':since' => $since,
+			':state_closed' => $state_closed,
+			':state_left' => $state_left
+		),
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
+
+	$output = array();
 	foreach ($rows as $row) {
-		$thread = thread_to_xml($row, $link);
+		$thread = thread_to_xml($row);
 		$output[] = $thread;
 		if ($row['lrevision'] > $revision)
 			$revision = $row['lrevision'];
 	}
 
-	close_connection($link);
-
 	echo "<threads revision=\"$revision\" time=\"" . time() . "000\">";
 	foreach ($output as $thr) {
 		print myiconv($webim_encoding, "utf-8", $thr);
@@ -167,7 +179,7 @@ function print_operators($operator)
 	echo "</operators>";
 }
 
-function visitor_to_xml($visitor, $link)
+function visitor_to_xml($visitor)
 {
     $result = "<visitor id=\"" . $visitor['visitorid'] . "\">";
 
@@ -197,7 +209,7 @@ function visitor_to_xml($visitor, $link)
     $result .= "<invitation>";
     if ($visitor['invited']) {
 	$result .= "<invitationtime>" . $visitor['unix_timestamp(invitationtime)'] . "000</invitationtime>";
-	$operator = get_operator_name(operator_by_id_($visitor['invitedby'], $link));
+	$operator = get_operator_name(operator_by_id($visitor['invitedby']));
 	$result .= "<operator>" . htmlspecialchars(htmlspecialchars($operator)) . "</operator>";
     }
     $result .= "</invitation>";
@@ -208,50 +220,56 @@ function visitor_to_xml($visitor, $link)
 
 function print_visitors()
 {
-	global $webim_encoding, $settings, $state_closed, $state_left, $mysqlprefix;
+	global $webim_encoding, $settings, $state_closed, $state_left;
 
-	$link = connect();
+	$db = Database::getInstance();
 
 // Remove old visitors
-	$query = "DELETE FROM ${mysqlprefix}chatsitevisitor WHERE (UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(lasttime)) > " . $settings['tracking_lifetime'] .
-			" AND (threadid IS NULL OR (SELECT count(*) FROM ${mysqlprefix}chatthread WHERE threadid = ${mysqlprefix}chatsitevisitor.threadid" .
-			" AND istate <> $state_closed AND istate <> $state_left) = 0)";
-	perform_query($query, $link);
+	$db->query(
+		"DELETE FROM {chatsitevisitor} " .
+		"WHERE (UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(lasttime)) > ? ".
+		"AND (threadid IS NULL OR " .
+		"(SELECT count(*) FROM {chatthread} WHERE threadid = {chatsitevisitor}.threadid " .
+		"AND istate <> {$state_closed} AND istate <> {$state_left}) = 0)",
+		array($settings['tracking_lifetime'])
+	);
 
 // Remove old invitations
-	$query = "UPDATE ${mysqlprefix}chatsitevisitor SET invited = 0, invitationtime = NULL, invitedby = NULL" .
-			" WHERE threadid IS NULL AND (UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(invitationtime)) > " .
-			$settings['invitation_lifetime'];
-	perform_query($query, $link);
+	$db->query(
+		"UPDATE {chatsitevisitor} SET invited = 0, invitationtime = NULL, invitedby = NULL".
+		" WHERE threadid IS NULL AND (UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(invitationtime)) > ?",
+		array($settings['invitation_lifetime'])
+	);
 
 // Remove associations of visitors with closed threads
-	$query = "UPDATE ${mysqlprefix}chatsitevisitor SET threadid = NULL WHERE threadid IS NOT NULL AND" .
-			" (SELECT count(*) FROM ${mysqlprefix}chatthread WHERE threadid = ${mysqlprefix}chatsitevisitor.threadid" .
-			" AND istate <> $state_closed AND istate <> $state_left) = 0";
-	perform_query($query, $link);
+	$db->query(
+		"UPDATE {chatsitevisitor} SET threadid = NULL WHERE threadid IS NOT NULL AND" .
+		" (SELECT count(*) FROM {chatthread} WHERE threadid = {chatsitevisitor}.threadid" .
+		" AND istate <> {$state_closed} AND istate <> {$state_left}) = 0"
+	);
 
 // Remove old visitors' tracks
-	$query = "DELETE FROM ${mysqlprefix}visitedpage WHERE (UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(visittime)) > " . $settings['tracking_lifetime'] .
-			" AND visitorid NOT IN (SELECT visitorid FROM ${mysqlprefix}chatsitevisitor)";
-	perform_query($query, $link);
-
-	$output = array();
+	$db->query(
+		"DELETE FROM {visitedpage} WHERE (UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(visittime)) > ? " .
+		" AND visitorid NOT IN (SELECT visitorid FROM {chatsitevisitor})",
+		array($settings['tracking_lifetime'])
+	);
 
 	$query = "SELECT visitorid, userid, username, unix_timestamp(firsttime), unix_timestamp(lasttime), " .
 			 "entry, details, invited, unix_timestamp(invitationtime), invitedby, invitations, chats " .
-			 "FROM ${mysqlprefix}chatsitevisitor " .
+			 "FROM {chatsitevisitor} " .
 			 "WHERE threadid IS NULL " .
 			 "ORDER BY invited, lasttime DESC, invitations";
 	$query .= ($settings['visitors_limit'] == '0') ? "" : " LIMIT " . $settings['visitors_limit'];
-
-	$rows = select_multi_assoc($query, $link);
+	
+	$rows = $db->query($query, NULL, array('return_rows' => Database::RETURN_ALL_ROWS));
+	
+	$output = array();
 	foreach ($rows as $row) {
-		$visitor = visitor_to_xml($row, $link);
+		$visitor = visitor_to_xml($row);
 		$output[] = $visitor;
 	}
 
-	close_connection($link);
-
 	echo "<visitors>";
 	foreach ($output as $thr) {
 		print myiconv($webim_encoding, "utf-8", $thr);
@@ -264,13 +282,11 @@ $status = verifyparam("status", "/^\d{1,2}$/", 0);
 $showonline = verifyparam("showonline", "/^1$/", 0);
 $showvisitors = verifyparam("showvisitors", "/^1$/", 0);
 
-$link = connect();
-loadsettings_($link);
+loadsettings();
 if (!isset($_SESSION["${mysqlprefix}operatorgroups"])) {
-	$_SESSION["${mysqlprefix}operatorgroups"] = get_operator_groupslist($operator['operatorid'], $link);
+	$_SESSION["${mysqlprefix}operatorgroups"] = get_operator_groupslist($operator['operatorid']);
 }
-close_old_threads($link);
-close_connection($link);
+close_old_threads();
 $groupids = $_SESSION["${mysqlprefix}operatorgroups"];
 
 start_xml_output();
diff --git a/src/messenger/webim/operator/userhistory.php b/src/messenger/webim/operator/userhistory.php
index 0f85b749..8b956f18 100644
--- a/src/messenger/webim/operator/userhistory.php
+++ b/src/messenger/webim/operator/userhistory.php
@@ -35,21 +35,19 @@ if (isset($_GET['userid'])) {
 
 function threads_by_userid($userid)
 {
-	global $mysqlprefix;
+	$db = Database::getInstance();
 	if ($userid == "") {
 		return null;
 	}
-	$link = connect();
-
-	$query = sprintf("select unix_timestamp(dtmcreated) as created, unix_timestamp(dtmmodified) as modified, " .
-					 " threadid, remote, agentName, userName " .
-					 "from ${mysqlprefix}chatthread " .
-					 "where userid=\"$userid\" order by created DESC", $userid);
-
-	$foundThreads = select_multi_assoc($query, $link);
-
-	close_connection($link);
-	return $foundThreads;
+	
+	return $db->query(
+		"select unix_timestamp(dtmcreated) as created, " .
+		"unix_timestamp(dtmmodified) as modified, threadid, remote, agentName, userName " .
+		"from {chatthread} " .
+		"where userid=? order by created DESC",
+		array($userid),
+		array('return_rows' => Database::RETURN_ALL_ROWS)
+	);
 }
 
 $found = threads_by_userid($userid);
diff --git a/src/messenger/webim/operator/users.php b/src/messenger/webim/operator/users.php
index 8e133575..e1c68ac2 100644
--- a/src/messenger/webim/operator/users.php
+++ b/src/messenger/webim/operator/users.php
@@ -26,10 +26,8 @@ $status = isset($_GET['away']) ? 1 : 0;
 
 notify_operator_alive($operator['operatorid'], $status);
 
-$link = connect();
-loadsettings_($link);
-$_SESSION["${mysqlprefix}operatorgroups"] = get_operator_groupslist($operator['operatorid'], $link);
-close_connection($link);
+loadsettings();
+$_SESSION["${mysqlprefix}operatorgroups"] = get_operator_groupslist($operator['operatorid']);
 
 $page = array();
 $page['havemenu'] = isset($_GET['nomenu']) ? "0" : "1";
diff --git a/src/messenger/webim/request.php b/src/messenger/webim/request.php
index ecf2b4b1..08e34036 100644
--- a/src/messenger/webim/request.php
+++ b/src/messenger/webim/request.php
@@ -30,14 +30,12 @@ if ($settings['enabletracking'] == '1') {
     $entry = isset($_GET['entry']) ? $_GET['entry'] : "";
     $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : "";
 
-    $link = connect();
-
     if (isset($_SESSION['visitorid']) && preg_match('/^[0-9]+$/', $_SESSION['visitorid'])) {
-	$invited = invitation_check($_SESSION['visitorid'], $link);
-	$visitorid = track_visitor($_SESSION['visitorid'], $entry, $referer, $link);
+	$invited = invitation_check($_SESSION['visitorid']);
+	$visitorid = track_visitor($_SESSION['visitorid'], $entry, $referer);
     }
     else {
-	$visitorid = track_visitor_start($entry, $referer, $link);
+	$visitorid = track_visitor_start($entry, $referer);
     }
 
     if ($visitorid) {
@@ -45,10 +43,9 @@ if ($settings['enabletracking'] == '1') {
     }
 
     if ($invited !== FALSE) {
-	$operator = operator_by_id_($invited, $link);
+	$operator = operator_by_id($invited);
     }
 
-    close_connection($link);
 }
 
 $response = array();
diff --git a/src/messenger/webim/thread.php b/src/messenger/webim/thread.php
index d45d703a..73bb1270 100644
--- a/src/messenger/webim/thread.php
+++ b/src/messenger/webim/thread.php
@@ -73,12 +73,10 @@ if( $act == "refresh" ) {
 		show_error("cannot send");
 	}
 
-	$link = connect();
-	$postedid = post_message_($threadid,$kind,$message,$link,$from,null,$isuser ? null : $operator['operatorid'] );
+	$postedid = post_message_($threadid,$kind,$message,$from,null,$isuser ? null : $operator['operatorid'] );
 	if($isuser && $thread["shownmessageid"] == 0) {
-		commit_thread( $thread['threadid'], array('shownmessageid' => $postedid), $link);
+		commit_thread( $thread['threadid'], array('shownmessageid' => $postedid));
 	}
-	close_connection($link);
 	print_thread_messages($thread, $token, $lastid, $isuser, $outformat, $isuser ? null : $operator['operatorid']);
 	exit;