Пометка PK рядом с атрибутом значит, что атрибут является ключевым (входит в первичный ключ (Primary Key)), а FK означает, что атрибут является внешним ключом (Foreign Key).
Табл. 3.1
Сущность
Атрибуты
Группа пользователей
Идентификатор группы (PK)
Название
Строка, используемая для соединения с базой данных
Пользователь
Идентификатор пользователя (PK)
Дата и время регистрации
Идентификатор группы (FK)
Имя
Пароль
Работодатель
Идентификатор работодателя (PK, FK)
Название фирмы
Адрес
Проезд
Телефон
E-mail
Информация о фирме в виде HTML-страницы
Кандидат
Идентификатор кандидата (PK, FK)
Имя
Фамилия
Отчество
Телефон
E-mail
Резюме в виде HTML-страницы
Флаг действия подбора
Специальность
Идентификатор специальности (PK)
Название
Идентификатор родительской специальности (FK)
Идентификатор пользователя, который добавил специальность (FK)
Microsoft SQL Server 6.5 позволяет добавлять в базу данных пользовательские типы данных, которые в дальнейшем можно использовать для указания типа полей таблиц также, как и встроенные типы.
Разработчиком выделены следующие часто используемые типы (см. табл. 3.2):
Id - для идентификаторов,
String - для строк переменной длины, не превышающих 255 символов.
В качестве средства обеспечения ссылочной целостности используются как первичные (primary key) и внешние ключи (foreign key), так и уникальные индексы (unique index).
Ссылочная целостность - обеспечение соответствия значения внешнего ключа экземпляра дочерней сущности значениям первичного ключа в родительской сущности.
Внешние ключи - это столбцы в таблице, которые соответствуют первичным ключам других таблиц. Отношение первичного ключа к внешнему ключу определяет домен допустимых значений внешнего ключа.
Начиная с версии SQL Server 6.0 первичный и внешние ключи имеют массу возможностей, которые в более ранних версиях SQL Server приходилось кодировать в триггерах.
ASP-приложение представляет собой виртуальный каталог (Virtual Directory), содержащий файл global.asa, а также набор связанных между собой asp-файлов, обеспечивающих интерфейс с пользователями сайта и реализующих часть логики сервера.
Для получения доступа к сервису посетителю Web-сайта (клиенту Биржи) предлагается зарегистрироваться. Причём для работодателей и кандидатов предусмотрены разные процедуры регистрации. В процессе регистрации клиент получает Имя (login) и Пароль, которые будут использованы им при последующих визитах на Биржу на странице Идентификация.
Работодателям и кандидатам Биржа предоставляет различные услуги, так как при посещении Биржи они преследуют различные цели. Например, работодателям предоставляется возможность добавления вакансий, а кандидатам - внесения резюме.
Подсоединение клиентов Биржи к базе данных Job происходит через разных пользователей базы данных (login), обладающих различными правами доступа к базе данных (эти права заданы разработчиком Биржи). Для всех работодателей это пользователь jobemployer, а для всех кандидатов - пользователь jobclient.
Для работы с базой данных написан файл sql.inc, содержащий реализации двух функций:
ExecuteSQLCommand(),
GetError().
Для их использования в файл asp необходимо включить инструкцию:
<!--#include file="sql.inc"-->
Функция ExecuteSQLCommand(sql), исполняет SQL-команду, передаваемую ей в виде строки sql, и возвращает результат в виде множества записей Recordset. При реализации функции ExecuteSQLCommand использована технология ADO (ActiveX Data Objects).
При исполнении SQL-команды может произойти ошибка. Её код можно получить посредством вызова функции GetError() - нулевое значение указывает на нормальное завершение.
Селекторные кнопки (radio button) используется для предоставления пользователю выбора одного из заранее заданного перечня вариантов. Создать селекторную кнопку можно, используя тег
<INPUT TYPE="Radio">.
В группе селекторных кнопок с одинаковым значением атрибута NAME можно выбрать только одну.
Область текста (text-area) - это элемент формы, подобный полю ввода, но с возможностью ввода нескольких строк текста. Для создания области текста используется тег
<TEXTAREA>, а для определения её размеров - атрибуты ROWS и COLS.
Поле ввода пароля (password field) - это такое поле ввода, где вместо каждого введённого символа отображается символ звёздочки (*). Пароли используют для защиты конфиденциальной информации, которая должна быть доступна только определённым пользователям. Создать поле ввода пароля позволяет тег
<INPUT TYPE="Password">.
Единственным средством, позволяющим получить информацию от пользователя, используя HTML, является HTML-форма, поэтому для каждого вновь создаваемого параметра отбора кандидатов работодателю необходимо указать его тип. Тип параметра определяет элемент формы, который будет использоваться при формировании анкет для кандидатов, а также тип переменной, используемой в выражениях для рейтинга.
Лексический анализ заключается в преобразовании строки, содержащей выражение для рейтинга, в последовательность (поток) лексем.
Каждая лексема представляется классом Lex (файл polska.inc) и имеет тип (Type) и значение (Value). Информация о возможных типах лексем приведена в табл. 3.6.
Взаимодействие ASP-приложения с приложением JobSelectServer ограничивается передачей запросов в направлении от ASP-приложения к приложению JobSelectServer (см. рис. 3.5).
Рис. 3.5. Передача запросов от ASP приложения к приложению JobSelectServer
Оба приложения работают на сервере:
ASP-приложение в среде Internet Information Server (IIS),
JobSelectServer в среде Windows NT Server.
Так как, в конечном счете, запросы приходят от клиентов по Internet, возможны ситуации как поступления нескольких запросов одновременно, так и поступления следующего запроса, в то время как обслуживание предыдущего не закончилось.
Для исключения потерь запросов для каждого запроса ASP-приложение создаёт отдельный процесс JobSelectClient и передаёт ему параметры запроса.
Параметрами запроса являются:
Тип запроса (Type). Выделены два типа запросов:
запрос на подбор вакансий для клиента (Type = 1),
запрос на подбор кандидатов на вакансию (Type = 2).
Идентификатор (ID). Если Type=1, то передаётся идентификатор клиента, а если Type=2 - идентификатор вакансии.
Запрос типа 1 посылается в случае изменения вакансии.
Запрос типа 2 посылается в следующих случаях:
Добавление специальности кандидата,
Удаление специальности кандидата,
Прохождение анкетирования кандидатом,
Изменение параметра кандидата,
Разрешение подбора кандидатом.
Так как серверные скрипты ASP-приложения написаны на языке JavaScript, а этот язык предоставляет удобные средства работы с COM-объектами, представляется возможность вызова внешнего приложения (процесса) посредством технологии OLE-автоматизации (OLE-automation). С этой целью написан сервер OLE-автоматизации KesJob (файл kesjob.exe).
Сервер OLE-автоматизации (OLE-automation server) KesJob разработан на Microsoft Visual C++ с помощью MFC (Microsoft Foundation Classes) и раскрывает единственный метод Go(Type, ID), имеющий два параметра - тип запроса (Type) и идентификатор (ID), который посредством API-вызова CreateProcess создаёт процесс JobSelectClient и передаёт ему параметры запроса. Для того чтобы сервер KesJob зарегистрировался в системе (с внешним именем "KESJOB.TASK") необходимо в первый раз (самостоятельно) запустить его. Это необходимый этап, иначе контроллер автоматизации не найдёт в системе сервер автоматизации.
В данном случае ASP-приложение является контроллером OLE-автоматизации (OLE-automation controller), так как для посылки запросов оно вызывает метод Job сервера KesJob.
Таким образом, код, который посылает из JavaScript-скрипта ASP-приложения запрос на выполнение подбора кандидатов на вакансию с идентификатором VacancyID, выглядит следующим образом:
Job = new ActiveXObject("KESJOB.TASK");
Job.Go(1,VacancyID);
Job = null;
А посылка запроса на выполнение подбора вакансий для кандидата UserID выглядит так:
Job = new ActiveXObject("KESJOB.TASK");
Job.Go(2, UserID);
Job = null;
JobSelectServer (файл JobSelectServer.exe) является приложением, разработанным с использованием Microsoft Visual C++ и библиотеки MFC (Microsoft Foundation Classes).
В процессе реализации приложения JobSelectServer разработаны следующие классы:
CAboutDlg,
CBool,
CClient,
CClientSpecSet,
CConformSet,
CExpression,
CJobSelectServerApp,
CJobSelectServerDlg,
CLex,
CLongSet,
CParamSet,
CSelectThread,
CServer,
CServerThread,
CSpecSet,
CTask,
CTasks,
CVacancySet,
CValueIntSet,
CValueStringSet,
CVarValue,
CVarValues.
Класс CBool представляет логическое значение.
Класс CJobSelectServerDlg обеспечивает взаимодействие пользователя с главной формой приложения.
Класс CAboutDlg реализует диалог "About".
Классы ClientSpecSet, CConformSet, CLongSet, CParamSet, CSpecSet, CVacancySet, CValueIntSet, CValueStringSet, CClient организуют выборки из таблиц базы данных.
Класс CJobSelectServerApp представляет собой класс приложения.
Класс CLex представляет лексему.
Класс CServer представляет сервер и реализует его запуск и остановку.
Класс CServerThread представляет поток, который принимает заявки и помещает их в очередь.
Класс CSelectThread представляет поток, который извлекает заявки из очереди и обслуживает их.
Класс CTask представляет заявку.
Класс CTasks представляет список задач, предоставляющий эксклюзивный доступ к данным.
Класс CVarValue представляет шаблон переменной.
Класс CVarValues представляет шаблон переменных.
Класс CExpression представляет выражение. Выражение хранится в виде массива лексем.
JobSelectServer работает на сервере и выполняет работу по подбору вакансий. Запросы на осуществление подбора, поступают от ASP-приложения и, поэтому возможны ситуации как поступления нескольких запросов одновременно, так и поступления следующего запроса, в то время как обслуживание предыдущего не закончилось.
Для исключения потерь запросов для каждого запроса ASP-приложение создаёт отдельный процесс JobSelectClient и передаёт ему параметры запроса. Как только запрос обслужен, процесс завершает работу. Таким образом, количество процессов на сервере зависит от времени обслуживания запросов.
Для уменьшения времени обслуживания запросов и, следовательно, числа процессов на сервере разработчиком в рамках процесса JobSelectServer выделены два потока:
ServerThread,
SelectThread.
При этом обслуживание запроса (процессом ServerThread) представляет собой формирование на его основе заявки и постановку её в очередь. Обслуживанием же заявок занимается поток SelectThread.
Взаимодействие процессов (а также потоков ServerThread и SelectThread в рамках процесса JobSelectServer) показано на рис. 3.6.
Очередь имеет дисциплину обслуживания - FIFO (First In - First Out, первый пришёл, - первый вышел) и реализуется классом CTasks. Класс CTasks обеспечивает эксклюзивный доступ к очереди, то есть в одно и то же время только один поток может работать с очередью. При реализации класса CTasks использованы механизмы синхронизации Windows - события (event, класс MFC CEvent) и критические секции (critical section, класс MFC CCriticalSection).
Интерфейс класса CTasks составляют две функции:
AddTask, которая добавляет заявку в очередь и
GetTask, которая извлекает заявку из очереди.
Если при получении заявки при помощи функции GetTask очередь оказалась пустой, то процесс блокируется и продолжит работу только после того, как функция AddTask добавит в очередь заявку.
Функции потока ServerThread (класс CServerThread) заключаются в приёме заявок и постановке их в очередь.
При реализации взаимодействия процессов JobSelectClient и потока ServerThread использованы механизмы синхронизации Windows - события (event, класс MFC CEvent) и взаимные исключения (mutex, класс MFC CMutex).
Взаимное исключение позволяет организовать ожидание остальных процессов-запросов во время обслуживания одного процесса-запроса.
Событие позволяет одному потоку уведомить другой поток о том, что произошло определённое событие. Пока не пришло событие - поток ожидает.
Причём в этих случаях ожидание не является активным, так как для его организации используются внутренние механизмы Windows (класс MFC CSingleLock).
Передача данных - параметров запроса - происходит через средство межпроцессного взаимодействия Windows, именованную трубу (named pipe).
Постановка заявки в очередь реализуется при помощи вызова функции AddTask класса CTasks.
Функции потока SelectThread (класс CSelectThread) заключаются в получении заявок из очереди и их обработке.
Получение заявок организуется при помощи вызова функции GetTask класса CTasks.
Входными данными для организации обработки заявок, то есть осуществления подбора, являются:
параметры запроса (тип заявки и идентификатор),
информация, хранящаяся в базе данных Job (Таблицы client, clientspec, param, spec, vacancy, vacparam, valuebit, valueint, valuestring, valuetext).
Выходными данными являются значения рейтинга (поле rating) и состояния (поле state_id) для пар {вакансия (поле vacancy_id), кандидат (поле client_id)}, совместимых (подходящих) по специальности. Выходная информация помещается в таблицу conform базы данных. Иллюстрация, поясняющая возможные состояния кандидата (поле state_id), приведена в приложении 9.1.
Взаимодействие потока SelectThread с базой данных организуется с использованием интерфейса ODBC (Open DataBase Connectivity) при помощи MFC классов CRecordset и CDatabase.
Класс CRecordset используется для выборки информации из базы, а класс CDatabase - для занесения выходной информации в базу.
Для присоединения к базе данных Job с помощью ODBC используется строка
"ODBC; DSN=KES_Company Job; UID=jobselect; PWD=;".
То есть работа с базой данных ведётся "от имени" пользователя jobselect.
В процессе реализации подбора введено понятие шаблона переменных. Шаблон переменных (класс CVarValues) суть массив, элементами которого являются шаблоны переменных (класс CVarValue). Шаблон переменной может быть:
пустым,
заполненным.
Пустой шаблон переменной содержит только идентификатор переменной (param_id).
Заполненный шаблон переменной содержит:
идентификатор переменной (param_id),
тип переменной (type),
значение переменной (value).
Шаблон переменных используется в процедуре вычисления рейтинга для ускорения расчётов.
Обслуживание заявок типа 1, то есть подбор кандидатов на вакансию, осуществляет процедура GoTaskEmployer. В качестве входного параметра в процедуру передаётся идентификатор вакансии. Алгоритм функционирования процедуры приведён на рис. 3.8.
Обслуживание заявок типа 2, то есть подбор вакансий для кандидата, осуществляет процедура GoTaskClient. В качестве входного параметра в процедуру передаётся идентификатор кандидата. Алгоритм функционирования процедуры приведён на рис. 3.9.