Что нового

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

joiner

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

Исходник
DB.au3
В архиве варианты 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
 

inververs

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

joiner

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

kaster

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

joiner

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

kaster

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

joiner

Модератор
Локальный модератор
Сообщения
3 038
Репутация
505
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 038
Репутация
505
в данной реализации - только текстовые. так как все задумывалось для хранения информации а не файлов. то есть, это не архиватор в прямом смысле.
хотя , можно без больших переделок, как мне кажется, реализовать хранение разного рода информации. я не делал кодирование строк, файл читаем в текстовом редакторе. считаю это опцией. хотя, если база будет в несколько мегабайт или гигабайт, то ее затруднительно будет открыть в редакторе ;D

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

kaster

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

joiner

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

joiner

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

joiner

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

joiner

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