发信人: yuce()
整理人: hunter__fox(2002-03-16 22:01:29), 站内信件
|
VFP数据库、表、索引等灾难一键恢复
VFP应用系统在使用时,由于用户非正常退出、特别是程序对多用户状态下封锁机
制运用不当、系统运行掉电造成:索引破坏、数据库(.DBC)与实际表索引不匹配
、数据库(.DBC)中记录的字段与实际表不一致等情况出现,虽不是经常性的问题
,一旦出现可能非要专业人员”出马”才能搞定!当然最常用的方法是经常备份
系统(包括.DBC,.DBF,.CDX等),但在某些时点上可能备份也不顶用了。
曾见网友遭此劫难求救于网易VFP论坛上。当时本人已在解决此事,因无完整预案
只得安慰网友:某日解决定相告吾友。随后日子工作繁忙,断断续续搞了近一个
月,方法已近成型,只是不够通用扔在硬盘里。某日无意发现自已硬盘的VFP6.0
系统中躺着一个叫GENDBC文件夹,打开GENDBC.PRG程序一个。会不会…?!哇噻
! 我的想法MS的VFP高手竟已写出完整的程序!不知为什么MS就是不说,正版手
册也无从查阅!再也能不犹疑了,仔细阅读,加入自己思路。一个较完整灾难恢
复方法偷“出笼”来。
GENDBC的思路是这样的:将一个已存在的.DBC(内含.DBF,.CDX及各种视图,远程
连接,存贮过程,表间联接关系)转换成一个.DBC的重建程序(ie:databk.prg)。
当系统有问题时:运行databk.prg,自动重建上述数据库及空表。本人在已将此
程序改成了将已有的数据再导入重建的空表中从而完成灾难恢复。此程序已在我
的VFP应用系统中成功应用。我的VFP应用系统中数据库中几乎包括了所有可能的
本远地视图,远程与AS400的连接,触发器,RI关联等。源程序附上,请各位VFP
的看官,挑挑错、强化程序,如谁完成了.FPT文件的通用程序自动恢复,请一定
告之。
My email: [email protected] 中信实业银行嘉兴支行 於策
********************************************************************** ****
** Program Name : GENDBC.PRG此程序来自VFP6.0的示例程序,并修改为带路径 生成
** 数据库及表,索引文件 於策改于 1999.7.8
** Creation Date: 94.12.01
**
** 用途 : 将一已存在的VFP3.0--VFP6.0数据库及其包含的所有内容变换成一可 输出
** 的程序(可重建库数据库程序re_build_database),该程序可再现该 数据库
** 及表,视图,连接,存贮过程等。起数据库备份及恢复如" 索引与数据 库不匹
** 配"等索引文件破坏错误。
** 参数 : cOutFile : 一个输入文件名(可包含路径扩展表,如省略为 .prg )
** lskipdisplay: 一个表示是否显示工作进度的逻辑变量
**
********************************************************************** ****
LPARAMETERS cOutFile,lskipdisplay
PRIVATE ALL EXCEPT g_*
*! Public Variables
m.g_cSafety = SET("SAFETY")
set safety off
IF SET("TALK") = "ON" && To restore SET TALK after use
SET TALK OFF && -- Have to do it this way so
m.g_cSetTalk = "ON" && -- nothing get's on screen
ELSE
m.g_cSetTalk = "OFF"
ENDIF
m.g_lskipdisplay = IIF(vartype(lskipdisplay)#"L",.F.,lskipdisplay)
m.g_cFullPath = SET("FULLPATH") && To restore old FULLPATH setting
m.g_cOnError = ON("ERROR") && To restore old ON ERROR condition
m.g_cSetDeleted = SET("DELETED") && To restore SET DELETED later
m.g_cSetStatusBar = SET("STATUS BAR") && To restore STATUS bar
m.g_cStatusText = SYS(2001, "MESSAGE", 1) && To restore text that may be on it
m.g_nMax = 7 && 为状态栏准备的最大信息数
m.g_nCurrentStat = 1 && 为状态栏准备的当前信息数
m.g_cFilterExp = "" && For Non-Supported Filte r Info
DIMENSION g_aProcs[1]
SET DELETED ON
SET FULLPATH ON
IF m.g_cSetStatusBar = "OFF"
SET STATUS BAR ON
ENDIF
*! 错误处理例程
ON ERROR DO GenDBC_Error WITH MESSAGE(), LINENO()
********************************************************************** ****
** Constants
********************************************************************** ****
#DEFINE CRLF CHR(13) + CHR(10)
#DEFINE DBCS_LOC "81 82 86 88"
********************************************************************** ****
** Error Messages
********************************************************************** ****
#DEFINE NO_DATABASE_IN_USE_LOC "没有打开任何数据库。本程序运行时必须要 有一个数据库可用。"
#DEFINE INVALID_PARAMETERS_LOC "无效参数..." + CRLF +"应该指定一个输出 文件" + CRLF +'ie: DO GENDBC WITH "filename.prg"'
#DEFINE INVALID_DESTINATION_LOC "无效的目标文件"
#DEFINE NO_TEMP_FILE_LOC "不能创建临时文件: "
#DEFINE NO_OUTPUT_WRITTEN_LOC "不能创建输出文件或不能向输出文件写内容 "
#DEFINE ERROR_TITLE_LOC "放弃 GenDBC..."
#DEFINE UNRECOVERABLE_LOC "不可恢复的错误:"
#DEFINE AT_LINE_LOC " 行: "
#DEFINE NO_FIND_LOC "不能设置 RI 信息。"
#DEFINE NO_FILE_FOUND_LOC "警告!找不到过程文件!"
#DEFINE GETFILE_GEN_LOC "生成..."
#DEFINE NOT_SUPPORTED_LOC "主索引上的筛选器现在不起作用。" +"注释将被 加入到输出文件中以指明这些筛选器。"
#DEFINE NS_COMMENT_LOC "****** 这些筛选器必须人工添加 ******"
#DEFINE WARNING_TITLE_LOC "GenDBC 警告..."
********************************************************************** ****
** Comments And Other Information
********************************************************************** ****
#DEFINE MESSAGE_START_LOC "正在创建数据库..."
#DEFINE MESSAGE_DONE_LOC "已完成。"
#DEFINE MESSAGE_MAKETABLE_LOC "正在创建表 "
#DEFINE MESSAGE_MAKEVIEW_LOC "正在创建视图 "
#DEFINE MESSAGE_MAKECONN_LOC "正在创建连接 "
#DEFINE MESSAGE_MAKERELATION_LOC "正在创建永久关系..."
#DEFINE MESSAGE_MAKERI_LOC "正在创建关系完整性规则..."
#DEFINE MESSAGE_END_LOC "..."
#DEFINE BEGIN_RELATION_LOC "*************** 开始关系设置 ************ **"
#DEFINE BEGIN_TABLE_LOC "建立表为"
#DEFINE BEGIN_INDEX_LOC "创建每一索引为 "
#DEFINE BEGIN_PROP_LOC "改变属性为 "
#DEFINE BEGIN_VIEW_LOC "建立视图为"
#DEFINE BEGIN_PROC_LOC "重新创建过程"
#DEFINE BEGIN_CONNECTIONS_LOC "连接定义"
#DEFINE BEGIN_RI_LOC "建立参照完整性"
#DEFINE OPEN_DATABASE_LOC "选择数据库..."
#DEFINE SAVE_PRG_NAME_LOC "输出程序名..."
#DEFINE NO_MODIFY_LOC "*** 警告 *** 请不要对此文件做任何修改 *** 警告 ***"
#DEFINE TABLE_NAME_LOC "* 表名: "
#DEFINE PRIMARY_KEY_LOC "* 主关键字: "
#DEFINE FILTER_EXP_LOC "* 筛选表达式: "
#DEFINE HEADING_1_LOC "* ********************************************* ************" + CRLF +"* *" + CRLF
#DEFINE HEADING_2_LOC "* *" + CRLF +"* ******************************* **************************" + CRLF + "* *" + CRLF + "* * 说明 :" + CRLF + "* * 此程序是 GENDBC 自动生成的" + CRLF + "* * Version 2 .26.67" + CRLF + "* *" + CRLF + "* ************************* ********************************" + CRLF
*! 确定必有一个数据库打开
IF EMPTY(DBC())
m.g_cFullDatabase = GETFILE("DBC", OPEN_DATABASE_LOC, GETFILE_GEN_LOC , 0)
IF EMPTY(m.g_cFullDatabase)
FatalAlert(NO_DATABASE_IN_USE_LOC, .F.)
ENDIF
OPEN DATABASE (m.g_cFullDatabase)
ENDIF
*! 数据库名称的全路径 (全局变量)
m.g_cFullDatabase = DBC()
*! 全局变量来存放数据库名称(不含路径)
IF RAT("\", m.g_cFullDatabase) > 0
m.g_cDatabase = SUBSTR(m.g_cFullDatabase, RAT("\", m.g_cFullDatabase) + 1)
ENDIF
*! 检测参数合法性
IF PARAMETERS() < 1 OR TYPE("cOutFile")#"C" OR EMPTY(cOutFile)
m.cOutFile = ""
m.cOutFile = PUTFILE(SAVE_PRG_NAME_LOC, (SUBSTR(m.g_cDatabase, 1, RAT (".", m.g_cDatabase)) + "PRG"), "PRG")
IF EMPTY(cOutFile)
FatalAlert(INVALID_PARAMETERS_LOC, .F.)
ENDIF
ENDIF
*! 检测合适的扩展名或加一个.PRG扩展名
IF RAT(".PRG", m.cOutFile) = 0 AND RAT(".", m.cOutFile) = 0
m.cOutFile = m.cOutFile + ".PRG"
ENDIF
*! 确定能够创建输出文件
m.hFile = FCREATE(m.cOutFile)
IF m.hFile <= 0
FatalAlert(INVALID_DESTINATION_LOC + m.cOutFile, .F.)
ENDIF
FCLOSE(m.hFile)
ERASE (m.cOutFile)
*!记录所有属于该数据库容器内的表的数量,及表名及其表的大小
*!Aused(array,workalia)返回指定工作中的表名称信息存入array数组中
m.g_nTotal_Tables_Used = AUSED(g_aAlias_Used)
IF m.g_nTotal_Tables_Used > 0
DIMENSION m.g_aTables_Used(m.g_nTotal_Tables_Used)
*! 记录打开表的真实名称
FOR m.nLoop = 1 TO m.g_nTotal_Tables_Used
g_aTables_Used(m.nLoop) = DBF(g_aAlias_Used(m.nLoop, 1))
ENDFOR
ENDIF
*! 得到数据库中包含的表的数量,表信息存入aAll_Tables数组中
*! ADBOBJETCS(array,'Table'),array(1)..array(n)中是表的名称如 'emplo ye'
m.nTotal_Tables = ADBOBJECTS(aAll_Tables, "Table")
m.g_nMax = m.g_nMax + m.nTotal_Tables
Stat_Message() && 状态行信息显示
*! 得到数据库中包含的视图数量
m.nTotal_Views = ADBOBJECTS(aAll_Views, "View")
m.g_nMax = m.g_nMax + m.nTotal_Views
Stat_Message() && 状态行信息显示
*! 得到数据库中包含的连接数量
m.nTotal_Connections = ADBOBJECTS(aAll_Connections, "Connection")
m.g_nMax = m.g_nMax + m.nTotal_Connections
Stat_Message() && 状态行信息显示
*! 得到数据库中包含的关联数量
m.nTotal_Relations = ADBOBJECTS(aAll_Relations, "Relation")
m.g_nMax = m.g_nMax + m.nTotal_Relations
Stat_Message() && 状态行信息显示
CLOSE DATABASE
SELECT 0
IF FILE("GENDBC.DBF")
ERASE "GENDBC.DBF"
ERASE "GENDBC.FPT"
ENDIF
CREATE TABLE GenDBC (Program M)
&& 创建一个文件GENDBC内有MEMO字段PROGRAM,生成自动程序用
APPEND BLANK
USE
**************************
*** 得到贮存过程
**************************
*! 建立一个输出文件m.cFile 存放贮存过程.
m.cFile = UPPER(SUBSTR(m.cOutFile, 1, RAT(".", m.cOutFile))) + "krt"
*! 把头文件信息写入.KRT存贮在过程文件开头
m.hFile = FCREATE(m.cFile)
IF m.hFile <= 0
FCLOSE(m.hFile)
FatalAlert(NO_OUTPUT_WRITTEN_LOC, .T.)
ENDIF
FPUTS(m.hFile, NO_MODIFY_LOC)
** 写入' *** 警告 *** 请不要对此文件做任何修改 *** 警告 ***'
FCLOSE(m.hFile)
*! No we are going to copy the object and source code
*! For the stored procedures把过程文件存入*.KRT文件中
COMPILE DATABASE (m.g_cFullDatabase)
USE (m.g_cFullDatabase)
LOCATE FOR Objectname = 'StoredProceduresSource'
IF FOUND()
COPY MEMO Code TO (m.cFile) ADDITIVE
ENDIF
ADIR(aTemp, m.cFile) && 取得过程贮存文件的大小为主要目的!
m.nSourceSize = aTemp(1, 2) - LEN(NO_MODIFY_LOC) && aTemp(1,2)内有文件 大小
LOCATE FOR Objectname = 'StoredProceduresObject'
IF FOUND()
COPY MEMO Code TO (m.cFile) ADDITIVE
ENDIF
USE
*! 独占打开数据库
OPEN DATABASE (m.g_cFullDatabase) EXCLUSIVE
ADIR(aTemp, m.cFile)
*! 检测过程存贮文件是否真的有内容,如果有就生成相应的贮存过程的恢复代码
IF aTemp(1, 2) > LEN(NO_MODIFY_LOC) + 2
*********************
*** 重新创建过程
*********************
m.hOutFile = FCREATE("GenDBC.$$$")
IF m.hOutFile <= 0
= FCLOSE(m.hFile)
= FatalAlert(NO_OUTPUT_WRITTEN_LOC, .T.)
ENDIF
WriteFile(m.hOutFile, "")
WriteFile(m.hOutFile, "********* " + BEGIN_PROC_LOC + " *********")
WriteFile(m.hOutFile, "IF !FILE([" + SUBSTR(m.cFile, RAT("\", m.cFile ) + 1) + "])")
WriteFile(m.hOutFile, " ? [" + NO_FILE_FOUND_LOC + "]")
WriteFile(m.hOutFile, "ELSE")
WriteFile(m.hOutFile, " CLOSE DATABASE")
WriteFile(m.hOutFile, " USE '" + m.g_cFullDatabase + "'") && 改成 全路径
WriteFile(m.hOutFile, " g_SetSafety = SET('SAFETY')")
WriteFile(m.hOutFile, " SET SAFETY OFF")
WriteFile(m.hOutFile, " LOCATE FOR Objectname = 'StoredProceduresSour ce'")
WriteFile(m.hOutFile, " IF FOUND()")
WriteFile(m.hOutFile, " APPEND MEMO Code FROM [" + SUBSTR(m.cFi le, RAT("\", m.cFile) + 1) + "] OVERWRITE")
WriteFile(m.hOutFile, " REPLACE Code WITH SUBSTR(Code, " + ALLTRIM (STR(LEN(NO_MODIFY_LOC) + 3)) + ", " + ALLTRIM(STR(m.nSourceSize - 2)) + ")")
WriteFile(m.hOutFile, " ENDIF")
WriteFile(m.hOutFile, " LOCATE FOR Objectname = 'StoredProceduresObje ct'")
WriteFile(m.hOutFile, " IF FOUND()")
WriteFile(m.hOutFile, " APPEND MEMO Code FROM [" + SUBSTR(m.cFi le, RAT("\", m.cFile) + 1) + "] OVERWRITE")
WriteFile(m.hOutFile, " REPLACE Code WITH SUBSTR(Code, " + ALLTRIM (STR(LEN(NO_MODIFY_LOC) + m.nSourceSize + 1)) + ")")
WriteFile(m.hOutFile, " ENDIF")
WriteFile(m.hOutFile, " SET SAFETY &g_SetSafety")
WriteFile(m.hOutFile, " USE")
WriteFile(m.hOutFile, " OPEN DATABASE [" + m.g_cFullDatabase + "]") && 改成全路径
WriteFile(m.hOutFile, "ENDIF")
WriteFile(m.hOutFile, "")
FCLOSE(m.hOutFile)
********* 重新创建过程 的代码生成(写在文件 GENDBC.$$$中)完成******* **
USE GenDBC EXCLUSIVE && 追加到GENDBC.DBF的MEMO字段中(GENDBC.FPT文件 内)
APPEND MEMO Program FROM "GENDBC.$$$"
ERASE "GENDBC.$$$"
USE
ELSE
ERASE (m.cFile)
ENDIF
Stat_Message()
* Write out database creation routines
* UpdateProcArray("ON ERROR DO error1562")
UpdateProcArray("DisplayStatus(["+MESSAGE_START_LOC+"])")
UpdateProcArray("CLOSE DATA ALL")
UpdateProcArray("CREATE DATABASE '" + m.g_cFullDatabase + "'")
**************************
*** Get Tables
**************************
IF m.nTotal_Tables > 0
FOR m.nLoop = 1 TO m.nTotal_Tables
DO GetTable WITH ALLTRIM(aAll_Tables(m.nLoop)), "GenDBC.tmp"
Stat_Message()
USE GenDBC EXCLUSIVE
APPEND MEMO Program FROM "GenDBC.tmp"
USE
ERASE "GenDBC.tmp"
UpdateProcArray("DisplayStatus(["+MESSAGE_MAKETABLE_LOC+aAll_Tables( m.nLoop)+MESSAGE_END_LOC+"])")
UpdateProcArray("MakeTable_"+FixName(aAll_Tables(m.nLoop))+"()")
ENDFOR
ENDIF
**************************
*** Get Connections
**************************
IF m.nTotal_Connections > 0
FOR m.nLoop = 1 TO m.nTotal_Connections
DO GetConn WITH aAll_Connections(m.nLoop), "GenDBC.tmp"
Stat_Message()
USE GenDBC EXCLUSIVE
APPEND MEMO Program FROM "GenDBC.tmp"
USE
ERASE "GenDBC.tmp"
UpdateProcArray("DisplayStatus(["+MESSAGE_MAKECONN_LOC+aAll_Connecti ons(m.nLoop)+MESSAGE_END_LOC+"])")
UpdateProcArray("MakeConn_"+FIXNAME(aAll_Connections(m.nLoop))+"()")
ENDFOR
ENDIF
**************************
*** Get Views
**************************
IF m.nTotal_Views > 0
FOR m.nLoop = 1 TO m.nTotal_Views
DO GetView WITH ALLTRIM(aAll_Views(m.nLoop)), "GenDBC.tmp"
Stat_Message()
USE GenDBC EXCLUSIVE
APPEND MEMO Program FROM "GenDBC.tmp"
USE
ERASE "GenDBC.tmp"
UpdateProcArray("DisplayStatus(["+MESSAGE_MAKEVIEW_LOC+aAll_Views(m. nLoop)+MESSAGE_END_LOC+"])")
UpdateProcArray("MakeView_"+FIXNAME(aAll_Views(m.nLoop))+"()")
ENDFOR
ENDIF
**************************
*** Get Relations
**************************
IF m.nTotal_Relations > 0
USE GenDBC EXCLUSIVE
REPLACE Program WITH BEGIN_RELATION_LOC + CRLF ADDITIVE
UpdateProcArray("DisplayStatus(["+MESSAGE_MAKERELATION_LOC+"])")
FOR m.nLoop = 1 TO m.nTotal_Relations
REPLACE Program WITH CRLF + "FUNCTION MakeRelation_"+TRANS(m.nLoop)+ CRLF+;
"ALTER TABLE '" + aAll_Relations(m.nLoop, 1) +;
"' ADD FOREIGN KEY TAG " +;
aAll_Relations(m.nLoop, 3) +;
" REFERENCES " + ;
aAll_Relations(m.nLoop, 2) +;
" TAG " + aAll_Relations(m.nLoop, 4) + ;
CRLF +"ENDFUNC"+CRLF+CRLF ADDITIVE
UpdateProcArray("MakeRelation_"+TRANS(m.nLoop)+"()")
Stat_Message()
ENDFOR
ENDIF
CLOSE DATABASE && Because we're going to start peeking into the
&& table structure of the DBC
**************************
*** Get RI Info
**************************
IF m.nTotal_Relations > 0
DO GetRI WITH "GenDBC.tmp"
IF FILE("GenDBC.tmp")
USE GenDBC EXCLUSIVE
APPEND MEMO Program FROM "GenDBC.tmp"
USE
ERASE "GenDBC.tmp"
UpdateProcArray("DisplayStatus(["+MESSAGE_MAKERI_LOC+"])")
UpdateProcArray("MakeRI()")
ENDIF
ENDIF
UpdateProcArray("DisplayStatus(["+MESSAGE_DONE_LOC+"])")
Stat_Message()
*! Make it a permanent file
USE GenDBC EXCLUSIVE
lcprocstr = ""
FOR i = 1 TO ALEN(g_aprocs)
lcprocstr = lcprocstr + g_aprocs[m.i] + CRLF
ENDFOR
lcMessageStr = "FUNCTION DisplayStatus(lcMessage)"+CRLF+;
"WAIT WINDOW NOWAIT lcMessage"+CRLF+;
"ENDFUNC"
REPLACE Program WITH HEADING_1_LOC + "* * " + DTOC(DATE()) +;
SPACE(19 - LEN(m.g_cDatabase) / 2) + ;
m.g_cDatabase + SPACE(19 - LEN(m.g_cDatabase) / 2) +;
TIME() + CRLF + HEADING_2_LOC + CRLF + ;
IIF(!EMPTY(m.g_cFilterExp), NS_COMMENT_LOC + m.g_cFilterExp + ;
CRLF + REPLICATE("*", 52) + CRLF, "") + ;
CRLF + lcprocstr + CRLF + Program +;
CRLF + lcMessageStr
COPY MEMO Program TO (m.cOutFile)
USE
ERASE "GenDBC.DBF"
ERASE "GenDBC.FPT"
Stat_Message()
*! Exit Program
COMPILE (m.cOutFile) && 能不生成.EXE文件?
GenDBC_CleanUp(.T.)
*********************** END OF PROGRAM ***********************
********************************************************************** ****
**
** Function Name: GETRI(<ExpC>)
** Purpose: To take existing FoxPro 3.0/5.0 RI Infomration, and genera te an output
** program that can be used to "re-create" this.
**
** Parameters:
**
** cOutFileName - A character string containing the name of the
** output file
**
** Modification History:
********************************************************************** ****
PROCEDURE GetRI
LPARAMETERS m.cOutFileName
PRIVATE ALL EXCEPT g_*
*! Create the output file
m.hGTFile = FCREATE(m.cOutFileName)
IF m.hGTFile < 1
FatalAlert(NO_TEMP_FILE_LOC + m.cOutFileName, .T.)
ENDIF
*! USE the database
USE (m.g_cFullDatabase) EXCLUSIVE
LOCATE FOR ObjectType = "Relation" AND !EMPTY(RiInfo)
IF FOUND()
WriteFile(m.hGTFile, "FUNCTION MakeRI")
WriteFile(m.hGTFile, "***** " + BEGIN_RI_LOC + " *****")
WriteFile(m.hGTFile, "CLOSE DATABASE")
WriteFile(m.hGTFile, "USE '" + m.g_cDatabase + "'")
DO WHILE FOUND()
*! Have to get the parent name to verify we are adding
*! Information to the right record.
m.nParentID = ParentID
*! We use select so we won't mess up our LOCATE ... CONTINUE comman d
SELECT ObjectName FROM (m.g_cFullDatabase) WHERE ObjectID = nParent ID INTO ARRAY aTableName
m.nStart = 1
m.cITag = ""
m.cTable = ""
m.cRTag = ""
DO WHILE m.nStart <= LEN(Property)
nSize = ASC(SUBSTR(Property, m.nStart, 1)) +;
(ASC(SUBSTR(Property, m.nStart + 1, 1)) * 256) +;
(ASC(SUBSTR(Property, m.nStart + 2, 1)) * 256^2) + ;
(ASC(SUBSTR(Property, m.nStart + 3, 1)) * 256^3)
m.nKey = ASC(SUBSTR(Property, m.nStart + 6, 1))
DO CASE
CASE m.nKey = 13
m.cITag = SUBSTR(Property, m.nStart + 7, m.nSize - 8)
CASE m.nKey = 18
m.cTable = SUBSTR(Property, m.nStart + 7, m.nSize - 8)
CASE m.nKey = 19
m.cRTag = SUBSTR(Property, m.nStart + 7, m.nSize - 8)
ENDCASE
m.nStart = m.nStart + m.nSize
ENDDO
WriteFile(m.hGTFile, "LOCATE FOR ObjectType = 'Table' AND ObjectNam e = '" + ;
ALLTRIM(aTableName(1)) + "'")
WriteFile(m.hGTFile, "IF FOUND()")
WriteFile(m.hGTFile, " nObjectID = ObjectID")
WriteFile(m.hGTFile, " LOCATE FOR ObjectType = 'Relation' AND '" + m.cITag + ;
"'$Property AND '" + m.cTable + "'$Property AND '" + m.cRTag + ;
"'$Property AND ParentID = nObjectID")
WriteFile(m.hGTFile, " IF FOUND()")
WriteFile(m.hGTFile, " REPLACE RiInfo WITH '" + RiInfo + "'")
WriteFile(m.hGTFile, " ELSE")
WriteFile(m.hGTFile, ' ? "' + NO_FIND_LOC + '"')
WriteFile(m.hGTFile, " ENDIF")
WriteFile(m.hGTFile, "ENDIF")
CONTINUE
ENDDO
WriteFile(m.hGTFile, "USE")
WriteFile(m.hGTFile, "ENDFUNC")
WriteFile(m.hGTFile, "")
FCLOSE(m.hGTFile)
ELSE
FCLOSE(m.hGTFile)
ERASE (m.cOutFileName)
ENDIF
USE
RETURN
********************************************************************** ****
**
** Function Name: GETTABLE(<ExpC>, <ExpC>)
** Purpose : To take an existing FoxPro 6.0 Table, and generate an output
** program that can be used to "re-create" that Table.
**
** Parameters:
** cTableName - A character string representing the name of th e
** existing Table
** cOutFileName - A character string containing the name of the
** output file
********************************************************************** ****
PROCEDURE GetTable
LPARAMETERS m.cTableName, m.cOutFileName
PRIVATE ALL EXCEPT g_*
*! Create the output file
m.hGTFile = FCREATE(m.cOutFileName)
IF m.hGTFile < 1
FatalAlert(NO_TEMP_FILE_LOC + m.cOutFileName, .T.)
ENDIF
*! Open Table to get field info
USE (m.cTableName) EXCLUSIVE
*! NOTE * NOTE * NOTE
*! If the table is greater than 8 characters then it will fail on pla tforms that
*! do not support this (Such as Win32s).
m.cOldSetFullPath = SET("FULLPATH")
m.cFullTableFileName = DBF(ALIAS())
SET FULLPATH OFF
m.cTableFileName = DBF(ALIAS())
SET FULLPATH &cOldSetFullPath
*! Get all the fields
m.nNumberOfFields = AFIELDS(aAll_Fields)
*! 判断有没有MEMO或GENERAL字段
m.m_g=.F. && MEMO或General字段没有=.F.
for m.nInner_Loop= 1 to m.nNumberOfFields
if aAll_Fields(m.nInner_Loop, 2) == "M" OR ;
aAll_Fields(m.nInner_Loop, 2) == "G"
m.m_g=.T.
exit
endif
endfor
*! Header Information
WriteFile(m.hGTFile, "FUNCTION MakeTable_"+FIXNAME(m.cTableName))
WriteFile(m.hGTFile, "**" + BEGIN_TABLE_LOC + m.cTableName + " -将变为 自由表的表备份一份by YC 1999.8.1**")
if m.m_g
writeFile(m.hGTFile,"IF FILE("+"'"+m.cFullTableFileName+"') and ;")
writeFile(m.hGTFile," FILE('"+left(m.cFullTableFileName,RAT('. ',m.cFullTableFileName))+"FPT')")
writeFile(m.hGTFile," COPY FILE "+m.cFullTableFileName+" TO .\ tmpdbf.dbf")
writeFile(m.hGTFile," COPY FILE "+left(m.cFullTableFileName,RA T('.',m.cFullTableFileName));
+"FPT TO .\tmpdbf.fpt")
else
writeFile(m.hGTFile,"IF FILE("+"'"+m.cFullTableFileName+"')" )
writeFile(m.hGTFile," COPY FILE "+m.cFullTableFileName+" TO .\ tmpdbf.dbf")
endif
writeFile(m.hGTFile, "ENDIF ")
writeFile(m.hGTFile,"** Added by YUCE 1999.8.1 Restore the old dat as **")
m.cTableFileName = SUBSTR(m.cTableFileName, RAT(":", m.cTableFileName ) + 1)
m.cCreateTable = "CREATE TABLE '" + m.cFullTableFileName + "' NAME '" + m.cTableName + "' ("
*! Information about each field that can been written with CREATE TAB LE - SQL
FOR m.nInner_Loop = 1 TO m.nNumberOfFields
IF m.nInner_Loop = 1
m.cCreateTable = m.cCreateTable + aAll_Fields(m.nInner_Loop, 1) + " "
ELSE
m.cCreateTable = SPACE(LEN(m.cTableName) + 15) + ;
aAll_Fields(m.nInner_Loop, 1) + " "
ENDIF
m.cCreateTable = m.cCreateTable + aAll_Fields(m.nInner_Loop, 2)
DO CASE
CASE aAll_Fields(m.nInner_Loop, 2) == "C"
m.cCreateTable = m.cCreateTable + "(" + ;
ALLTRIM(STR(aAll_Fields(m.nInner_Loop, 3))) + ")"
IF aAll_Fields(m.nInner_Loop, 6)
m.cCreateTable = m.cCreateTable + " NOCPTRANS"
ENDIF
CASE aAll_Fields(m.nInner_Loop, 2) == "M"
IF aAll_Fields(m.nInner_Loop, 6)
m.cCreateTable = m.cCreateTable + " NOCPTRANS"
ENDIF
CASE aAll_Fields(m.nInner_Loop, 2) == "N" OR ;
aAll_Fields(m.nInner_Loop, 2) == "F"
cCreateTable = m.cCreateTable + "(" + ;
ALLTRIM(STR(aAll_Fields(m.nInner_Loop, 3))) + ;
", " + ALLTRIM(STR(aAll_Fields(m.nInner_Loop, 4))) + ")"
CASE aAll_Fields(m.nInner_Loop, 2) == "B"
m.cCreateTable = m.cCreateTable + "(" + ;
ALLTRIM(STR(aAll_Fields(m.nInner_Loop, 4))) ;
+ ")"
ENDCASE
IF aAll_Fields(m.nInner_Loop, 5)
m.cCreateTable = m.cCreateTable + " NULL"
ELSE
m.cCreateTable = m.cCreateTable + " NOT NULL"
ENDIF
*! Get properties for fields
IF !EMPTY(aAll_Fields(m.nInner_Loop, 7))
m.cCreateTable = m.cCreateTable + " CHECK " + aAll_Fields(m.nInner_ Loop, 7)
ENDIF
IF !EMPTY(aAll_Fields(m.nInner_Loop, 8))
m.cCreateTable = m.cCreateTable + " ERROR " + aAll_Fields(m.nInner_ Loop, 8)
ENDIF
IF !EMPTY(aAll_Fields(m.nInner_Loop, 9))
m.cCreateTable = m.cCreateTable + " DEFAULT " + aAll_Fields(m.nInne r_Loop, 9)
ENDIF
IF m.nInner_Loop <> m.nNumberOfFields
m.cCreateTable = m.cCreateTable + ", ;"
ELSE
m.cCreateTable = m.cCreateTable + ")"
ENDIF
WriteFile(m.hGTFile, m.cCreateTable)
ENDFOR
writeFile(m.hGTFile,"***** 原数据追加到新创建的表中 added by YUCE ****")
writeFile(m.hGTFile,"IF FILE('.\tmpdbf.dbf')")
writeFile(m.hGTFile," APPE FROM .\tmpdbf " )
writeFile(m.hGTFile," ERASE .\tmpdbf.* ")
writeFile(m.hGTFile,"ENDIF")
*! Get Index Information
WriteFile(m.hGTFile, CRLF + "***** " + BEGIN_INDEX_LOC + m.cTableName + " *****")
m.cCollate = ""
FOR m.nInner_Loop = 1 TO TAGCOUNT()
m.cTag = UPPER(ALLTRIM(TAG(m.nInner_Loop)))
IF m.cCollate <> IDXCOLLATE(m.nInner_Loop)
m.cCollate = IDXCOLLATE(m.nInner_Loop)
WriteFile(m.hGTFile, "SET COLLATE TO '" + m.cCollate + "'")
ENDIF
IF !EMPTY(m.cTag)
DO CASE
CASE PRIMARY(m.nInner_Loop)
IF !EMPTY(SYS(2021, m.nInner_Loop))
IF EMPTY(m.g_cFilterExp)
MessageBox(NOT_SUPPORTED_LOC, 64, WARNING_TITLE_LOC)
ENDIF
m.g_cFilterExp = m.g_cFilterExp + CRLF + ;
TABLE_NAME_LOC + m.cTableName + CRLF + ;
PRIMARY_KEY_LOC + SYS(14, m.nInner_Loop) + CRLF + ;
FILTER_EXP_LOC + SYS(2021, m.nInner_Loop)
ENDIF
WriteFile(m.hGTFile, "ALTER TABLE '" + m.cTableNa me + ;
"' ADD PRIMARY KEY " + SYS(14, m.nIn ner_Loop) ;
+ " TAG " + m.cTag)
CASE CANDIDATE(m.nInner_Loop)
IF EMPTY(SYS(2021, m.nInner_Loop))
WriteFile(m.hGTFile, "INDEX ON " + SYS(14, m.nInner_Loop) + ;
" TAG " + m.cTag + " CANDIDATE")
ELSE
WriteFile(m.hGTFile, "INDEX ON " + SYS(14, m.nInner_Loop) + ;
" TAG " + m.cTag + " FOR " + SYS(2021, m.nInner_Loop) + ;
+ " CANDIDATE")
ENDIF
CASE UNIQUE(m.nInner_Loop)
IF(EMPTY(SYS(2021, m.nInner_Loop)))
WriteFile(m.hGTFile, "INDEX ON " + SYS(14, m.nInner_Loop) + ;
" TAG " + m.cTag + " UNIQUE")
ELSE
WriteFile(m.hGTFile, "INDEX ON " + SYS(14, m.nInner_Loop);
+ " TAG " + m.cTag + " FOR " + SYS (2021, m.nInner_Loop) ;
+ " UNIQUE")
ENDIF
OTHERWISE
IF(EMPTY(SYS(2021, m.nInner_Loop)))
WriteFile(m.hGTFile, "INDEX ON " + SYS(14, m.nInner_Loop) + ;
" TAG " + m.cTag + ;
IIF(DESCENDING(m.nInner_Loop), " DESCENDING ", ""))
ELSE
WriteFile(m.hGTFile, "INDEX ON " + SYS(14, m.nInner_Loop);
+ " TAG " + m.cTag + " FOR " + SYS(2021, m.nInner_Loop) + ;
IIF(DESCENDING(m.nInner_Loop), " DESCENDING ", ""))
ENDIF
ENDCASE
ELSE
EXIT FOR
ENDIF
ENDFOR
*! Get Properties For Table
WriteFile(hGTFile, CRLF + "***** " + BEGIN_PROP_LOC + m.cTableName + " *****")
FOR m.nInner_Loop = 1 TO m.nNumberOfFields
m.cFieldAlias = m.cTableName + "." + aAll_Fields(m.nInner_Loop, 1)
m.cFieldHeaderAlias = [DBSETPROP('] + m.cFieldAlias + [', 'Field', ]
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "Caption")
IF !EMPTY(cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
WriteFile(hGTFile, m.cFieldHeaderAlias + ['Caption', "] + m.cTemp + [")])
ENDIF
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "Comment")
IF !EMPTY(m.cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
*! Strip Line Feeds
m.cTemp = STRTRAN(m.cTemp, CHR(10))
*! Convert Carriage Returns To Programmatic Carriage Returns
m.cTemp = STRTRAN(m.cTemp, CHR(13), '" + CHR(13) + "')
WriteFile(m.hGTFile, m.cFieldHeaderAlias + ['Comment', "] + m.cTemp + [")])
ENDIF
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "InputMask")
IF !EMPTY(m.cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
WriteFile(m.hGTFile, m.cFieldHeaderAlias + ['InputMask', "] + m.cTe mp + [")])
ENDIF
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "Format")
IF !EMPTY(m.cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
WriteFile(m.hGTFile, m.cFieldHeaderAlias + ['Format', "] + m.cTemp + [")])
ENDIF
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "DisplayClass")
IF !EMPTY(m.cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
WriteFile(m.hGTFile, m.cFieldHeaderAlias + ['DisplayClass', "] + m. cTemp + [")])
ENDIF
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "DisplayClassLibrary")
IF !EMPTY(m.cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
WriteFile(m.hGTFile, m.cFieldHeaderAlias + ['DisplayClassLibrary', "] + m.cTemp + [")])
ENDIF
ENDFOR
m.cTemp = DBGETPROP(m.cTableName, "Table", "Comment")
IF !EMPTY(m.cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
*! Strip Line Feeds
m.cTemp = STRTRAN(m.cTemp, CHR(10))
*! Convert Carriage Returns To Programmatic Carriage R eturns
m.cTemp = STRTRAN(m.cTemp, CHR(13), '" + CHR(13) + "')
WriteFile(m.hGTFile, [DBSETPROP('] + m.cTableName + [', 'Table', ] + ['Comment', "] + m.cTemp + [")])
ENDIF
m.cTemp = DBGETPROP(m.cTableName, "Table", "DeleteTrigger")
IF !EMPTY(m.cTemp)
WriteFile(hGTFile, "CREATE TRIGGER ON '" + m.cTableName + ;
"' FOR DELETE AS " + m.cTemp)
ENDIF
m.cTemp = DBGETPROP(m.cTableName, "Table", "InsertTrigger")
IF !EMPTY(m.cTemp)
WriteFile(m.hGTFile, "CREATE TRIGGER ON '" + m.cTableName + ;
"' FOR INSERT AS " + m.cTemp)
ENDIF
m.cTemp = DBGETPROP(m.cTableName, "Table", "UpdateTrigger")
IF !EMPTY(m.cTemp)
WriteFile(m.hGTFile, "CREATE TRIGGER ON '" + m.cTableName + ;
"' FOR UPDATE AS " + m.cTemp)
ENDIF
m.cTemp = DBGETPROP(m.cTableName, "Table", "RuleExpression")
IF !EMPTY(m.cTemp)
m.cError = DBGETPROP(m.cTableName, "Table", "RuleText")
IF !EMPTY(cError)
WriteFile(m.hGTFile, "ALTER TABLE '" + m.cTableName + ;
"' SET CHECK " + m.cTemp + " ERROR " + ;
m.cError)
ELSE
WriteFile(m.hGTFile, "ALTER TABLE '" + m.cTableName + ;
"' SET CHECK " + m.cTemp)
ENDIF
ENDIF
WriteFile(m.hGTFile, "ENDFUNC")
WriteFile(m.hGTFile, "")
FCLOSE(m.hGTFile)
RETURN
********************************************************************** ****
**
** Function Name: GETVIEW(<ExpC>, <ExpC>)
** Purpose : To take an existing FoxPro 3.0/5.0 View, and generat e an output
** program that can be used to "re-create" that view.
**
** Parameters:
**
** cViewName - A character string representing the name of th e
** existing view
** cOutFileName - A character string containing the name of the
** output file
********************************************************************** *****************
PROCEDURE GetView
LPARAMETERS cViewName, cOutFileName
PRIVATE ALL EXCEPT g_*
m.nFileHand = FCREATE(m.cOutFileName, 0)
IF m.nFileHand < 1
FatalAlert(NO_TEMP_FILE_LOC + m.cOutFileName, .T.)
ENDIF
*! Get View Information for later use
m.nSourceType = DBGetProp(m.cViewName, 'View', 'SourceType')
m.cConnectName = ALLTRIM(DBGetProp(m.cViewName, 'View', 'ConnectName' ))
m.cSQL = ALLTRIM(DBGetProp(m.cViewName, 'View', 'SQL'))
m.cnUpdateType = ALLTRIM(STR(DBGetProp(m.cViewName, 'View', 'UpdateTy pe')))
m.cnWhereType = ALLTRIM(STR(DBGetProp(m.cViewName, 'View', 'WhereType ')))
m.clFetchMemo = IIF(DBGetProp(m.cViewName, 'View', 'Fetchmemo'),'.T.' ,'.F.')
m.clShareConnection = IIF(DBGetProp(m.cViewName, 'View', 'ShareConnec tion'),'.T.','.F.')
m.clSendUpdates = IIF(DBGetProp(m.cViewName, 'View', 'SendUpdates'),' .T.','.F.')
m.cnUseMemoSize = ALLTRIM(STR(DBGetProp(m.cViewName, 'View', 'UseMemo Size')))
m.cnFetchSize = ALLTRIM(STR(DBGetProp(m.cViewName, 'View', 'FetchSize ')))
m.cnMaxRecords = ALLTRIM(STR(DBGetProp(m.cViewName, 'View', 'MaxRecor ds')))
m.ccTables = ALLTRIM(DBGetProp(m.cViewName, 'View', 'Tables'))
m.clPrepared = IIF(!EMPTY(DBGetProp(m.cViewName, 'View', 'Prepared')) , '.T.', '.F.')
m.clCompareMemo = IIF(!EMPTY(DBGetProp(m.cViewName, 'View', 'CompareM emo')), '.T.', '.F.')
m.clFetchAsNeeded = IIF(!EMPTY(DBGetProp(m.cViewName, 'View', 'FetchA sNeeded')), '.T.', '.F.')
m.cParams = ALLTRIM(DBGetProp(m.cViewName, 'View', 'ParameterList'))
m.lOffline = DBGetProp(m.cViewName, 'View', 'Offline')
m.cComment = DBGETPROP(m.cViewName, 'View', 'Comment')
IF !EMPTY(m.cComment )
m.cComment = STRTRAN(m.cComment , ["], ['])
*! Strip Line Feeds
m.cComment = STRTRAN(m.cComment , CHR(10))
*! Convert Carriage Returns To Programmatic Carriage Returns
m.cComment = STRTRAN(m.cComment , CHR(13), '" + CHR(13) + "')
ENDIF
m.cnBatchUpdateCount = ALLTRIM(STR(DBGetProp(m.cViewName, 'View', 'Ba tchUpdateCount')))
*! Generate Comment Block
WriteFile(m.nFileHand, "FUNCTION MakeView_"+FIXNAME(m.cViewName))
m.cCommentBlock = "***************** " + BEGIN_VIEW_LOC + m.cViewName + ;
" ***************" + CRLF
WriteFile(m.nFileHand, m.cCommentBlock)
*! Generate CREATE VIEW command
m.cCreateString = 'CREATE SQL VIEW "'+ALLTRIM(m.cViewName)+'" ; '+CRL F
IF m.nSourceType != 1 && If it isn't a local view
m.cCreateString = m.cCreateString + ' REMOTE '
IF !EMPTY(m.cConnectName)
m.cCreateString = m.cCreateString + 'CONNECT "' + m.cConnectName + '" ; '+CRLF
ENDIF
ENDIF
m.cCreateString = m.cCreateString + ' AS '+ m.cSQL + CRLF
WriteFile(m.nFileHand, m.cCreateString)
*! GENERATE code to Set View Level Properties
m.cViewDBSetPrefix = [DBSetProp(']+m.cViewName+[', 'View', ]
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['UpdateType', ] + m.cnUp dateType + [)])
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['WhereType', ] + m.cnWhe reType + [)])
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['FetchMemo', ] + m.clFet chMemo + [)])
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['SendUpdates', ] + m.clS endUpdates + [)])
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['UseMemoSize', ] + m.cnU seMemoSize + [)])
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['FetchSize', ] + m.cnFet chSize + [)])
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['MaxRecords', ] + m.cnMa xRecords + [)])
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['Tables', '] + m.ccTable s + [')])
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['Prepared', ] + m.clPrep ared + [)])
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['CompareMemo', ] + m.clC ompareMemo + [)])
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['FetchAsNeeded', ] + m.c lFetchAsNeeded + [)])
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['FetchSize', ] + m.cnFet chSize + [)])
IF !EMPTY(m.cParams)
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['ParameterList', "] + m .cParams + [")])
ENDIF
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['Comment', "] + m.cComm ent + [")])
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['BatchUpdateCount', ] + m.cnBatchUpdateCount + [)])
WriteFile(m.nFileHand, m.cViewDBSetPrefix + ['ShareConnection', ] + m .clShareConnection + [)])
IF m.lOffline
WriteFile(m.nFileHand, 'CREATEOFFLINE("' + m.cViewName + '")')
ENDIF
*! GENERATE code to Set Field Level Properties
USE (DBC()) AGAIN IN 0 ALIAS GenViewCursor EXCLUSIVE
SELECT GenViewCursor
LOCATE FOR ALLTRIM(UPPER(GenViewCursor.ObjectName)) == m.cViewName AN D ;
GenViewCursor.ObjectType = 'View'
m.nObjectId = GenViewCursor.ObjectId
SELECT ObjectName FROM GenViewCursor ;
WHERE GenViewCursor.ParentId = m.nObjectId ;
INTO ARRAY aViewFields
USE in GenViewCursor
WriteFile(m.nFileHand, CRLF + '*!* Field Level Properties for ' + m.c ViewName)
IF _TALLY # 0
FOR m.nLoop = 1 TO ALEN(aViewFields, 1)
m.cFieldAlias = m.cViewName + "." + ALLTRIM(aViewFields(nLoop, 1))
m.clKeyField = IIF(DBGetProp(m.cFieldAlias, 'Field', 'KeyField'),'. T.','.F.')
m.clUpdatable = IIF(DBGetProp(m.cFieldAlias, 'Field', 'Updatable'), '.T.','.F.')
m.ccUpdateName = ALLTRIM(DBGetProp(m.cFieldAlias, 'Field', 'UpdateN ame'))
m.cViewFieldSetPrefix = [DBSetProp(']+m.cFieldAlias+[', 'Field', ]
WriteFile(m.nFileHand, '* Props for the '+m.cFieldAlias+' field.')
WriteFile(m.nFileHand, m.cViewFieldSetPrefix + ['KeyField', ] + m.c lKeyField + [)])
WriteFile(m.nFileHand, m.cViewFieldSetPrefix + ['Updatable', ] + m. clUpdatable + [)])
WriteFile(m.nFileHand, m.cViewFieldSetPrefix + ['UpdateName', '] + m.ccUpdateName + [')])
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "RuleExpression")
IF !EMPTY(m.cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
WriteFile(m.nFileHand, m.cViewFieldSetPrefix + ['RuleExpression', "]+m.cTemp+[")])
ENDIF
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "RuleText")
IF !EMPTY(m.cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
WriteFile(m.nFileHand, m.cViewFieldSetPrefix + ['RuleText', "]+m.c Temp+[")])
ENDIF
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "Caption")
IF !EMPTY(m.cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
WriteFile(m.nFileHand, m.cViewFieldSetPrefix + ['Caption', "] + m. cTemp + [")])
ENDIF
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "Comment")
IF !EMPTY(m.cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
*! Strip Line Feeds
m.cTemp = STRTRAN(m.cTemp, CHR(10))
*! Convert Carriage Returns To Programmatic Carriage Returns
m.cTemp = STRTRAN(m.cTemp, CHR(13), '" + CHR(13) + "')
WriteFile(m.nFileHand, m.cViewFieldSetPrefix + ['Comment', "] + m. cTemp + [")])
ENDIF
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "InputMask")
IF !EMPTY(m.cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
WriteFile(m.nFileHand, m.cViewFieldSetPrefix + ['InputMask', "] + m.cTemp + [")])
ENDIF
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "Format")
IF !EMPTY(m.cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
WriteFile(m.nFileHand, m.cViewFieldSetPrefix + ['Format', "] + m.c Temp + [")])
ENDIF
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "DisplayClass")
IF !EMPTY(m.cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
WriteFile(m.nFileHand, m.cViewFieldSetPrefix + ['DisplayClass', "] + m.cTemp + [")])
ENDIF
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "DisplayClassLibrary")
IF !EMPTY(m.cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
WriteFile(m.nFileHand, m.cViewFieldSetPrefix + ['DisplayClassLibra ry', "] + m.cTemp + [")])
ENDIF
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "DataType")
IF !EMPTY(m.cTemp)
WriteFile(m.nFileHand, m.cViewFieldSetPrefix + ['DataType', "] + m .cTemp + [")])
ENDIF
m.cTemp = DBGETPROP(m.cFieldAlias, "Field", "DefaultValue")
IF !EMPTY(m.cTemp)
m.cTemp = STRTRAN(m.cTemp, ["], ['])
WriteFile(m.nFileHand, m.cViewFieldSetPrefix + ['DefaultValue', "] + m.cTemp + [")])
ENDIF
ENDFOR
ENDIF
WriteFile(m.nFileHand, "ENDFUNC")
WriteFile(m.nFileHand, " ")
*! Close output file
FCLOSE(m.nFileHand)
RETURN
********************************************************************** ****
**
** Function Name: GETCONN(<ExpC>, <ExpC>)
** Purpose : To take an existing FoxPro 6.0 Connection, and genera te
** an output program that can be used to "re-create" that connection.
**
** Parameters:
**
** cConnectName - A character string representing the name of th e
** existing connection
** m.cOutFileName - A character string containing the name of th e
** output file
**
********************************************************************** *****************
PROCEDURE GetConn
LPARAMETERS cConnectionName, m.cOutFileName
PRIVATE ALL EXCEPT g_*
m.nFileHand = FCREATE(m.cOutFileName, 0)
IF m.nFileHand < 1
FatalAlert(NO_TEMP_FILE_LOC + m.cOutFileName, .T.)
ENDIF
*! Get Connection Information for later use
m.clAsynchronous = IIF(DBGetProp(m.cConnectionName, 'Connection', 'As ynchronous'),'.T.','.F.')
m.clBatchMode = IIF(DBGetProp(m.cConnectionName, 'Connection', 'Batch Mode'),'.T.','.F.')
m.ccComment = ALLTRIM(DBGetProp(m.cConnectionName, 'Connection', 'Com ment'))
m.ccConnectString = ALLTRIM(DBGetProp(m.cConnectionName, 'Connection' , 'ConnectString'))
m.cnConnectTimeOut = ALLTRIM(STR(DBGetProp(m.cConnectionName, 'Connec tion', 'ConnectTimeOut')))
m.ccDataSource = ALLTRIM(DBGetProp(m.cConnectionName, 'Connection', ' DataSource'))
m.cnDispLogin = ALLTRIM(STR(DBGetProp(m.cConnectionName, 'Connection' , 'DispLogin')))
m.clDispWarnings = IIF(DBGetProp(m.cConnectionName, 'Connection', 'Di spWarnings'),'.T.','.F.')
m.cnIdleTimeOut = ALLTRIM(STR(DBGetProp(m.cConnectionName, 'Connectio n', 'IdleTimeOut')))
m.ccPassword = ALLTRIM(DBGetProp(m.cConnectionName, 'Connection', 'Pa ssword'))
m.cnQueryTimeOut = ALLTRIM(STR(DBGetProp(m.cConnectionName, 'Connecti on', 'QueryTimeOut')))
m.cnTransactions = ALLTRIM(STR(DBGetProp(m.cConnectionName, 'Connecti on', 'Transactions')))
m.ccUserId = ALLTRIM(DBGetProp(m.cConnectionName, 'Connection', 'User Id'))
m.cnWaitTime = ALLTRIM(STR(DBGetProp(m.cConnectionName, 'Connection', 'WaitTime')))
m.ccDatabase = DBGetProp(m.cConnectionName, 'Connection', 'Database')
*! Generate Comment Block
m.cCommentBlock = "***************** " + BEGIN_CONNECTIONS_LOC + " " + m.cConnectionName + ;
" ***************" + CRLF
WriteFile(m.nFileHand, "FUNCTION MakeConn_"+FIXNAME(m.cConnectionName ))
WriteFile(m.nFileHand, m.cCommentBlock)
*! Generate CREATE Connection command
m.cCreateString = 'CREATE CONNECTION '+ALLTRIM(m.cConnectionName)+' ; '+CRLF
IF EMPTY(ALLTRIM(m.ccConnectString)) && If connectstring not specifi ed
m.cCreateString = m.cCreateString + ' DATASOURCE "' + ALLT(m.ccDat aSource) + '" ; ' + CRLF
m.cCreateString = m.cCreateString + ' USERID "' + ALLT(m.ccUserId) + '" ; ' + CRLF
m.cCreateString = m.cCreateString + ' PASSWORD "'+ ALLT(m.ccPasswo rd) + '"' + CRLF
ELSE
m.cCreateString = m.cCreateString + ' CONNSTRING "' + ALLT(m.ccCon nectString) + '"'
ENDIF
WriteFile(m.nFileHand, m.cCreateString)
*! GENERATE code to Set Connection Level Properties
m.cConnectionDBSetPrefix = [DBSetProp(']+m.cConnectionName+[', 'Conne ction', ]
m.cConnectionProps = '****' + CRLF
m.cConnectionProps = m.cConnectionProps + m.cConnectionDBSetPrefix + ;
['Asynchronous', ] + m.clAsynchronous + [)]+ CRLF
m.cConnectionProps = m.cConnectionProps + m.cConnectionDBSetPrefix + ;
['BatchMode', ] + m.clBatchMode + [)]+ CRLF
m.cConnectionProps = m.cConnectionProps + m.cConnectionDBSetPrefix + ;
['Comment', '] + m.ccComment + [')]+ CRLF
m.cConnectionProps = m.cConnectionProps + m.cConnectionDBSetPrefix + ;
['DispLogin', ] + m.cnDispLogin + [)]+ CRLF
m.cConnectionProps = m.cConnectionProps + m.cConnectionDBSetPrefix + ;
['ConnectTimeOut', ] + m.cnConnectTimeOut + [)]+ CRLF
m.cConnectionProps = m.cConnectionProps + m.cConnectionDBSetPrefix + ;
['DispWarnings', ] + m.clDispWarnings + [)]+ CRLF
m.cConnectionProps = m.cConnectionProps + m.cConnectionDBSetPrefix + ;
['IdleTimeOut', ] + m.cnIdleTimeOut + [)]+ CRLF
m.cConnectionProps = m.cConnectionProps + m.cConnectionDBSetPrefix + ;
['QueryTimeOut', ] + m.cnQueryTimeOut + [)]+ CRLF
m.cConnectionProps = m.cConnectionProps + m.cConnectionDBSetPrefix + ;
['Transactions', ] + m.cnTransactions + [)]+ CRLF
m.cConnectionProps = m.cConnectionProps + m.cConnectionDBSetPrefix + ;
['Database', '] + m.ccDatabase + [')] + CRLF
WriteFile(m.nFileHand, m.cConnectionProps)
*! Close output file
WriteFile(m.nFileHand, "ENDFUNC")
WriteFile(m.nFileHand, " ")
FCLOSE(m.nFileHand)
RETURN
********************************************************************** ****
**
** Function Name: FATALALERT(<ExpC>)
** Purpose: Place a message box to alert user of a fatal error.
**
** Parameters:
** cAlert_Message - Message to display to user
** lCleanup - If we should try to restore environment
**
********************************************************************** ****
PROCEDURE FatalAlert
LPARAMETERS cAlert_Message, lCleanup
MESSAGEBOX(m.cAlert_Message, 16, ERROR_TITLE_LOC)
GenDBC_CleanUp(m.lCleanup)
CANCEL
RETURN
********************************************************************** ****
**
** Function Name: GenDBC_CleanUp(<ExpL>)
** Purpose: Restore the environment
**
** Parameters:
** lCleanup - If we should try to restore tables open
********************************************************************** ****
PROCEDURE GenDBC_CleanUp
LPARAMETERS lCleanup
*! Restore everything
IF !EMPTY(m.g_cOnError)
ON ERROR &g_cOnError
ELSE
ON ERROR
ENDIF
IF !EMPTY(m.g_cSetTalk)
SET TALK &g_cSetTalk
ENDIF
IF !EMPTY(m.g_cSafety)
SET SAFETY &g_cSafety
ENDIF
IF !EMPTY(m.g_cSetDeleted)
SET DELETED &g_cSetDeleted
ENDIF
IF m.g_cSetStatusBar = "OFF"
SET STATUS BAR OFF
ENDIF
IF !EMPTY(m.g_cStatusText)
SET MESSAGE TO (m.g_cStatusText)
ELSE
SET MESSAGE TO
ENDIF
SET FULLPATH &g_cFullPath
CLOSE ALL
IF m.lCleanUp
IF !EMPTY(m.g_cFullDatabase) AND m.lCleanUp == .T.
OPEN DATABASE (m.g_cFullDatabase) EXCLUSIVE
IF m.g_nTotal_Tables_Used > 0
FOR m.nLoop = 1 TO m.g_nTotal_Tables_Used
IF UPPER(JUSTEXT(m.g_aTables_Used(m.nLoop)))="TMP"
LOOP
ENDIF
USE (m.g_aTables_Used(m.nLoop)) IN (m.g_aAlias_Used(m.nLoop, 2)) EXCLUSIVE;
ALIAS (m.g_aAlias_Used(m.nLoop, 1))
ENDFOR
ENDIF
ENDIF
ENDIF
RETURN
********************************************************************** ****
**
** Function Name: WRITEFILE(<ExpN>, <ExpC>)
** Purpose : Centralized file output routine to check for proper output
**
** Parameters:
** hFileHandle - Handle of output file
** cText - Contents to write to file
********************************************************************** ****
PROCEDURE WriteFile
LPARAMETERS hFileHandle, cText
m.nBytesSent = FPUTS(m.hFileHandle, m.cText)
IF m.nBytesSent < LEN(m.cText)
FatalAlert(NO_OUTPUT_WRITTEN_LOC, .T.)
ENDIF
RETURN
********************************************************************** ****
** Function Name: GenDBC_Error(<expC>, <expN>)
** Parameters:
** cMess - Message to give user
** nLineNo - Line Number Error Occurred
********************************************************************** ****
PROCEDURE GenDBC_Error
LPARAMETERS cMess, nLineNo
FatalAlert(UNRECOVERABLE_LOC + CRLF + m.cMess + CRLF + ;
AT_LINE_LOC + ALLTRIM(STR(m.nLineNo)), .T.)
RETURN
********************************************************************** ****
**
** Function Name: Stat_Message()
** Creation Date: 1994.01.08
** Purpose : Generalized Status Bar Progression
********************************************************************** ****
PROCEDURE Stat_Message
PRIVATE ALL EXCEPT g_*
m.nStat = m.g_nCurrentStat * (160 / g_nMax)
SET MESSAGE TO REPLICATE("|", m.nStat) + " " + ;
ALLTRIM(STR(INT(100 * (m.g_nCurrentStat / m.g_nMax)))) + "%"
m.g_nCurrentStat = m.g_nCurrentStat + 1
RETURN
********************************************************************
**
** Function Name: UpdateProcArray(<ExpC>)
** Creation Date: 1997.10.22
** Purpose : 用程序语句来填充g_aprocs[]数组
**
** Parameters:
**
** cText - 要加到g_aprocs[]数组中的 程序语句
**********************************************************************
PROCEDURE UpdateProcArray(lcProcName)
*! 如传过来的过程名是 'displayStatus',且不需要显示执行进度就返回了
*! 不需要显示执行进度 参数是 g_lskipdisplay=.T.
IF g_lskipdisplay AND ATC("DisplayStatus",lcprocname)#0
RETURN
ENDIF
IF !EMPTY(g_aprocs[ALEN(g_aprocs)])
DIMENSION g_aprocs[ALEN(g_aprocs)+1]
ENDIF
g_aprocs[ALEN(g_aprocs)] = lcProcName
ENDPROC
********************************************************************** ****
**
** Function Name: FixName(<ExpC>)
** Creation Date: 1997.10.22
** Purpose : Fixes procedure name to remove bad chars
**
** Parameters:
**
** cText - Name of procedure to add fix
********************************************************************** ****
PROCEDURE FixName(lcProcName)
lcProcName=ALLTRIM(lcProcName)
IF VERSION(3) $ DBCS_LOC
cbadchars = '/,-=:;!@#$%&*.<>()?[]\'+'+'+CHR(34)+CHR(39)+" "
ENDIF
lcProcName = CHRTRAN(lcProcName,cbadchars ,REPL('_',LEN(cbadchars)))
RETURN lcProcName
ENDPROC
-- ※ 修改:.yuce 于 Aug 25 11:47:42 修改本文.[FROM: 202.96.101.162] ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.101.162]
|
|