Saitistika 4.0.Руководство разработчика.2005
.pdfUPDATETEXT SaitistikaDest.dbo.Pages.[Content] @ptrPageContentDst 0
@contentLengthDst
SaitistikaDest.dbo._EXPORT_Pages.[Content] @ptrPageContentSrc
FETCH NEXT FROM pageCursor
INTO @pageID, @pageTitle, @pageImageCount, @pageContent, @pageComplete,
@pageLength
END
CLOSE pageCursor DEALLOCATE pageCursor
-----------------------------------------------------------------
-----------------------------------------------------------------
-- PICTURES
DECLARE picsCursor CURSOR FOR
SELECT SaitistikaDest.dbo._EXPORT_PicturesFS.[ID], SaitistikaDest.dbo._EXPORT_PicturesFS.[Label],
SaitistikaDest.dbo._EXPORT_PicturesFS.[Height], SaitistikaDest.dbo._EXPORT_PicturesFS.[Width],
SaitistikaDest.dbo._EXPORT_PicturesFS.[Type], SaitistikaDest.dbo._EXPORT_PicturesFS.[Size]
FROM SaitistikaDest.dbo._EXPORT_PicturesFS
WHERE (SaitistikaDest.dbo._EXPORT_PicturesFS.[ID] = @artSmallPicture OR SaitistikaDest.dbo._EXPORT_PicturesFS.[ID] =
@artBigPicture)
OPEN picsCursor
FETCH NEXT FROM picsCursor
INTO @picID, @picLabel, @picHeight, @picWidth, @picType, @picSize
WHILE (@@FETCH_STATUS = 0) BEGIN
INSERT INTO SaitistikaDest.dbo.Pictures
(
[Label],
[Height],
[Width],
[Type],
[Size]
)
VALUES
(
@picLabel,
@picHeight,
@picWidth,
@picType,
@picSize
)
--
SELECT @lastPicID = @@IDENTITY
-- link thru table ArticlePictures
INSERT INTO SaitistikaDest.dbo.ArticlePictures
(
[Article],
[Picture]
)
VALUES
(
@lastID,
@lastPicID
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
291 из 291 |
|
|
)
-- record in Articles table IF (@picID = @artSmallPicture) BEGIN
UPDATE SaitistikaDest.dbo.Articles SET SaitistikaDest.dbo.Articles.[Picture] = @lastPicID WHERE (SaitistikaDest.dbo.Articles.[ID] = @lastID)
-- |
SET |
UPDATE SaitistikaDest.dbo._EXPORT_ArticlesID |
SaitistikaDest.dbo._EXPORT_ArticlesID.[smallPicture] =
@artSmallPicture
, SaitistikaDest.dbo._EXPORT_ArticlesID.[bigPicture] =
@artBigPicture
, SaitistikaDest.dbo._EXPORT_ArticlesID.[newSmallPicture] =
@lastPicID
WHERE (SaitistikaDest.dbo._EXPORT_ArticlesID.[ID] = @artID)
END
ELSE
BEGIN
UPDATE SaitistikaDest.dbo.Articles SET SaitistikaDest.dbo.Articles.[BigPicture] = @lastPicID WHERE (SaitistikaDest.dbo.Articles.[ID] = @lastID)
-- |
SET |
UPDATE SaitistikaDest.dbo._EXPORT_ArticlesID |
SaitistikaDest.dbo._EXPORT_ArticlesID.[smallPicture] =
@artSmallPicture
, SaitistikaDest.dbo._EXPORT_ArticlesID.[bigPicture] =
@artBigPicture
, SaitistikaDest.dbo._EXPORT_ArticlesID.[newBigPicture] =
@lastPicID
WHERE (SaitistikaDest.dbo._EXPORT_ArticlesID.[ID] = @artID)
END
FETCH NEXT FROM picsCursor
INTO @picID, @picLabel, @picHeight, @picWidth, @picType, @picSize
END
CLOSE picsCursor
DEALLOCATE picsCursor
-------------------------------------------------------------------
-------------------------------------------------------------------
---outer links
---из таблицы _EXPORT_OuterLinks в таблицу OuterLinks
---аналогично страницам
FETCH NEXT FROM artCursor
INTO @artID, @artTitle, @artComment, @artThanks, @artEditorComment, @artKeywords, @artSmallPicture, @artBigPicture
END
CLOSE artCursor
DEALLOCATE artCursor
4.После переноса материалов в таблице _EXPORT_AriticlesID останутся данные о том, какие картинки следует получить из каталога pictures сайта-источника (колонки smallPicture и bigPicture) и какие имена им нужно дать (соответственно, колонки newSmallPicture и newBigPicture). Руководствуясь этой информацией, следует либо перенести и переименовать картинки вручную, либо сгенерировать для это batch-скрипты.
5.С файлами и картинками из контента материалов все сложнее: список папок, подлежащих выкачиванию с сервера- источника дает нам колонка ID в таблице _EXPORT_ArticlesID, новые имена для папок – колонка newID. Если при
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
292 из 292 |
|
|
переименовании и копировании папок с новыми именами в каталоги pub/images/articles и pub/files/articles не встречается конфликтов имен и если есть уверенность, что не возникнет в будущем (это возможно, если нет совпадающих имен папок, либо в папках с совпавшими именами нет одноименных файлов, и если при росте значения колонки ID в таблицах Files и Pictures такие файлы не появятся), можно больше ничего не делать. При небольшом количестве конфликтов они фиксируются и устраняются ручной правкой содержимого страниц материалов. Если есть опасность появления большого числа конфликтов и/или для соответствия проимпортированных материалов всем параметрам логики БД Saitistika 4.0 (наличие соответствующих физическим файлам записей в таблицах Pictures и Files), следует придумать механизм для корректного переноса картинок из содержимого страниц и прикрепленных к материалу файлов.
Конвертация форм и результатов заполнения из 2.x в 3.5 (связи и триггеры отключены)
DELETE FROM DataStorage
DELETE FROM FormsIndex
DELETE FROM DataStorageVariants DELETE FROM MetaDataFields DELETE FROM Forms
DELETE FROM MetaDataForms
SET IDENTITY_INSERT MetaDataForms ON
INSERT INTO MetaDataForms ([ID], TextBegin, TextEnd, ErrorBegin, ErrorEnd, ErrorTemplate) SELECT ID, TopText, BottomText, ErrorMsgStart, ErrorMsgEnd, ErrorMsgTemplate
FROM FormInputs
SET IDENTITY_INSERT MetaDataForms OFF
INSERT INTO Forms ( Form, Folder, Email, Action, Message, Url)
SELECT ID, Folder, Email, Action, Message, Url
FROM FormInputs
--
-- перенос FieldTypes: 2->3, 3->4, 4->2, other->self.
--
SET IDENTITY_INSERT MetaDataFields ON
INSERT INTO MetaDataFields (ID, Form, Title, Description, FieldType, ErrorMessage, Options, Position)
SELECT ID, FormInput, title, Description, Case When(Type=2) Then 3
When(Type=3) Then 4
When(Type=4) Then 2 Else Type End
, ErrorMsg, Options, SeqNo FROM ForminputFields
SET IDENTITY_INSERT MetaDataFields OFF
SET IDENTITY_INSERT DataStorageVariants ON
INSERT INTO DataStorageVariants ([ID], Field, Title, Options, Position)
SELECT [ID], Field, Title, Options, SeqNo
FROM ForminputAnswerVariants
SET IDENTITY_INSERT DataStorageVariants OFF
INSERT INTO FormsIndex ([Index], Form, [Date], [User])
SELECT [ID], FormInput, [Date], UserID
FROM ForminputResults
SET IDENTITY_INSERT DataStorage ON
INSERT INTO DataStorage ([ID], [Index], Form, Field, [Float], [Text], [DateTime], Variant)
SELECT FA.ID, FA.Result, FR.FormInput, FA.Field, /*CAST(AnswerText AS Float)*/Null, AnswerText, /*CAST(AnswerText AS DateTime)*/Null, AnswerID
FROM ForminputAnswers FA
JOIN ForminputResults FR ON FR.ID=FA.Result SET IDENTITY_INSERT DataStorage OFF
перенос постингов конференций в форумы плоским списком
/*
Форумы:
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
293 из 293 |
|
|
47 1277 Опросы
55 1552 Обсуждение материалов портала
Конференции
37 1271 Опросы
38 1272 Обсуждение материалов портала
*/
/*
DECLARE @Forum INT, @Conf INT, @Posting INT Set @Conf = 38 --ID конференции
Set @Forum = 55 -- ID форума DECLARE @confTopic INT
DECLARE X Cursor FOR SELECT [ID] FROM ConfTopics WHERE Conference = @Conf OPEN X
FETCH NEXT FROM X INTO @confTopic WHILE @@FETCH_STATUS = 0
BEGIN
--
INSERT INTO ForumsPostings (Forum,Parent,[Text],Author, AuthorID, [Date], IsValid, Topic, IP )
SELECT @Forum, 0, CP.[Text], CT.Author, CT.AuthorID, CT.[Date], CP.IsValid, CT.Title, CP.IP
FROM ConfTopics CT
JOIN ConfPostings CP ON CP.[ID]=CT.FirstMessage WHERE CT.[ID]=@confTopic
SET @Posting = @@IDENTITY IF @Posting > 0
BEGIN
UPDATE ForumsPostings SET Thread = @Posting WHERE [ID]=@Posting
INSERT INTO ForumsPostings (Forum,Parent,[Text],Author, AuthorID, [Date], IsValid, Topic, IP, Thread )
SELECT @Forum, @Posting, CP.[Text], CP.Author, CP.AuthorID, CP.[Date], CP.IsValid, CT.Title, CP.IP, @Posting
FROM ConfTopics CT
JOIN ConfPostings CP ON CP.Topic=CT.[ID] AND CP.[ID]<>CT.FirstMessage WHERE CT.[ID] = @confTopic
END
FETCH NEXT FROM X INTO @confTopic
END
DEALLOCATE X
Чего можно «занулить»
∙почистить объектные права, выставить на сервера права для группы «Системная (бэкофис)», остальным унаследовать
DELETE FROM UsersObjRights WHERE NOT(AccountID=25 AND Type LIKE '_G')
∙сделать ВСЕ КУСТОМНЫЕ РАЗДЕЛЫ ТИПОМ «КАТАЛОГ СЕРВЕРА»
UPDATE Folders SET SubType = NULL WHERE Type = 0 ∙ обнулить настройки интерактивов и близкие материалы
очистить таблицы
NeibLinks
OuterLinks ArticleRelConfs RelArticles
Ручное донастраивание
Действия после переноса. Пример
1.Отключить foreign key:
1.1.Events-Folders
1.2.FK_EventParamsStructure_Articles
1.3.FK_EventParamsStructure_Folders
2.Составить список всех авторов, имеющих материалы
SELECT DISTINCT Author, People.Title FROM Articles JOIN People ON People.[ID]=Author
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
294 из 294 |
|
|
3.Перенос списков рассылок
3.1.Создание рассылок
INSERT INTO MailLists(folder)
SELECT [ID] From Folders Where Type = 26
3.2.Сохранение свойств, перенос подписчиков – вручную
4.Очистить бинарники картинок в таблице Pictures UPDATE Pictures
SET Img = NULL
WHERE ID IN (
SELECT Picture From Folders UNION
SELECT SmallPicture From Folders UNION
SELECT Picture From Articles UNION
SELECT BigPicture From Folders
)
5.Пренос типов разделов и системных разделов
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
295 из 295 |
|
|
Глобальная замена контента в БД
Расширенный сервис «Поиск и замена» http://saitistika.project.ru/aspscripts/materials/material-search-replace.asp
Специальная страница, позволяющая в содержании материалов (только там, что редактируется через визуальный редактор) производить глобальные замены по всей системе. Применяется в различных случаях, например:
1.При смене домена бэкофиса – исправить абсолютные пути ссылок в материалах
2.При операциях с линками – например, о слова «Microsoft» на всем сайте поставить ссылку на www.microsoft.com, или
удалить на всем сайте ссылки на удаленные ресурсы
3.Для удаления информации – одни и те же фрагменты текста удалить или заменить на другие
И т.п.
Процедура замены подстроки в поле текстового типа таблицы БД
Пример для замены строки '/images/' на '/pubimages/' во всех записях поля Content таблицы Pages базы данных SaitistikaProject
Alter Procedure ReplaceString
As
-- Разрешаем оператор UpdateText
Execute sp_dboption 'SaitistikaProject', 'select into/bulkcopy', 'true'
--Объявляем курсор, будем по одной выбирать адреса каждой текстовой строки
Declare
Cur Cursor For Select
TextPtr (Content) From
Pages
--Объявляем переменные
Declare
--В эту переменную будем читать данные из курсора
@TPtr VarBinary (16),
--В эту переменную будем записывать номер символа в записи, с которого начинается
--вхождение искомой подстроки
@P Int
--Открываем курсор
Open Cur
--Читаем в переменную @TPtr адрес первой записи
Fetch From Cur Into
@TPtr
--Цикл, пока строки не кончились
While @@Fetch_Status = 0
Begin
--Ищем подстроку '/images/' в текущей строке
--Поскольку PatIndex возвращает № символа, а нам нужно будет смещение, вычитаем 1 Set @P = (
Select
PatIndex ('%/images/%', Content) From
Pages Where
TextPtr (Content) = @TPtr ) - 1
--Цикл, пока в текущей строке есть вхождения искомой подстроки
While @P >= 0
Begin
--Заменяем в поле Pages.Content по адресу @TPtr со смещением @P 8 символов на
'/pubimages/'
UpdateText Pages.Content @TPtr @P 8 '/pubimages/'
--Ищем следующее вхождение
Set @P = (
Select
PatIndex ('%/images/%', Content)
From
Pages
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
296 из 296 |
|
|
Where
TextPtr (Content) = @TPtr ) - 1 End
-- Читаем следующую запись
Fetch From Cur Into
@TPtr End
-- Закрываем и удаляем курсор
Close Cur Deallocate Cur
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
297 из 297 |
|
|
Процедуры
Reset всех объектных прав
RightsReset.sql
/*
*1. На всех разделах поставить права наследования от корня сервера.
*Исключение – группа «Системная бкофис». В ней права такие же, но без наследования (как сейчас).
*2. У всех материалов поставить права суммы всех разделов в которых они находятся.
*По факту у всех опубликованных материалов везде должны получиться такие же.
*3. Всем материалам добавить индивидуальное полное право для пользователя, являющегося текущим его автором.
*4. Проверить права на наличие дупликатов (раньше такое обнаруживали).
*
*/
--
-- Удалить записи о правах для всех разделов и материалов, кроме записей о правах корневого раздела сервера.
--
delete from usersobjrights
where type like '%fg%' and objid <> 4
delete from usersobjrights where type like '%fu%'
delete from usersobjrights
where type like '%ag%' or type like '%au%'
--
-- Добавить записи о правах для всех разделов, кроме корневого раздела сервера.
--
insert into UsersObjRights (AccountID, Type, ObjID, ORights, Inherited)
select s.AccountID, 'FG', f.[id], s.ORights, case when s.AccountID <> 25 then 1 else 0 end
from folders f
left join usersobjrights s on s.objid = 4 and s.type like '%fg%'
where [id] <> 4
--
-- Добавить записи о правах для всех материалов: группа "системная (бэкофис)" и автор материала.
--
insert into UsersObjRights (AccountID, Type, ObjID, ORights, Inherited) select 25, 'AG', a.[id], 3855, 0
from articles a
insert into UsersObjRights (AccountID, Type, ObjID, ORights, Inherited) select a.author, 'AU', a.[id], 3855, 0
from articles a
--
-- Добавить записи о правах для всех групп, кроме "системная (бэкофис)", -- суммируя права групп на разделы, куда опубликованы материалы.
--
insert into UsersObjRights (AccountID, Type, ObjID, ORights, Inherited) select distinct uor.accountid, 'AG', fa.article, uor.ORights, 1
from usersobjrights uor
left join folderarticles fa on uor.objid = fa.folder where type like '%fg%' and (fa.folder is not null) and uor.accountid <> 25 order by fa.article
/*
--
-- Определить материалы, информация о правах у которых есть больше одного раза для одной группы.
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
298 из 298 |
|
|
--
select distinct objid from usersobjrights uor
where (select count(accountid) from usersobjrights uor2 where uor2.objid = uor.objid and uor2.type='AG') > 9 and type='AG'
--
--Определить разделы, у которых: права по всем группах кроме «Системная (бэкофис)»
--являются ненаследуемыми
--
select * from usersobjrights where inherited=0 and type like '%FG%' and accountid <> 25 and objid <> 4
*/
Полное удаление пользователя
Пользователь помимо непосредственно записей в People и Clients со временем также становится собственником материалов, владельцем индивидуальных прав и т.д. Всего несколько десятков мест. Поскольку многие из принадлежностей удалить нельзя, то сначала нужно передать всю собственность другому пользователю, используя процедуру
exec UsersReplace ‘login_to_delete’, ‘login_existing_user’
После этого можно удалить пользователя из таблиц People и Clients
exec DeleteUser ‘administrator_login’, ‘administrator_password’, Id_to_delete, Id_to_delete_again
Проверка наличия посторонних данных в связанных таблицах
create table #tmp (id int, folder int)
insert into #tmp (id, folder)
select b.id, b.folderid from BannersInFolders b left join Folders f on f.id = b.folderid
where f.id is null
select * from #tmp
select * from BannersInFolders where folderid in (select folder from #tmp)
drop table #tmp
Очистка журнала событий
Поскольку чистка журнала из интерфейса работает медленно, созданы быстрые служебные процедуры для менее выборочной очистки:
1.Events_ClearEvents. Удаляет весь журнал. Не имеет параметров. Работает несколько секунд на любом объеме данных.
2.Events_ClearEventsEx. Удаляет все события с выбором периода и доменов. Параметры указаны внутри процедуры. Работает со скоростью примерно 200.000 записей в минуту на Pentium4, 3Ггц
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
299 из 299 |
|
|
Функции и приемы
Проверка наличия посторонних данных в связанных таблицах
create table #tmp (id int, folder int)
insert into #tmp (id, folder)
select b.id, b.folderid from BannersInFolders b left join Folders f on f.id = b.folderid
where f.id is null
select * from #tmp
select * from BannersInFolders where folderid in (select folder from #tmp)
drop table #tmp
Преобразование дат в строки
Хранимые процедуры возвращают даты из таблиц в формате 106 (dd Mon yyyy). Преобразование из внутреннего формата MS SQL Server в строку выполняется оператором
CONVERT (VARCHAR (20), Date, 106)
Аналогия функции «Replace» на XSL
Поскольку в XSL нет функции Replace, был создан рекурсивный шаблон, выполняющий эту функцию.
<xsl:template name="replace">
<xsl:param name="text"/><!-- исходный текст --> <xsl:param name="find"/><!-- строка поиска --> <xsl:param name="replace"/><!-- строка замены-->
<xsl:if test="string-length($text) > 0"> <xsl:choose>
<xsl:when test="contains($text,$find)">
<xsl:value-of select="substring-before($text,$find)"/> <xsl:value-of select="$replace"/>
<xsl:call-template name="replace">
<xsl:with-param name="text" select="substring-
after($text,$find)"/>
<xsl:with-param name="find" select="$find"/> <xsl:with-param name="replace" select="$replace"/>
</xsl:call-template> </xsl:when> <xsl:otherwise>
<xsl:value-of select="$text"/> </xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
Пример вызова
<xsl:call-template name="replace">
<xsl:with-param name="text" select="$storage/@Text"/> <xsl:with-param name="find" select="string(' ')"/> <xsl:with-param name="replace" select="string('<br >')"/>
</xsl:call-template>
Счетчик со статистикой
Copyright © 2005 Individ company |
Страница |
Контакты: www.saitistika.ru | support@saitistika.ru | (0852) 321464 |
300 из 300 |
|
|