# -*- coding: utf-8 -*-
#|L_DBase


#----------------------------------------------------------
# Пример взят из SDK - Step4
# и конвертирован на Python.
#
# Для работы апиложения скопируйте из SDK - Step4
# в текущую папку файл текстовой базы данных
# Step4.loa
#
# В оригинале номер атрибута запрашивается через ksReadDouble,
# но фактически введеное значение урезается до 9 знаков
# что естетсвенно приводит к отрицательному результату.
# Для устранения этой проблемы в данном примере
# используется ksReadString с дальнейшим преобразованием
# через функцию Python - int().
#----------------------------------------------------------

import pythoncom
from win32com.client import Dispatch, gencache

# Подключение библиотеки коллекций для работы со структурой
from collections import namedtuple

import LDefin2D
import MiscellaneousHelpers as MH

#  Подключим константы API Компас
const_2d = gencache.EnsureModule("{75C9F5D0-B5B8-4526-8681-9903C567D2ED}", 0, 1, 0).constants

#  Подключим описание интерфейсов API5
kapi_5 = gencache.EnsureModule("{0422828C-F174-495E-AC5D-D31014DBBE87}", 0, 1, 0)
iKompas_5 = kapi_5.KompasObject(Dispatch("Kompas.Application.5")._oleobj_.QueryInterface(kapi_5.KompasObject.CLSID, pythoncom.IID_IDispatch))
MH.iKompasObject = iKompas_5



#  Получим активный документ
iDocument2D_5 = iKompas_5.ActiveDocument2D()

#---------------------------------
# Работа с текстовой базой данных
#---------------------------------

# Создаем аналог структуры C++
b = namedtuple('b', ('dr', 'l', 'f'))

data = kapi_5.ksDataBaseObject( iKompas_5.DataBaseObject() )
par = kapi_5.ksUserParam( iKompas_5.GetParamStruct(const_2d.ko_UserParam) )
item = kapi_5.ksLtVariant( iKompas_5.GetParamStruct(const_2d.ko_LtVariant) )
arr = kapi_5.ksDynamicArray( iKompas_5.GetDynamicArray(LDefin2D.LTVARIANT_ARR) )
if ( par and item and data ):
    par.Init()
    par.SetUserArray( arr )
    item.Init()
    item.doubleVal = 0
    arr.ksAddArrayItem( -1, item )
    item.Init()
    item.doubleVal = 0
    arr.ksAddArrayItem( -1, item )
    item.Init()
    item.intVal = 0
    arr.ksAddArrayItem( -1, item )
    libName = iKompas_5.ksChoiceFile( "*.loa","Базы данных(*.loa)|*.loa|Все файлы (*.*)|*.*|", 1 )
    if( libName ):
        bd = data.ksCreateDB("TXT_DB") # Создать объект, обслуживающий базу данных
        if (data.ksConnectDB(  bd, libName) ): # Связать объект базы с определенной базой данных( для текстового файла - имя файла )
            r1 = data.ksRelation( bd )  # Создать отношение - буфер для считывания информации из таблицы
            data.ksRDouble( "dr")   # имена даются ключевым колонкам,
            data.ksRDouble( "L" )   # по ним в дальнейшем формируются условия выборки
            data.ksRInt("")
            data.ksEndRelation()

            # Установить запрос - отношение связывается с базой( указываем какие колонки
            # базы связать с переменными буфера )
            data.ksDoStatement( bd, r1, "1 2 3" )   # Колонка dr - 1, L - 2, оставшаяся колонка -3
            i= data.ksReadRecord( bd, r1, par )     # Считать очередную порцию информации и положть в структуру b
            while( i ):
                arr.ksGetArrayItem( 0, item )
                b.dr = item.doubleVal
                arr.ksGetArrayItem( 1, item )
                b.l = item.doubleVal
                arr.ksGetArrayItem( 2, item )
                b.f = item.intVal
                strMes = " DR = " + '{0:f}'.format(b.dr) + "\n" \
                + " L = " + '{0:f}'.format(b.l) + "\n" \
                + " F = " + '{0:d}'.format(b.f)
                iKompas_5.ksMessage(strMes)

                i= data.ksReadRecord( bd, r1, par )
            iKompas_5.ksMessage("end")
            i = 1
            arr.ksClearArray()
            item.Init()
            item.strVal = ""
            arr.ksAddArrayItem( -1, item )
            r2 = data.ksRelation( bd ) # Создать отношение - буфер для считывания информации из таблицы
            data.ksRChar( "", 255, 0 )
            data.ksEndRelation()

            data.ksDoStatement( bd, r2, "2")  # Установить запрос - отношение связывается с базой( указываем какие колонки
            while( i ):
                i= data.ksReadRecord( bd, r2, par ) # Считать очередную порцию информации и положть в структуру b
                if ( i ):
                    arr.ksGetArrayItem( 0, item )
                    strMes = "L = " + item.strVal
                    iKompas_5.ksMessage( strMes )

            iKompas_5.ksMessage( "end")

            con = namedtuple('con', ('a', 'l'))
            i = 1

            arr.ksClearArray()
            item.Init()
            item.doubleVal = 0
            arr.ksAddArrayItem( -1, item )
            item.Init()
            item.doubleVal = 0
            arr.ksAddArrayItem( -1, item )
            r3 = data.ksRelation( bd )  # Создать отношение - буфер для считывания информации из таблицы
            data.ksRDouble("")
            data.ksRDouble("L")
            data.ksEndRelation()

            data.ksDoStatement( bd, r3, "1 2") # Установить запрос - отношение связывается с базой( указываем какие колонки
            data.ksCondition( bd, r3, "L=100||L=150")
            while( i ):
                i= data.ksReadRecord( bd, r3, par ) # Считать очередную порцию информации и положть в структуру b
                if ( i ):
                    arr.ksGetArrayItem( 0, item )
                    con.a = item.doubleVal
                    arr.ksGetArrayItem( 1, item )
                    con.l = item.doubleVal
                    strMes = " dr = " + '{0:f}'.format(con.a) + "\n" \
                    + " L = " + '{0:f}'.format(con.l)
                    iKompas_5.ksMessage(strMes)
            iKompas_5.ksMessage( "end")

data.ksDeleteDB( bd )   # Удалить обьект, обслуживающий базу данных

