Показать сообщение отдельно
  #9  
Старый 10.08.2012, 11:15
Аватар для ~TB~
~TB~ ~TB~ вне форума
Начинающий
 
Регистрация: 17.02.2006
Адрес: Казахстан
Сообщения: 172
Версия Delphi: XE
Репутация: 1500
По умолчанию

Может еще и за тебя все сделать? Гм. Порылся на винте, откопал кое-какое старье, которое давно делал в целях эксперимента. Авось пригодиться. Выдрал код отвечающий за чат работающий через MySQL. Представляет из себя что-то вроде тонкого клиента, где большая часть функционала работает на сервере посредством хранимых процедур. Короче как-то так:

MySQL база с таблицами:
Код:
CREATE DATABASE `tbserver` DEFAULT CHARACTER SET cp1251 COLLATE cp1251_general_cs;

CREATE TABLE `tbserver`.`userlist` (
`id` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 30 ) NOT NULL ,
`admin` BOOLEAN NOT NULL DEFAULT '0' ,
`desc` VARCHAR( 100 ) NOT NULL ,
`rank` INT( 10 ) NOT NULL DEFAULT '1'
) ENGINE = InnoDB CHARACTER SET cp1251 COLLATE cp1251_general_cs;

CREATE TABLE `tbserver`.`catlist` (
`id` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 30 ) NOT NULL 
) ENGINE = InnoDB CHARACTER SET cp1251 COLLATE cp1251_general_cs;

INSERT INTO `tbserver`.`catlist` (
`id` ,
`name` 
)
VALUES (NULL , 'General');

INSERT INTO `tbserver`.`catlist` (
`id` ,
`name` 
)
VALUES (NULL , 'User''s');

CREATE TABLE `tbserver`.`roomlist` (
`id` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`table` VARCHAR( 30 ) NOT NULL ,
`name` VARCHAR( 30 ) NOT NULL ,
`desc` VARCHAR( 100 ) NOT NULL ,
`pass` VARCHAR( 30 ) NOT NULL DEFAULT '' ,
`cat` INT( 10 ) NOT NULL ,
`user` INT( 10 ) NOT NULL ,
`lastmes` DATETIME NOT NULL 
) ENGINE = InnoDB CHARACTER SET cp1251 COLLATE cp1251_general_cs;

CREATE TABLE `tbserver`.`userbuf` (
`id` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user` INT( 10 ) NOT NULL ,
`room` INT( 10 ) NOT NULL ,
`lastmark` DATETIME NOT NULL 
) ENGINE = InnoDB CHARACTER SET cp1251 COLLATE cp1251_general_cs;

CREATE TABLE `tbserver`.`banlist` (
`id` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user` INT( 10 ) NOT NULL 
) ENGINE = InnoDB CHARACTER SET cp1251 COLLATE cp1251_general_cs;

Что там делается? Создается база. В нее добавляются таблицы списка пользователей, списка каталогов, списка комнат, списка юзверьского буфера (типа кто когда в какой комнате был был), списка забаненых юзверей.

Ну а дальше:
Код:
CREATE FUNCTION `getlastmes`(room_id INT (10)) RETURNS DATETIME
BEGIN
  SELECT `lastmes` FROM `roomlist` WHERE `id` = room_id INTO @result;
  RETURN @result;
END
//

CREATE PROCEDURE `addmessage`(IN room_table VARCHAR(30), IN user_id INT(10), IN mes_text VARCHAR(255))
BEGIN
  SET @query := CONCAT("SELECT COUNT(*) FROM `", var_table, "` INTO @var_count");
  PREPARE query FROM @query;
  EXECUTE query;
  DEALLOCATE PREPARE query;
  IF @var_count >= 10 THEN
  BEGIN
    SET @query := CONCAT("SELECT MIN(`id`) FROM `", var_table, "` INTO @min");
    PREPARE query FROM @query;
    EXECUTE query;
    DEALLOCATE PREPARE query;
    SET @query := CONCAT("DELETE FROM `", var_table, "` WHERE `id` = @min");
    PREPARE query FROM @query;
    EXECUTE query;
    DEALLOCATE PREPARE query;
  END;
  END IF;
  SET NAMES CP1251;
  SET @query := CONCAT("INSERT INTO `", var_table, "`(`user`, `meswhen`, `mestext`) VALUES (", user_id, ", NOW(), '", mes_text, "')");
  PREPARE query FROM @query;
  EXECUTE query;
  DEALLOCATE PREPARE query;
  SET @query := CONCAT("UPDATE `roomlist` SET `lastmes` = NOW() WHERE `table` = '", room_table, "'");
  PREPARE query FROM @query;
  EXECUTE query;
  DEALLOCATE PREPARE query;
END
//

CREATE PROCEDURE `markuser`(IN room_id INT(10), IN user_id INT(10))
BEGIN
  SET NAMES CP1251;
  IF EXISTS(SELECT * FROM `userbuf` WHERE `user` = user_id) THEN
    UPDATE `userbuf` SET `room` = room_id, `lastmark` = NOW() WHERE `user` = user_id;
  ELSE
    INSERT INTO `userbuf`(`user`, `room`, `lastmark`) VALUES (user_id, room_id, NOW());
  END IF;
END
//

CREATE PROCEDURE `addroom`(IN room_table VARCHAR(30), IN room_name VARCHAR(30), IN room_desc VARCHAR(100), IN room_pass VARCHAR(30), IN room_cat INT(10), IN room_user INT(10))
BEGIN
  SET NAMES CP1251;
  INSERT INTO `roomlist` (
  `table`,
  `name` ,
  `desc` ,
  `pass` ,
  `cat` ,
  `user` ,
  `lastmes`
  )
  VALUES (room_table, room_name, room_desc, room_pass, room_cat, room_user, NOW( ));
  SET @query := CONCAT("CREATE TABLE `", room_table, "` (`id` INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY, `user` INT(10) NOT NULL, ");
  SET @query := CONCAT(@query, "`meswhen` DATETIME NOT NULL, `mestext` VARCHAR(255) NOT NULL) ENGINE = InnoDB ");
  SET @query := CONCAT(@query, "CHARACTER SET cp1251 COLLATE cp1251_general_cs");
  PREPARE query FROM @query;
  EXECUTE query;
  DEALLOCATE PREPARE query;
END
//

CREATE FUNCTION `getroomcount`(user_id INT (10)) RETURNS INT
BEGIN
  SELECT COUNT(*) FROM `roomlist` WHERE `user` = user_id INTO @result;
  RETURN @result;
END
//

CREATE PROCEDURE `addcat`(IN cat_name VARCHAR(30))
BEGIN
  SET NAMES CP1251;
  INSERT INTO `catlist` (`name`) VALUES (cat_name);
END
//

CREATE PROCEDURE `editroom`(IN room_name VARCHAR(30), IN room_desc VARCHAR(100), IN room_pass VARCHAR(30))
BEGIN
  SET NAMES CP1251;
  UPDATE `roomlist` SET `desc` = room_desc, `pass` = room_pass WHERE `name` = room_name;
END
//

CREATE PROCEDURE `delroom`(IN room_table VARCHAR(30))
BEGIN
  SET NAMES CP1251;
  DELETE FROM `roomlist` WHERE `table` = room_table;
  SET @query := CONCAT("DROP TABLE `", room_table, "`");
  PREPARE query FROM @query;
  EXECUTE query;
  DEALLOCATE PREPARE query;  
END
//

CREATE PROCEDURE `delcat`(IN cat_name VARCHAR(30))
BEGIN
  SET NAMES CP1251;
  DELETE FROM `catlist` WHERE `name` = cat_name;
END
//

CREATE PROCEDURE `unmarkuser`(IN user_id INT(10))
BEGIN
  SET NAMES CP1251;
  IF EXISTS(SELECT * FROM `userbuf` WHERE `user` = user_id) THEN
    UPDATE `userbuf` SET `room` = 0, `lastmark` = NOW() WHERE `user` = user_id;
  ELSE
    INSERT INTO `userbuf`(`user`, `room`, `lastmark`) VALUES (user_id, 0, NOW());
  END IF;
END
//

CREATE PROCEDURE `edituser`(IN user_name VARCHAR(30), IN user_desc VARCHAR(100), IN user_rank INT)
BEGIN
  SET NAMES CP1251;
  UPDATE `userlist` SET `desc` = user_desc, `rank` = user_rank WHERE `name` = user_name;
END
//

CREATE FUNCTION `getban`(user_id INT (10)) RETURNS INT
BEGIN
  SELECT COUNT(*) FROM `banlist` WHERE `user` = user_id INTO @result;
  RETURN @result;
END
//

CREATE PROCEDURE `banuser`(IN user_id INT(10))
BEGIN
  SET NAMES CP1251;
  IF NOT EXISTS(SELECT * FROM `banlist` WHERE `user` = user_id) THEN
    INSERT INTO `banlist`(`user`) VALUES (user_id);
  END IF;
END
//

В куске кода выше добавляются в базу хранимые функции и процедуры упрощающие работу с общим бедламом и позволяющие обеспечить более-менее безопасную работу обрезая пользовательские права (БД предварительно настраивается так, что юзвери способны только на выполнение хранимых процедур и все). В частности тут функция которая гребет последнее сообщение в комнате, процедура, которая добавляет сообщение в комнату от заданного юзверя, процедура которая отмечает пользователя в комнате, процедура которая добавляет комнату, функция которая возвращает число комнат, процедура которая добавляет каталог, процедура которая редактирует комнату, процедура которая удаляет комнату, процедура которая удаляет каталог, процедура стирающая метку пользователя, процедура редактирования пользователя, функция проверки на забаненость, процедура забанивания.

Реализовано кривовато, но делалось это довольно давно и наспех. Уж простите. Зато работает.

Ну а тут (вложение2), вообще кошмар (вы не поверите - это работает, и еще, я когда щас листал код, обнаружил в нем несколько SELECT'ов, что говорит о том, что все права резать пользователям нельзя, без добавления нескольких хранимых процедур-функций на сервер - SELECT придется оставить).

Ну а вот (вложение1) и код юнита чата и форма.

100% все работает. Правда так я делать теперь не рекомендую. Лучше собери все на толстом клиенте, так как на тонком, от сервера требуется очень многое.
Вложения
Тип файла: zip Chat.zip (21.5 Кбайт, 18 просмотров)
Тип файла: zip Classes.zip (3.3 Кбайт, 11 просмотров)
__________________
00110001 00101100 00110110 00110001 00111000 00110000 00110011 00110011 00111001 00111000 00111000 00110111 00110100 00111001 00111000 00111001 00110100 00111000 00110100 00111000 00110010 00110000 00110100 00110101 00111000 00110110 00111000 00110011 00110100 00110011 00110110 00110101 00110110
Ответить с цитированием