Что нового

Создание базы данных. Концепция

joiner

Модератор
Локальный модератор
Сообщения
3 109
Репутация
518
Версия AutoIt
3.3.12.0
Версия
1
AutoIt: 3.3.12.0

Категория: База данных

Описание: Создание базы документов. Документы в базе не кодированы и не сжаты
Функции предназначены для создания базы документов и работы с ними: запись, редактирование, удаление. Не путать с архиватором.

Примеры
Создание базы:
Код:
#include <DB.au3>
#include <File.au3>
$files = _FileListToArrayRec('C:\Script', '*.au3', 1, 1, 0, 2)
$PathBase = 'D:\base.txt'
Local $aArrayPoint = _LoadBase($PathBase, 0)
For $i = 1 To $files[0]
    $fr = FileRead($files[$i])
    $name = StringRegExpReplace($files[$i], '^(?:.*\\)([^\\]*?)(?:\.[^.]+)?$', '\1')
    _WriteDoc($aArrayPoint[0], $aArrayPoint[1], $PathBase, $name, $fr)
Next

Работа с базой:
Код:
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include <DB.au3>

Local $PathBase = 'D:\base.txt'
Global $datadocinit, $text, $fr, $datadoc = '', $datalistw, $indexlist = ''
Global $Form1 = GUICreate("Form1", 901, 438, 192, 124)
Global $ListView1 = GUICtrlCreateListView("", 8, 8, 410, 422, $LVS_SHOWSELALWAYS, BitOR($LVS_EX_GRIDLINES, $LVS_EX_DOUBLEBUFFER, $LVS_EX_FULLROWSELECT))
_GUICtrlListView_AddColumn($ListView1, "Список документов", 300)
Global $Edit1 = GUICtrlCreateEdit('', 432, 8, 457, 225)
Global $Input1 = GUICtrlCreateInput("", 432, 248, 457, 21)
$Button1 = GUICtrlCreateButton("Создать", 432, 280, 75, 25);записываем новый документ
$Button2 = GUICtrlCreateButton("Изменить", 632, 280, 75, 25);изменяем документ
$Button3 = GUICtrlCreateButton("Удалить", 816, 280, 75, 25)
GUISetState(@SW_SHOW)

Local $aArrayPoint = _LoadBase($PathBase);загрузить весь список имен
;----------Пример загрузки базы по имени документа------------------------------
;Local $aArrayPoint = _LoadBase($PathBase,'имя',1,1);полное совпадение
;Local $aArrayPoint = _LoadBase($PathBase,'имя',1,0);частичное совпадение
;описание параметров поиска смотри в описании функции _LoadDocsList()
;-------------------------------------------------------------------------------

If IsArray($aArrayPoint[0]) Then
    For $i = 0 To UBound($aArrayPoint[0]) - 1
        _GUICtrlListView_AddItem($ListView1, ($aArrayPoint[0])[$i][0])
    Next
EndIf

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While 1
    If $fr Then
        $fr = 0
        $datadocinit = _ReadDoc($aArrayPoint[0], $text, $PathBase)
        If IsArray($datadocinit) Then
            GUICtrlSetData($Input1, $text)
            For $i = 0 To UBound($datadocinit) - 1
                $datadoc &= $datadocinit[$i][0]
            Next
            GUICtrlSetData($Edit1, $datadoc)
            $datadoc = ''
        EndIf
    EndIf
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button1
            $readname = GUICtrlRead($Input1)
            $readtext = GUICtrlRead($Edit1)
            If Not _WriteDoc($aArrayPoint[0], $aArrayPoint[1], $PathBase, $readname, $readtext) Then
                GUICtrlSetData($Edit1, '')
                GUICtrlSetData($Input1, '')
                _GUICtrlListView_AddItem($ListView1, ($aArrayPoint[0])[UBound($aArrayPoint[0]) - 1][0])
            EndIf
        Case $Button2
            $newname = GUICtrlRead($Input1)
            $newdata = GUICtrlRead($Edit1)
            If Not _EditDoc($aArrayPoint[0], $datadocinit, $PathBase, $newname, $newdata) Then
                _GUICtrlListView_SetItemText($ListView1, $indexlist, $datadocinit[0][3])
            EndIf
        Case $Button3
            If Not _RemoveDoc($aArrayPoint[0], $datadocinit, $PathBase) Then
                _GUICtrlListView_DeleteItem($ListView1, $indexlist)
                GUICtrlSetData($Edit1, '')
                GUICtrlSetData($Input1, '')
            EndIf
    EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $imsg, $wParam, $lParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $iIDFrom
        Case $ListView1
            Switch $iCode
                Case $NM_DBLCLK
                    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                    $indexlist = DllStructGetData($tInfo, "Index")
                    $text = _GUICtrlListView_GetItemText($ListView1, $indexlist, 0)
                    $fr = 1
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Исходник
В архиве варианты UDF
DB_33120 - AutoIT 3.3.12.0
DB_33140 - Autoit 3.3.14.0
DBSD_33140 - Autoit 3.3.14.0 (используется Scripting.Dictionary)

Источник: autoit-script.ru
Автор(ы): joiner
 
Автор
joiner

Вложения

  • 7,2 КБ Просмотры: 1
Последнее редактирование:

inververs

AutoIT Гуру
Сообщения
2 135
Репутация
462
Какую проблему решает? Зачем это? Можно поподробнее?
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 109
Репутация
518
проблем нет. ключевое слово - "концепция"
общий смысл - хранение многого в одном. возможность редактировать часть записи без перезаписи всего файла и пр. :smile:
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
joiner
почему 12 байт? почему текст? можно прикрепить маленький пример базы?
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 109
Репутация
518
Это не готовый продукт, все условно. Пример базы можно получить, запустив примеры выше. Я хотел немного порассуждать , как создать своё, не прибегая к общеизвестным типам баз данных :smile:
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
joiner [?]
Пример базы можно получить, запустив примеры выше
я знаю, что так можно получить базу. но ни под рукой, ни на расстоянии "километра", винды нет. иначе бы не спрашивал.
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 109
Репутация
518
damien2008 [?]
почитай здесь http://autoit-script.ru/index.php?topic=9479.15
там я указал на ограничение такой записи
если в двух словах, то в моем примере мы лишь получаем список документов с указателями на позиции документов в базе. чтение нужного документа происходит не методом перебора , как это сделано в Package
Yashied [?]
Еще раз про падение скорости. Технически, для извлечения каждого пакета необходимо сначала найти его в архиве, последовательно перечислив все пакеты, располагающиеся до искомого пакета. Таким образом получается, что чем дальше от начала файла находится извлекаемый пакет, тем больше времени потребуется на его поиск.
а установкой указателя на нужную позицию и чтение. это дает значительный прирост в скорости получения содержания документа


Добавлено:
Сообщение автоматически объединено:

пример содержание базы. смотри скрин
http://autoit-script.ru/autoit_rv_ua/files/Administration/base.jpg


Добавлено:
Сообщение автоматически объединено:

следующие два фото - пример, когда заполнен первый блок и начат второй - 200 документов. два снимка базы
http://autoit-script.ru/autoit_rv_ua/files/Administration/base1.jpg
http://autoit-script.ru/autoit_rv_ua/files/Administration/base2.jpg
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
это только для текстовых данных? можно ли иметь одинаковые имена документов?
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 109
Репутация
518
в данной реализации - только текстовые. так как все задумывалось для хранения информации а не файлов. то есть, это не архиватор в прямом смысле.
хотя , можно без больших переделок, как мне кажется, реализовать хранение разного рода информации. я не делал кодирование строк, файл читаем в текстовом редакторе. считаю это опцией. хотя, если база будет в несколько мегабайт или гигабайт, то ее затруднительно будет открыть в редакторе ;D

можно иметь одинаковые имена.проверка на совпадение не производится. каждый документ имеет свою позицию в файле.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
joiner [?]
можно иметь одинаковые имена
а вот это строка в функции _ReadDoc что делает?
Код:
If Not StringCompare(StringStripWS($NameDoc, 3), $ListDoc[$i][0]) Then
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 109
Репутация
518
Ищет совпадение по имени. Но при записи в базу нет проверки. Соответственно, все документы с одинаковыми именами выводятся в список
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 109
Репутация
518
Изменения в UDF
1.Функции загрузки базы объединены в одну с параметрами загрузки(смотри пример)
а)загрузка документов по имени
б)загрузка документов по дате
в)загрузка документов по типу
г)загрузка всего списка (по умолчанию)
2. Функция записи документа в базу может дописывать документ в существующую базу без загрузки списка . Массовая дописка документов(смотри пример создания базы)
3. Имя документа ограничено 250-ю символами.
Если есть возможность, протестируйте.
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 109
Репутация
518
изменение функции загрузки базы.
функция возвращает массив с указателями на два массива - массив списка и массив последних позиций для записи(смотри описания к функциям)
изменены примеры в первом сообщении.
плюс некоторые мелкие поправки
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3 109
Репутация
518
Сделал изменения согласно последней версии AutoIT 3.3.14.0
В архиве три варианта (смотри первое сообщение темы)
 
Верх