Exemple #1
0
/**
* Запустить приложение в пакетном режиме
*
* @param код результата, который вернуло приложение
* @param режим открытия информационной базы. Например: конфигуратор или предприятие
* @param аргументы запуска (может быть пустым)
*
* @result код результата и информация об ошибке (если есть)
 */
func (ib InformationBase) runApplication(mode string, args []string) (resultCode int, err error) {

	fullargs := []string{mode}
	ib.addAccessString(mode, &fullargs)
	for _, v := range args {

		if len(v) > 0 {
			fullargs = append(fullargs, v)
		}
	}
	addPathToLog(mode, &fullargs)

	cmd := exec.Command(ib.pathTo1C, fullargs...)
	utils.AddTextToLog(utils.LogLevel_INFO, "Командная строка: "+strings.Join(cmd.Args, " "))

	if err = cmd.Run(); err == nil {
		waitStatus := cmd.ProcessState.Sys().(syscall.WaitStatus)
		resultCode = waitStatus.ExitStatus()
	} else {
		utils.AddTextToLog(utils.LogLevel_ERROR, err.Error())

		if exitError, ok := err.(*exec.ExitError); ok {
			waitStatus := exitError.Sys().(syscall.WaitStatus)
			resultCode = waitStatus.ExitStatus()
		}
	}

	utils.AddTextToLog(utils.LogLevel_INFO, fmt.Sprintf("Код результата: %d", resultCode))
	return
}
Exemple #2
0
// Инициализация объекта данными из файла
func (c *ConfCf) InitFromFile(fileData []byte) error {

	utils.AddTextToLog(utils.LogLevel_INFO, "Начало инициализации объекта данными конфигурационного файла")

	if len(fileData) <= len(groupBlocksFlag) {
		return errors.New("Не верный размер файла конфигурационного файла")
	}

	if !bytes.Equal(fileData[:len(groupBlocksFlag)], groupBlocksFlag) {
		return errors.New("Данные не соотвествуют файлу конфигурационному файлу")
	}

	bloksHeadersPairs, err := readTOC(fileData)
	if err != nil {
		return err
	} else if len(bloksHeadersPairs) == 0 {
		return errors.New("Ошибка чтения заголовка.")
	}

	funcForInitBlocks := func(numStream int, processBlocksTotal int, countBlocks int, blockInitResultChanal chan bool) {
		for i := processBlocksTotal; i < countBlocks && i-processBlocksTotal != numStream; i++ {
			pair := bloksHeadersPairs[i]
			go c.blocksList[i].Init(fileData, pair.attrs, pair.data, blockInitResultChanal)
		}
	}

	c.initBlocks(len(bloksHeadersPairs), funcForInitBlocks)

	utils.AddTextToLog(utils.LogLevel_INFO, "-Окончание инициализации объекта данными конфигурационного файла")

	return nil
}
Exemple #3
0
// Инициализировать блок из данных сохраненных блоков в файлы
func (b *block) InitFromFiles(pathToDir string, fileInfo os.FileInfo, c chan<- bool) {

	utils.AddTextToLog(utils.LogLevel_TRACE, "Начало инициализации блока")

	var err error
	b.attrs.name = fileInfo.Name()
	currentTime := time.Now().UnixNano() / int64(time.Millisecond)
	fullPathToFile := path.Join(pathToDir, b.attrs.name)

	funcGenerateErr := func(errorNum int) {
		err = errors.New(fmt.Sprintf("Ошибка инициализации блока из даных файла №%d: %s", errorNum, err.Error()))
		utils.AddTextToLog(utils.LogLevel_ERROR, err.Error())
		panic(err.Error())
	}

	if fileInfo.IsDir() {
		b.blockType = blockType_multiple

		var files []os.FileInfo
		if files, err = utils.ReadFilesInDir(fullPathToFile); err != nil {
			funcGenerateErr(1)
		}

		b.subBlocks = make([]subBlock, len(files))
		for i, fi := range files {
			b.subBlocks[i].Attrs.name = fi.Name()
			b.subBlocks[i].Attrs.creationDate = currentTime
			b.subBlocks[i].Attrs.modificationDate = b.subBlocks[i].Attrs.creationDate

			pathToSubBlock := path.Join(fullPathToFile, fi.Name())
			if b.subBlocks[i].Data, err = ioutil.ReadFile(pathToSubBlock); err != nil {
				funcGenerateErr(2)
			}
		}

	} else {
		b.blockType = blockType_simply

		if b.data, err = ioutil.ReadFile(fullPathToFile); err != nil {
			funcGenerateErr(3)
		}

	}

	b.attrs.creationDate = currentTime
	b.attrs.modificationDate = b.attrs.creationDate
	if b.IsForm() {
		b.attrs.groupType = groupTypeForm
	} else if b.IsModule() {
		b.attrs.groupType = groupTypeModule
	} else {
		b.attrs.groupType = groupTypeNoModule
	}

	utils.AddTextToLog(utils.LogLevel_TRACE, "Окончание инициализации блока")
	c <- true
}
Exemple #4
0
/**
* Выполняет обновление конфигурации информационной базы 1С
*
* @param код результата, который вернуло приложение
*
* @result код результата и информация об ошибке (если есть)
 */
func (ib InformationBase) UpdateDBCfg() (resultCode int, err error) {

	utils.AddTextToLog(utils.LogLevel_INFO, "Обновление ИБ")

	args := []string{"/UpdateDBCfg"}
	resultCode, err = ib.runApplication(MODE_DESIGNER, args)

	utils.AddTextToLog(utils.LogLevel_INFO, fmt.Sprintf("-Обновление ИБ: %t", err == nil))
	return
}
Exemple #5
0
// Возвращает пары <заголовок атрибутов блока, заголовок данных блока> на основании ЧАСТИ оглавления файла
func readPartTOC(data []byte, pathHeader header, pairs *[]headersPair) (err error) {

	utils.AddTextToLog(utils.LogLevel_TRACE, "Начало чтения части оглавления")

	dataTOC := getRegion(data, pathHeader)
	addres := addresInTOC{}
	addresPath := addres.getElementSize()
	bytesInElement := addres.getSize()
	elements := len(dataTOC) / bytesInElement

	utils.AddTextToLog(utils.LogLevel_TRACE, "Резмер данных оглавления: "+utils.IntToString(len(dataTOC)))
	utils.AddTextToLog(utils.LogLevel_TRACE, "Количество элементов в оглавлении: "+utils.IntToString(elements))

	for i := 0; i < elements; i++ {
		startPos := i * bytesInElement

		blockAttrs := dataTOC[startPos : startPos+addresPath]
		blockData := dataTOC[startPos+addresPath : startPos+addresPath+addresPath]

		attrsPos := int(utils.BytesToInt32(blockAttrs))
		dataPos := int(utils.BytesToInt32(blockData))

		if !isHeader(data, attrsPos) || !isHeader(data, dataPos) {
			continue
		}

		attrsHeader, err := createHeader(data, attrsPos)
		if err != nil {
			break
		}
		dataHeader, err := createHeader(data, dataPos)
		if err != nil {
			break
		}

		if !attrsHeader.isAttributesData(data) || dataHeader.getDataSize() == 0 {
			continue
		}

		var newPair headersPair
		newPair.attrs = *attrsHeader
		newPair.data = *dataHeader

		*pairs = append(*pairs, newPair)
	}

	utils.AddTextToLog(utils.LogLevel_TRACE, "-Окончание чтения части оглавления")
	return
}
Exemple #6
0
/**
* Создать новую информационную базу
*
* @param код результата, который вернуло приложение
* @param шаблон конфигурации на основании которого необходимо создать информационную базу (может быть не указан)
*
* @result код результата и информация об ошибке (если есть)
 */
func (ib InformationBase) Create(pathToTemplate string) (resultCode int, err error) {

	utils.AddTextToLog(utils.LogLevel_INFO, "Создание новой ИБ: "+pathToTemplate)

	if len(pathToTemplate) > 0 {
		var exist bool
		exist, err = utils.Exists(pathToTemplate)
		if err != nil {
			utils.AddTextToLog(utils.LogLevel_ERROR, err.Error())
			return
		} else if !exist {
			err = errors.New("Файл не найден: " + pathToTemplate)
			utils.AddTextToLog(utils.LogLevel_ERROR, err.Error())
			return
		}
	}

	err = utils.RemoveIfExist(ib.connectionSettings.GetIbPath())
	if err != nil {
		utils.AddTextToLog(utils.LogLevel_ERROR, "Ошибка удаления каталога: "+ib.connectionSettings.GetIbPath()+":"+err.Error())
		return
	}

	/*
		1С предлагает для создания новой конфигурации на основе существующего
		cf файла использование параметра /UseTemplate, но по какой-то причине
		на некоторых версия платформы он работает не корректно.

		Поэтому делаем в два этапа:
		1. создаем новую конфигурацию
		2. загружаем в нее нужный cf файл
		3. обновляем конфигурацию информационной базы
	*/

	args := []string{}
	resultCode, err = ib.runApplication(MODE_CREATE, args)

	if err == nil && len(pathToTemplate) > 0 {
		resultCode, err = ib.LoadCfg(pathToTemplate)
	}

	if err == nil {
		resultCode, err = ib.UpdateDBCfg()
	}

	utils.AddTextToLog(utils.LogLevel_INFO, fmt.Sprintf("-Создание новой ИБ: %t", err == nil))
	return
}
Exemple #7
0
/**
* Выгрузка свойств объектов метаданных конфигурации в XML-файлы
*
* @param код результата, который вернуло приложение
* @param каталог, в который будет выгружена конфигурация
*
* @result код результата и информация об ошибке (если есть)
 */
func (ib InformationBase) DumpConfigToFiles(pathToDirectory string) (resultCode int, err error) {

	utils.AddTextToLog(utils.LogLevel_INFO, "Выгрузка конфигурации в xml: "+pathToDirectory)

	err = utils.RemoveIfExist(pathToDirectory)
	if err != nil {
		utils.AddTextToLog(utils.LogLevel_ERROR, "Ошибка удаления каталога: "+pathToDirectory+":"+err.Error())
		return
	}

	args := []string{"/DumpConfigToFiles", pathToDirectory}
	resultCode, err = ib.runApplication(MODE_DESIGNER, args)

	utils.AddTextToLog(utils.LogLevel_INFO, fmt.Sprintf("-Выгрузка конфигурации в xml: %t", err == nil))
	return
}
Exemple #8
0
/**
* Сохранить конфигурацию в файл
*
* @param код результата, который вернуло приложение
* @param путь к файлу результата
*
* @result код результата и информация об ошибке (если есть)
 */
func (ib InformationBase) DumpCfg(pathToFile string) (resultCode int, err error) {

	utils.AddTextToLog(utils.LogLevel_INFO, "Сохранение cf: "+pathToFile)

	err = utils.RemoveIfExist(pathToFile)
	if err != nil {
		utils.AddTextToLog(utils.LogLevel_ERROR, "Ошибка удаления файла: "+pathToFile+":"+err.Error())
		return
	}

	args := []string{"/DumpCfg", pathToFile}
	resultCode, err = ib.runApplication(MODE_DESIGNER, args)

	utils.AddTextToLog(utils.LogLevel_INFO, fmt.Sprintf("-Сохранение cf: %t", err == nil))
	return
}
Exemple #9
0
// Найти заголовки блоков оглавления (оглавление может состоять из нескольских блоков)
// @param данные файла
// @result заголовки областей оглавления, описание ошибки (если есть)
func findTOC(data []byte) (headerTOC []header, err error) {

	utils.AddTextToLog(utils.LogLevel_TRACE, "Начало поиска оглавления")

	err = errors.New("Оглавление не найдено")
	var previousHeader *header

	for i := 0; i < len(data); i++ {

		if !isHeader(data, i) {
			continue
		}

		err = nil
		utils.AddTextToLog(utils.LogLevel_TRACE, "Позиция части оглавления: "+utils.IntToString(i))
		previousHeader, err = createHeader(data, i)
		break
	}

	for true {
		if err != nil {
			headerTOC = make([]header, 0)
			break
		}

		headerTOC = append(headerTOC, *previousHeader)

		if previousHeader.getNextHeaderPosition() == 0 {
			break
		} else {
			i := previousHeader.getNextHeaderPosition()
			if i > len(data) {
				break
			}

			utils.AddTextToLog(utils.LogLevel_TRACE, "Позиция части оглавления: "+utils.IntToString(i))
			previousHeader, err = createHeader(data, i)
		}
	}

	utils.AddTextToLog(utils.LogLevel_TRACE, "-Окончание поиска оглавления")

	return
}
Exemple #10
0
// Инициализировать блок данными из файла
// @param данные файла
// @param заголовок атрибутов блока
// @param заголовок данных блока
// @param канал в который будет записана инфорамция что блок инициализирован
func (b *block) Init(sourceData []byte, attrsHeader header, dataHeader header, c chan<- bool) {

	utils.AddTextToLog(utils.LogLevel_TRACE, "Начало инициализации блока")

	var blockData []byte
	getAttrsAndData(sourceData, attrsHeader, dataHeader, &b.attrs, &blockData)
	sourceLen := len(blockData)
	if sourceLen > 0 {
		var err error

		blockData, err = zlibwrapper.Decompress(blockData)
		if err != nil {
			panic("Ошибка распаковки блока: " + b.attrs.name)
		}
	}

	headersTOC, err := findTOC(blockData)

	if err == nil &&
		len(headersTOC) > 0 &&
		bytes.Equal(groupBlocksFlag, blockData[:len(groupBlocksFlag)]) {

		b.blockType = blockType_multiple

		subBlocksHeadersPairs, err := readTOC(blockData)
		if err != nil {
			panic("Ошибка разбора составного блока: " + err.Error())
		}

		b.subBlocks = make([]subBlock, len(subBlocksHeadersPairs))

		for i, p := range subBlocksHeadersPairs {
			getAttrsAndData(blockData, p.attrs, p.data, &b.subBlocks[i].Attrs, &b.subBlocks[i].Data)
		}
	} else {
		b.data = blockData
		b.blockType = blockType_simply
	}

	utils.AddTextToLog(utils.LogLevel_TRACE, "Окончание инициализации блока")
	c <- true
}
Exemple #11
0
// Создать новый конфигурационный файл на основании данных файлов содержащихся в каталоге
func buildCf(pathToDirWithSourceData string, pathToCf string) {

	pathToTarget := createTargetDir(utils.GetParentDir(pathToCf))

	utils.InitLogger(pathToTarget, utils.LogLevel_INFO)
	utils.AddTextToLog(utils.LogLevel_INFO, "Начало")

	var err error
	var objectCf cf.ConfCf
	if err = objectCf.InitFromCatalog(pathToDirWithSourceData); err != nil {
		panic(err.Error())
	}

	fileData := objectCf.GetDataForConfigFile()
	if err = ioutil.WriteFile(pathToCf, fileData, os.ModeAppend); err != nil {
		panic(err.Error())
	}

	utils.AddTextToLog(utils.LogLevel_INFO, "-Завершение")
}
Exemple #12
0
/**
* Загрузить конфигурацию из cf файла
*
* @param полный путь к cf файлу
*
* @result код результата и информация об ошибке (если есть)
 */
func (ib InformationBase) LoadCfg(pathToFile string) (resultCode int, err error) {

	utils.AddTextToLog(utils.LogLevel_INFO, "Загрузка cf:"+pathToFile)

	exist, err := utils.Exists(pathToFile)
	if err != nil {
		utils.AddTextToLog(utils.LogLevel_ERROR, err.Error())
		return
	} else if !exist {
		err = errors.New("Файл не найден: " + pathToFile)
		utils.AddTextToLog(utils.LogLevel_ERROR, err.Error())
		return
	}

	args := []string{"/LoadCfg", pathToFile}
	resultCode, err = ib.runApplication(MODE_DESIGNER, args)

	utils.AddTextToLog(utils.LogLevel_INFO, fmt.Sprintf("-Загрузка cf: %t", err == nil))
	return
}
Exemple #13
0
// Возвращает пары <заголовок атрибутов блока, заголовок данных блока> на основании оглавления файла
func readTOC(data []byte) (pairs []headersPair, err error) {

	utils.AddTextToLog(utils.LogLevel_TRACE, "Начало чтения оглавления")

	pairs = make([]headersPair, 0)
	headersTOC, err := findTOC(data)
	if err == nil {
		for _, h := range headersTOC {
			err = readPartTOC(data, h, &pairs)
			if err != nil {
				pairs = make([]headersPair, 0)
				break
			}
		}
	}

	utils.AddTextToLog(utils.LogLevel_TRACE, "-Окончание чтения оглавления. Найдено блоков: "+utils.IntToString(len(pairs)))

	return
}
Exemple #14
0
/**
* Выгрузка свойств объектов метаданных конфигурации (модули и шаблоны)
*
* @param каталог расположения файлов свойств
* @param типы которые выгружаем:
*                   Module — признак необходимости выгрузки модулей;
                    Template — признак необходимости выгрузки макетов;
                    Help — признак необходимости выгрузки справочной информации;
                    AllWritable — признак выгрузки свойств только доступных для записи объектов;
                    Picture — признак выгрузки общих картинок;
                    Right — признак выгрузки прав.
*
* @result код результата и информация об ошибке (если есть)
*/
func (ib InformationBase) DumpConfigFiles(pathToDirectory string, types ...string) (resultCode int, err error) {

	utils.AddTextToLog(utils.LogLevel_INFO, "Выгрузка конфигурации: "+pathToDirectory)

	err = utils.RemoveIfExist(pathToDirectory)
	if err != nil {
		utils.AddTextToLog(utils.LogLevel_ERROR, "Ошибка удаления каталога: "+pathToDirectory+":"+err.Error())
		return
	}

	// /DumpConfigFiles "{0}" -Module -Template
	args := []string{"/DumpConfigFiles", pathToDirectory}
	for _, v := range types {
		args = append(args, "-"+v)
	}
	resultCode, err = ib.runApplication(MODE_DESIGNER, args)

	utils.AddTextToLog(utils.LogLevel_INFO, fmt.Sprintf("-Выгрузка конфигурации: %t", err == nil))
	return
}
Exemple #15
0
/**
* Загрузка свойств объектов метаданных конфигурации
*
* @param код результата, который вернуло приложение
* @param каталог, содержащий XML-файлы конфигурации
*
* @result код результата и информация об ошибке (если есть)
 */
func (ib InformationBase) LoadConfigFromFiles(pathToDirectory string) (resultCode int, err error) {

	utils.AddTextToLog(utils.LogLevel_INFO, "Загрузка конфигурации из xml: "+pathToDirectory)

	exist, err := utils.Exists(pathToDirectory)
	if err != nil {
		utils.AddTextToLog(utils.LogLevel_ERROR, err.Error())
		return
	} else if !exist {
		err = errors.New("Каталог не найден: " + pathToDirectory)
		utils.AddTextToLog(utils.LogLevel_ERROR, err.Error())
		return
	}

	args := []string{"/LoadConfigFromFiles", pathToDirectory}
	resultCode, err = ib.runApplication(MODE_DESIGNER, args)

	utils.AddTextToLog(utils.LogLevel_INFO, fmt.Sprintf("-Загрузка конфигурации из xml: %t", err == nil))
	return
}
Exemple #16
0
// Добавляет оглавление группового блока
func addTableOfContent(fileData *[]byte, addresses []addresInTOC) {

	utils.AddTextToLog(utils.LogLevel_TRACE, "Начало добавления оглавления")

	addres := addresInTOC{}
	delimetr := utils.Int32ToBytes(emptyValue)
	countBlocks := len(addresses)
	valuableTOCSize := addres.getSize() * countBlocks
	fullTOCSize := valuableTOCSize

	if fullTOCSize < defaultBlockSize {
		fullTOCSize = defaultBlockSize
	}

	data := []byte{}
	utils.AddToSlice(&data,
		groupBlocksFlag,                              // маркер группы
		utils.Int32ToBytes(defaultBlockSize),         // размер блока по умолчанию
		[]byte{0x00, 0x00, 0x00, 0x00},               // unknown
		[]byte{0x00, 0x00, 0x00, 0x00},               // unknown
		getHeaderForCf(valuableTOCSize, fullTOCSize)) // Заголовок области оглавления

	beginFileDataLen := int32(len(data) + fullTOCSize)

	for _, v := range addresses {
		utils.AddToSlice(&data,
			utils.Int32ToBytes(v.AttrsPos+beginFileDataLen), // позиция заголовка атрибутов блока
			utils.Int32ToBytes(v.DataPos+beginFileDataLen),  // позиция заголовка данных блока
			delimetr) // макер разделителя адресов
	}

	emptyData := []byte{}
	if valuableTOCSize < fullTOCSize {
		emptyData = make([]byte, fullTOCSize-valuableTOCSize)
	}

	data = append(data, emptyData...)
	*fileData = append(data, (*fileData)...)

	utils.AddTextToLog(utils.LogLevel_TRACE, "-Окончание добавления оглавления")
}
Exemple #17
0
// Инициализация объекта данными из каталого содержащего распакованный конфигурационный блок
func (c ConfCf) InitFromCatalog(pathToDir string) (err error) {

	utils.AddTextToLog(utils.LogLevel_INFO, "Начало инициализации объекта данными конфигурационного файла из каталога")

	var fileInfos []os.FileInfo

	if fileInfos, err = utils.ReadFilesInDir(pathToDir); err != nil {
		return err
	}

	funcForInitBlocks := func(numStream int, processBlocksTotal int, countBlocks int, blockInitResultChanal chan bool) {
		for i := processBlocksTotal; i < countBlocks && i-processBlocksTotal != numStream; i++ {
			fi := fileInfos[i]
			go c.blocksList[i].InitFromFiles(pathToDir, fi, blockInitResultChanal)
		}
	}

	c.initBlocks(len(fileInfos), funcForInitBlocks)

	utils.AddTextToLog(utils.LogLevel_INFO, "-Окончание инициализации объекта данными конфигурационного файла из каталога")

	return nil
}
Exemple #18
0
// Распаковать конфигурационный файл в каталог
func unpackToDir(pathToCf string, pathToTarget string) {

	createTargetDir(pathToTarget)

	utils.InitLogger(pathToTarget, utils.LogLevel_INFO)
	utils.AddTextToLog(utils.LogLevel_INFO, "Начало")

	var err error
	var fileData []byte
	if fileData, err = ioutil.ReadFile(pathToCf); err != nil {
		panic(err.Error())
	}

	pathToUnpackDir := createTargetDir(path.Join(pathToTarget, "unpack"))

	var objectCf cf.ConfCf
	if err = objectCf.InitFromFile(fileData); err != nil {
		panic(err.Error())
	}

	objectCf.SaveBlocksToFiles(pathToUnpackDir)

	utils.AddTextToLog(utils.LogLevel_INFO, "-Завершение")
}