Saitistika 4.0.Руководство разработчика.2005
.pdfISAPI-расширение для доступа к файлам
Это расширение (файл FileAccess.dll, далее «расширение») предназначено для ограничения доступа к файлам, хранящимся в каталоге /common/data/pub/files и его подкаталогах, а также для логирования запросов пользователей на эти файлы.
На доступность файла влияют следующие факторы:
1.Файл должен физически существовать.
2.Файл может быть подгружен в систему через интерфейс бэкофиса или фронтофиса. Если файл был подгружен в систему, то для него существует запись в БД, в которой хранятся «виртуальные» свойства файла
2.1.Права Сайтистики на файл
2.2.Доступность по дате
2.3.Статус (доступны только файлы со статусом «Опубликован»)
2.4.Удаленность в архив.
Если записи в БД для файла нет, то он считается доступным по свойствам и правам.
В результате своей работы ISAPI-расширение проверяет доступность файла и либо выдает содержимое файла, либо производит редирект на одну из страниц ошибок:
1.Если файл не существует физически, то производится редирект на страницу ошибки 404.
2.Если файл недоступен по правам Сайтистики для текущего пользователя, то производится редирект на страницу ошибки
401.
3.Если файл недоступен по свойствам или происходит запрос директории, а не файла, то производится редирект на страницу ошибки 403.
4.Если во время работы расширения по каким-то причинам произошла ошибка доступа к базе данных, то производится редирект на страницу ошибки 500.
Независимо от доступности файла расширение также логирует факт доступа к файлу (успешный или неуспешный).
Логика работы
Расширение перехватывает запросы ко всем файлам виртуальной директории, на которую оно настроено в IIS всеми методами (на которые оно также настроено в IIS). При этом обрабатываются только методы GET и HEAD, при запросе файла другим методом выводится ошибка 501 (Not Implemented).
Во время обработки запроса расширение сначала пытается получить ID пользователя по кукам логина и пароля бэкофиса (что может произойти, только если запрос производится из бэкофиса, где пользователь в настоящее время авторизован). Если ID пользователя бэкофиса получить не удается, читается идентификатор текущей сессии Сайтистики из куки site_session_id, устанавливаемой в файле /common/include/fo-init.asp фронтофиса, и ID пользователя определяется как ID пользователя из последнего события этой сессии. Если ни тем, ни другим способом ID пользователя получить не удалось, что может случиться, например, при прямом запросе файла в новом окне броузера, то пользователь считается анонимом.
После определения ID пользователя расширение проверяет права Сайтистики на файл и свойства, определяющие его доступность. При этом, если фильтр работает на бэкофисе (т.е удалось определить ID пользователя как пользователя бэкофиса), то признак удаленности файла в рахив игнорируется, если у пользователя есть право записи на этот файл.
Если все проверки прошли успешно, то расширение формирует и отправляет ответ клиенту. При этом отправляются следующие заголовки:
1.Content-Type – тип содержимого файла. Если о файле есть запись в БД, то тип содержимого, если он задан, берется из нее. Иначе тип содержимого берется из реестра по расширению файла. Если тип содержимого определить не удалось, то передается application/octet-stream.
2.Accept-Ranges – передается строка «bytes».
3.Last-Modified – передается дата создания или последнего изменения файла из его физических свойств.
4.Content-Range – передается в стандартном формате только при запросе частичного содержимого (т.е. при докачке).
5.Content-Length – при запросе методом HEAD передается 0, иначе – длина передаваемого содержимого.
В случае успешной передачи файла клиенту
1.возвращается статус 200 (OK) или 206 (Partial Content). Последний статус возвращается при запросе частичного содержимого (докачке).
2.Добавляется запись в таблице FilesIPAccess, после чего файл становится доступным клиенту с тем же IP в течение периода таймаута сессии независимо от прав Сайтистики на этот файл (доступность по свойствам обрабатывается как обычно). Основное предназначение этой функции - чтобы пользователь мог скачать файл через download manager-ы.
Если же файл оказался недоступен по одной из причин или во время работы произошла ошибка 500, то клиенту
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
281 из 281 |
|
|
возвращается статус 302 (Redirect) – редирект на страницу соответствующей ошибки, а в лог IIS записывается статус, равный коду ошибки. В отладочной версии расширения вместо редиректа клиенту выводится страница с указанием подробной причины ошибки.
Используемые таблицы и хранимые процедуры
При обращении к базе данных расширение использует ряд хранимых процедур. Эти процедуры написаны с учетом их предназначения для данного расширения. К большинству полей таблиц, возвращаемых этими процедурами, доступ производится по индексу. В связи с этим используемые расширением хранимые процедуры не рекомендуется значительно изменять без согласования этих изменений с расширением.
Используемые хранимые процедуры:
1.Users_GetUserID
2.Files_Extension_UserFromSession
3.Files_Extension_GetPathInfo
4.Files_Extension_UpdateFileAccess
5.Events_AddFileAccessParams
6.Events_MakeObjectStaticString
7.Events_AddEvent
8.Events_LinkEvent
9.Sait_Common_GetClientInfo
10.Sait_GetFolderInfo
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
282 из 282 |
|
|
Несистематизированные наработки
В разделе описаны полезные функции, приемы и рекомендации по программированию Сайтистики. Раздел постоянно пополняется разработчиками и его содержимое трудно поддается системаизации, однако ознакомиться с ним рекомендуется любому разработчику сайтистики, так как в нем описаны нетривиальные приемы и рекомендации для решения наиболее широко известных проблем, с которыми рано или поздно столкнется любой разработчик.
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
283 из 283 |
|
|
Импорт данных
Структура данных между разными версиями систем значительно отличается. Учитывая также то, что в большинстве случаев в конечных инсталляциях структура данных при развитии данных изменяется и расширяется программистами, универсальную процедуру импорта создать практически невозможно.
Однако большинство действий по импорту между разными версиями систем совпадают, поэтому разработана общая методика ручного импорта данных, которая и приведена ниже. Использовать эту методику на практике лучше как мастер- план (шаблон) для составления плана импорта данных в конечной ситсеме.
1.Определить что необходимо перености, конкретные таблицы
1.1.Например если только разделы + материалы = Sites, Folders, Articles, FoldersArticles, UsersObjRights, таблицы интерактивов + все связанные данные
1.2.Всю информацию (проще)
2.Определить версии сайтистики, различия в таблицах, набор таблиц-справочников
2.1.2.x -> 3.x
2.2.2.x,3.x -> 4.x (сложно)
3.Сделать backup (BACKUP1) базы в которую переносят
4.Отключение связей, триггеров, чистка базы (оставить справочники)
5.Перенос кустомных процедур (если такие есть)
6.Сделать еще один backup (BACKUP2) уже вычищеной базы (вероятней всего с первого раза перенос не пройдет)
7.Определить изменения в структуре данных
7.1.Небольшие изменения (поля таблицы, переименование таблиц) переносятся путем трансформации во время преноса (Transform->[…])
7.2.При серьезных изменениях таблицы с исходными данными переносятся в темповые таблицы TableName_Bak, из которых на 9-м шаге sql-скриптом генерятся нужные данные.
7.3.Важно! Не переносить те таблицы, которых нет (удалены) в новой версии, либо переносить их как темповые
8.Перенос данных с помощью DTS
9.Конвертация, зануление свойств
9.1.Написание и выполнение скриптов переноса данных из темповых таблиц в новые структуры данных
9.2.Зануление свойств – например всем разделам 0-го типа обнулить (NULL) подтип, чтобы стали «Каталогами сервера»
10.При ошибках переноса или конвертации почистить базу (Скрипт 1) или восстановить из BACKUP2, и вернуться к 7 шагу
11.Удаление темповых таблц, лишних данных
11.1.Лишние данные – например неактуальные записи в UsersObjRights
12.Включение связей, триггеров
13.Ручное донастраивание (добавление информации, которой не было в пред. версии) Использовать BACKUP1
14.Если оказалось, что упущен (не сохранен) какой либо справочник из новой версии, восстанавливаем базу из BACKUP1 и возвращаемся к 4-му шагу
Справочники
Для 3.5
ArticleStatus DirectoriesResourceTypes EventTypes
FolderTypes
Menu_Items Menu_ItemRights Menu_ItemGroups MySaitistikaBlocks ObjectTypes Rights SystemSettings FoldersTypes FoldersNotes SystemFolders
RegFields – необязательно
Для 4.0
ArticleStatus CacheRuleOperators CacheRuleTypes
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
284 из 284 |
|
|
CacheUniqueTypes
DirectoriesResourceTypes
EventTypes
FieldTypes
FieldVariants
FolderTypes
Menu_Items
Menu_ItemRights
Menu_ItemGroups
MySaitistikaBlocks
ObjectTypes
Roles
SystemSettings
SystemFolders
Отключение связей, триггеров. Чистка базы
--Отключение связи
DECLARE @Y VARCHAR (255)
DECLARE X Cursor FOR SELECT name FROM SysObjects WHERE xtype = 'U' OPEN X
FETCH NEXT FROM X INTO @Y WHILE @@FETCH_STATUS = 0 BEGIN
exec ( 'ALTER TABLE ['+@Y+'] NOCHECK CONSTRAINT ALL' ) FETCH NEXT FROM X INTO @Y
END DEALLOCATE X
--Отключение триггеры
DECLARE X Cursor FOR SELECT name FROM SysObjects WHERE xtype = 'U' OPEN X
FETCH NEXT FROM X INTO @Y
WHILE @@FETCH_STATUS = 0 BEGIN
exec ( 'ALTER TABLE ['+@Y+'] DISABLE TRIGGER ALL ' ) FETCH NEXT FROM X INTO @Y
END DEALLOCATE X -- Чистка БД
DECLARE X Cursor FOR SELECT name FROM SysObjects WHERE xtype = 'U' OPEN X
FETCH NEXT FROM X INTO @Y
WHILE @@FETCH_STATUS = 0 BEGIN
IF |
@Y |
<> 'SystemSettings' |
|
|
and |
@Y |
<> 'Rights' |
|
and |
@Y |
<> 'Menu_Items' |
|
and |
@Y |
<> 'Menu_ItemRights' |
|
and |
@Y |
<> 'Menu_ItemGroups' |
|
and |
@Y |
<> 'MySaitistikaBlocks' |
|
and |
@Y |
<> 'EventTypes' |
|
and |
@Y |
<> 'ObjectTypes' |
|
and |
@Y |
<> 'FolderTypes' |
|
and |
@Y |
<> 'DirectoriesResourceTypes' |
|
and |
@Y |
<> 'MetaDataFieldTypes' |
|
and |
@Y |
<> 'ArticleStatus' |
|
exec ( |
'DELETE FROM ['+@Y+']' ) |
FETCH NEXT FROM X INTO @Y
END
DEALLOCATE X
Включение связей
--включение связи
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
285 из 285 |
|
|
DECLARE @Y VARCHAR (255)
DECLARE X Cursor FOR SELECT name FROM SysObjects WHERE xtype = 'U' OPEN X
FETCH NEXT FROM X INTO @Y
WHILE @@FETCH_STATUS = 0 BEGIN
exec ( 'ALTER TABLE ['+@Y+'] CHECK CONSTRAINT ALL' ) FETCH NEXT FROM X INTO @Y
END DEALLOCATE X
-- включение триггеры
DECLARE X Cursor FOR SELECT name FROM SysObjects WHERE xtype = 'U' OPEN X
FETCH NEXT FROM X INTO @Y
WHILE @@FETCH_STATUS = 0 BEGIN
exec ( 'ALTER TABLE ['+@Y+'] ENABLE TRIGGER ALL ' ) FETCH NEXT FROM X INTO @Y
END DEALLOCATE X
Перенос процедур
SELECT s1.[name] FROM SysObjects s1
left join SaitistikaOldversion30..SysObjects s2 on s2.[name] = s1.[name]
where s1.xtype = 'p' and s1.status >=0 and ((s1.[name]is Null) or (s2.[name] is Null))
order by s1.[name]
SELECT s1.[name] FROM SaitistikaOldversion30..SysObjects s1
left join SaitistikaNewversion..SysObjects s2 on s2.[name] = s1.[name]
where s1.xtype = 'p' and s1.status >=0 and ((s1.[name]is Null) or (s2.[name] is Null))
order by s1.[name]
Первый селект возвращает все ХП которых нет на дивнете , второй все ХП которых нет на девелопменте
Нужно добавить в новую базу все процедуры которые возвращает второй селект и выставить им права
Сравнение таблиц
SELECT s1.[name] FROM SaitistikaNewversion..SysObjects s1
left join SaitistikaOldversion30..SysObjects s2 on s2.[name] = s1.[name]
where s1.xtype = 'u' and s1.status >=0 and ((s1.[name]is Null) or (s2.[name] is Null))
order by s1.[name]
SELECT s1.[name] FROM SaitistikaOldversion30..SysObjects s1
left join SaitistikaNewversion..SysObjects s2 on s2.[name] = s1.[name]
where s1.xtype = 'u' and s1.status >=0 and ((s1.[name]is Null) or (s2.[name] is Null))
order by s1.[name]
Первый селект возвращает все таблицы которых нет на дивнете , второй все таблицы которых нет на девелопменте
Импорт данных из старой базы
Переносить Enterprize Manager-ом
1.Правой кнопкой на пустой новой БД, All Tasks -> Import Data
2.Указать Data Source (старая БД клиента), Data Destination уже будет указан
3.Выбрать “Copy table(s) from the source database”
4.Нажать Select All, убрать выделения для всех view и для таблицы SystemSettings и maillists и справочников (Список справочников ниже)
5.Запустить (Next>Next>Finish)
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
286 из 286 |
|
|
Иногда в таблицах различается порядок полей и возникают ошибки. В случае таких ошибок надо делать следующее:
1.Посмотреть в каких таблицах возникли ошибки
2.Вернуться на страницу выбора таблиц для переноса
3.В колонке Transform для этих таблиц нажать […]
4.Выбрать закладку Transformation
5.Установить Transform information as it copied to the destination и отредактировать скрипт так, чтобы поля копировались в поля с соответствующими им названиями.
Примеры конвертации данных SQL-скриптами
Импорт материалов из 3.5 в 4.0
1.В БД-источнике во временные таблицы выбрать:
1.1.ID всех материалов, подлежащих импорту, в той же таблице создать 5 дополнительных полей для хранения актуальной во время импорта информации. Пример таблицы
_EXPORT_ArticleID
ID |
newID |
smallPicture |
bigPicture |
newSmallPicture |
newBigPicture |
|
|
|
|
|
|
На данном этапе нам требуется только поле ID (не следует делать его ключевым!).
1.2. По выбранным ID материалов сделать выборку информации в таблицы:
_EXPORT_Articles
Полностью аналогична таблице Articles в БД-источнике, материалы только те, у которых ID в таблице _EXPORT_ArticleID.
_EXPORT_ArticlePictures
Полностью аналогична таблице ArticlePictures в БД-источнике, записи связи только по материалам из списка экспорта.
_EXPORT_OuterLinks
Полностью аналогична таблице OuterLinks в БД-источнике, записи только по материалам из списка экспорта.
_EXPORT_Pages
Полностью аналогична таблице Pages в БД-источнике, записи только по материалам из списка экспорта.
_EXPORT_PicturesFS
Похожа на таблицу Pictures в БД-источнике, разница только в отстутствии колонки Img, записи только по материалам из списка экспорта.
2.Сделать экспорт вновь созданных таблиц в БД-приемник.
3.В БД-приемнике написать и выполнить скрипт переноса информации из временных таблиц в рабочие.
Пример скрипта:
DECLARE
@artID INT
,@artTitle VARCHAR(256)
,@artComment VARCHAR(1024)
,@artThanks VARCHAR(1024)
,@artEditorComment VARCHAR(1024)
,@artKeyWords VARCHAR(8000)
,@ptrArtKeywords VARBINARY(16)
,@ptrArtKeywordsDest VARBINARY(16)
,@artSmallPicture INT
,@artBigPicture INT
,@lastId INT
,@pageID INT
,@pageTitle VARCHAR(256)
,@pageImageCount INT
,@pageContent VARCHAR(8000)
,@pageComplete BIT
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
287 из 287 |
|
|
,@pageLength INT
,@ptrPageContentSrc VARBINARY(16)
,@ptrPageContentDst VARBINARY(16)
,@contentLengthSrc INT
,@contentLengthDst INT
,@picID INT
,@picLabel VARCHAR(1024)
,@picHeight INT
,@picWidth INT
,@picType VARCHAR(1024)
,@picSize INT
,@lastPicID INT
DECLARE artCursor CURSOR FOR
SELECT SaitistikaDest.dbo._EXPORT_Articles.[ID],
SaitistikaDest.dbo._EXPORT_Articles.[Title],
SaitistikaDest.dbo._EXPORT_Articles.[Comment],
SaitistikaDest.dbo._EXPORT_Articles.[Thanks],
SaitistikaDest.dbo._EXPORT_Articles.[EditorComment],
SaitistikaDest.dbo._EXPORT_Articles.[Keywords],
SaitistikaDest.dbo._EXPORT_Articles.[Picture],
SaitistikaDest.dbo._EXPORT_Articles.[BigPicture]
FROM SaitistikaDest.dbo._EXPORT_Articles
OPEN artCursor
SET @lastID = 0
FETCH NEXT FROM artCursor
INTO @artID, @artTitle, @artComment, @artThanks, @artEditorComment, @artKeywords, @artSmallPicture, @artBigPicture
WHILE (@@FETCH_STATUS = 0)
BEGIN
INSERT INTO SaitistikaDest.dbo.Articles
(
[Type],
[Name],
[Description],
[Created],
[Changed],
[Deleted],
[System],
[Active],
[Notes],
[Owner],
[Status],
[Ord],
[ExpiredBefore],
[ExpiredAfter],
[Picture],
[BigPicture],
[Keywords],
[Comment1],
[Comment2],
[Comment3],
[IsHidden],
[IsTemplate],
[Searched],
[ScriptCode],
[LikeArticles],
[Integration],
[HasRating],
[Editor],
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
288 из 288 |
|
|
[RPercent], |
|
|
[SeqNo] |
|
|
) |
|
|
VALUES |
|
|
( |
-- type |
|
4, |
||
@artTitle, |
-- article title |
|
@artComment, |
|
-- description |
GETDATE(), |
-- created date |
|
GETDATE(), |
-- changed date |
|
NULL, |
|
-- deleted date |
0, |
-- system |
|
1, |
-- active |
|
'.', |
-- notes |
|
2651, |
-- owner (Administrator -???) |
|
4, |
-- status |
|
NULL, |
-- ord |
|
NULL, |
-- expired before |
|
NULL, |
-- expired after |
|
NULL, |
-- picture |
|
NULL, |
|
-- big picture |
@artKeywords, |
-- keywords |
|
@artComment, |
|
-- comment 1 |
NULL, |
-- comment 2 |
|
@artThanks, |
-- comment 3 |
|
0, |
-- isHidden |
|
0, |
-- isTemplate |
|
1, |
-- searched |
|
NULL, |
-- script code |
|
0, |
-- like articles |
|
NULL, |
-- integration |
|
0, |
-- has rating |
|
NULL, |
-- editor |
|
0, |
-- RPercent |
|
@lastID+2 |
-- SeqNo (у первой внесенной стьи SeqNo = 2, ее найти и исправить |
вручную)
)
--store new article's id in variable SELECT @lastID = @@IDENTITY
--now store information about new article in FolderArticles INSERT INTO SaitistikaDest.dbo.FolderArticles
(
[Folder],
[Article]
)
VALUES
( |
-- folder |
|
|
2039, |
|
|
|
@lastID |
-- articleID |
|
|
) |
|
|
|
-- save new article's ID in SaitistikaDest.dbo.ArticlesID |
|
||
UPDATE SaitistikaDest.dbo._EXPORT_ArticlesID |
SET |
|
|
SaitistikaDest.dbo._EXPORT_ArticlesID.[newID] = @lastID |
|
||
WHERE (SaitistikaDest.dbo._EXPORT_ArticlesID.[ID] = @artID) |
|
||
----------------------------------------------------------------- |
|
||
-- now work with article's pages |
|
|
|
DECLARE pageCursor CURSOR FOR |
|
|
|
SELECT SaitistikaDest.dbo._EXPORT_Pages.[ID], |
|
||
SaitistikaDest.dbo._EXPORT_Pages.[Title], |
|
|
|
SaitistikaDest.dbo._EXPORT_Pages.[ImageCount], |
|
|
|
SaitistikaDest.dbo._EXPORT_Pages.[Content], |
|
|
|
|
|
|
|
|
Copyright © 2005 Individ company |
|
Страница |
|
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
289 из 289 |
SaitistikaDest.dbo._EXPORT_Pages.[Complete], SaitistikaDest.dbo._EXPORT_Pages.[lenght]
FROM SaitistikaDest.dbo._EXPORT_Pages
WHERE (SaitistikaDest.dbo._EXPORT_Pages.[Article] = @artID) OPEN pageCursor
FETCH NEXT FROM pageCursor
INTO @pageID, @pageTitle, @pageImageCount, @pageContent, @pageComplete,
@pageLength
WHILE (@@FETCH_STATUS = 0)
BEGIN
-- reading page content SELECT @ptrPageContentSrc =
TEXTPTR(SaitistikaDest.dbo._EXPORT_Pages.[Content]) FROM SaitistikaDest.dbo._EXPORT_Pages
WHERE SaitistikaDest.dbo._EXPORT_Pages.[ID] = @pageID
--
SELECT @contentLengthSrc = DATALENGTH(SaitistikaDest.dbo._EXPORT_Pages.[Content])
FROM SaitistikaDest.dbo._EXPORT_Pages
WHERE SaitistikaDest.dbo._EXPORT_Pages.[ID] = @pageID
--
READTEXT SaitistikaDest.dbo._EXPORT_Pages.[Content] @ptrPageContentSrc
0 @contentLengthSrc |
|
|
INSERT INTO SaitistikaDest.dbo.Pages |
||
( |
|
|
[Article], |
|
|
[Title], |
|
|
[SeqNo], |
|
|
[ImageCount], |
|
|
[Content], |
|
|
[Complete], |
|
|
[lenght], |
|
|
[lockDate], |
|
|
[lockType], |
|
|
[lockUserId] |
|
|
) |
|
|
VALUES |
|
|
( |
-- Article ID |
|
@lastID, |
||
@pageTitle, -- Page Title |
||
0, |
-- SeqNo |
|
@pageImageCount,-- Image count |
||
@pageContent, |
-- content |
|
@pageComplete, |
-- page complete |
|
@pageLength, |
|
-- page length |
NULL, |
-- lockDate |
|
NULL, |
-- lockType |
|
NULL |
-- lockUserID |
|
) |
|
|
-- writing page content
SELECT @ptrPageContentDst = TEXTPTR(SaitistikaDest.dbo.Pages.[Content]) FROM SaitistikaDest.dbo.Pages
WHERE SaitistikaDest.dbo.Pages.[ID] = @@IDENTITY
--
SELECT @contentLengthDst = DATALENGTH(SaitistikaDest.dbo.Pages.[Content])
FROM SaitistikaDest.dbo.Pages
WHERE SaitistikaDest.dbo.Pages.[ID] = @@IDENTITY
--
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
290 из 290 |
|
|