Что нового

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

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Версия 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

Вложения

  • DB.7z
    7.2 КБ · Просмотры: 16
Последнее редактирование:

inververs

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

joiner

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

kaster

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

joiner

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

kaster

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

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
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
Репутация
626
это только для текстовых данных? можно ли иметь одинаковые имена документов?
 
Автор
joiner

joiner

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

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

kaster

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

joiner

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

joiner

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

joiner

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

joiner

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