Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Saitistika 4.0.Руководство разработчика.2005

.pdf
Скачиваний:
12
Добавлен:
23.08.2013
Размер:
3.22 Mб
Скачать

ISAPI-расширение для доступа к файлам

Это расширение (файл 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