934 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			934 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| subroutine tappbackup_sub(dummy)
 | |
| 
 | |
| * Changes and modification
 | |
| * ??/??/??  ???  Original programmer.
 | |
| * 01/30/96  DMG  Change to add Notes sources, Datasets and Reporistory Reports.
 | |
| * 02/22/96  CS   Fixed the table copy process to remove relational indexes
 | |
| 
 | |
| * Inserts.
 | |
| $insert DB_MGMT_EQUATES
 | |
| $insert fserrors_hdr
 | |
| $insert fserrors_100
 | |
| $insert fserrors_400
 | |
| $insert msg_equates
 | |
| $insert repository_equates
 | |
| $insert sysrepos_col_equates
 | |
| $insert systable_names
 | |
| 
 | |
| * Equates.
 | |
| EQU FALSE$		TO 0
 | |
| EQU TRUE$		TO 1
 | |
| EQU NULL$		TO ''
 | |
| EQU CRLF$		TO \0D0A\
 | |
| 
 | |
| EQU APPNAME$	TO "Application Backup"
 | |
| EQU WINID$		TO "APPBACKUP"
 | |
| EQU OPBACKUP$	TO "Backup"
 | |
| EQU OPRESTORE$	TO "Restore"
 | |
| EQU BACKUP$		TO "_BACKUP"
 | |
| EQU TYPEIDS$	TO "APPNOTE,APPROW,DATASOURCE,DBCOMPONENT,DBCOMPONENTEXE,DBCOLUMN,DBTABLE,DLL,DOC,IMAGE,MSG,OIEVENT,OIEVENTDBG,OIEVENTEXE,OIREPORT,OIWIN,OIWINEXE,OSFILE,POPUP,STPROC,STPROCDBG,STPROCEXE,STPROCINS,WINEXE"
 | |
| EQU TARGETS$	TO "LH,,LH,LH,LH,COLUMN,TABLE,OS,OS,OS,LH,LH,LH,LH,LH,LH,LH,OS,LH,LH,LH,LH,LH,OS"
 | |
| 
 | |
| * 1/18/96 - DMG - Added in the new datatypes.
 | |
| * DMG 1/18/96 - the concation operator within this string is to get around that a string can only have 255 chars
 | |
| EQU DESTLIST$	TO "SYSREPOSAPPNOTES,,SYSREPOSDATASOURCES,SYSREPOSDBCOMPONENTS,SYSREPOSDBCOMPONENTEXES,,,DLL,DOC,IMAGE,SYSREPOSMESSAGES,SYSREPOSEVENTS,SYSREPOSEVENTEXES,SYSREPOSEVENTEXES,SYSREPOSREPORTS,SYSREPOSWINS,SYSREPOSWINEXES,OSFILE,SYSREPOSPOPUPS,SYSPROCS,SYSOBJ,":"SYSOBJ,SYSPROCS,WINEXE"
 | |
| 
 | |
| EQU SETSTAT_OK$		TO 0
 | |
| EQU SETSTAT_ERR$	TO 1
 | |
| EQU SETSTAT_APPEND$	TO -1
 | |
| 
 | |
| EQU V119_DELETE$	TO 'D'
 | |
| EQU V119_EXTRACT$	TO 'E'
 | |
| EQU V119_INIT$		TO 'I'
 | |
| EQU V119_MERGE$		TO 'M'
 | |
| EQU V119_SORT$		TO 'S'
 | |
| EQU V119_VALUES$	TO 'V'
 | |
| EQU V119_WRITE$		TO 'W'
 | |
| 
 | |
| EQU MAX_LEN$		TO 32000	;* Threshold for creating temporary file. 
 | |
| EQU MAX_SEND_SIZE$	TO 32000	;* Target size for sending data back.
 | |
| EQU EXTRACT_SIZE$	TO 32000	;* Size of blocks that v119 sends back.
 | |
| 
 | |
| * Subroutine / function declarations.
 | |
| declare subroutine repos_checkformat, attach_table, mkdir, create_table, v119
 | |
| declare subroutine create_table, copy_table, detach_volume, update_index
 | |
| declare subroutine define_database, initrnd, set_property, set_fserror
 | |
| declare subroutine utility, msg, set_status, send_event, get_status
 | |
| declare function msg, get_property, repository, getappid
 | |
| declare function get_repos_entities, resolve_path, msg
 | |
| 
 | |
| * PROGRAM TOP *
 | |
| 
 | |
| utility( "CURSOR", 'H')	;* Put up hourglass.
 | |
| 
 | |
| * Initialization...
 | |
| winId = WINID$
 | |
| msgRow = ''
 | |
| tableList = ''
 | |
| errorSummary = "Code	-	Detail" : @FM
 | |
| bErrors = FALSE$
 | |
| bProcessErr = FALSE$
 | |
| bCopyHdr = FALSE$
 | |
| bLongList = FALSE$
 | |
| errStat = FALSE$
 | |
| SSPLIST = ''
 | |
| @file.error = ''
 | |
| bMerged = FALSE$		;* The sort file only needs to merged once.
 | |
| 
 | |
| 
 | |
| * Create a temporary sortfile name (8 characters in length).
 | |
| if len( @STATION) then
 | |
| 	sortfile = @STATION[ -8, 8]
 | |
| end else
 | |
| 	initrnd timedate()
 | |
| 	sortfile = rnd( 90000000) + 10000000
 | |
| end
 | |
| sortfile := ".SFX"
 | |
| 
 | |
| * Extract the parameters.
 | |
| controls = winId:".OPERATION_OPT" : @RM : winId:".LOCATION_EDIT"
 | |
| controls := @RM : winId:".COPYDATA_CHK"
 | |
| properties = "VALUE" : @RM : "TEXT" : @RM : "CHECK"
 | |
| retval = get_property( controls, properties)
 | |
| 
 | |
| operation = field( retval, @RM, 1, 1)
 | |
| location = field( retval, @RM, 2, 1)
 | |
| bCopyData = field( retval, @RM, 3, 1)
 | |
| if location else
 | |
| 	msgRow<MTEXT$> = "A location is required!"
 | |
| 	msgRow<MTYPE$> = "BOk"
 | |
| 	msgRow<MCAPTION$> = APPNAME$
 | |
| 	msgRow<MICON$> = '!'
 | |
| 	msg( winId, msgRow)
 | |
| 	return
 | |
| end
 | |
| 
 | |
| if location[ -1, 1] = '\' then
 | |
| 	location[ -1, 1] = ''
 | |
| end
 | |
| 
 | |
| appid = getappid()<1>
 | |
| 
 | |
| /* Copy Table now removes relational indexes so there is no need to stop 
 | |
| unless the users wants to CS*/
 | |
| 
 | |
| if operation = OPBACKUP$ then
 | |
| 	gosub analyze
 | |
| 	if errorList then
 | |
| 		convert @FM to CRLF$ in errorList
 | |
| 		msgRow  = "Relational Indexes will not be copied from the following tables:"
 | |
| 		msgRow := CRLF$ : CRLF$ : errorList : CRLF$
 | |
| 		msgRow := "Press Ok to continue"
 | |
| 		msgRow< MICON$ >  = '!'
 | |
| 		msgRow< MTYPE$ > = "BOC"
 | |
| 		
 | |
| 		response = msg( WINID$, msgRow)
 | |
| 		
 | |
| 		If response = Char(27) Then	return ; *Check to see if the user wants to abort
 | |
| 		
 | |
| 	end
 | |
| end
 | |
| 
 | |
| * Validate the location.  If no backup files exist, create them.
 | |
| tempSysRepos = SYSREPOS_FILE$ : BACKUP$
 | |
| attach_table( location, tempSysRepos, GLOBAL$, '', status)
 | |
| if get_status(errcode) then
 | |
| 
 | |
| 	* Table doesn't exist.  Create it.
 | |
| 	if errcode<1,1> = "FS":FS_INVALID_MAP_QUALIFIER$ then
 | |
| 		set_status( SETSTAT_OK$, TRUE$)
 | |
| 	end
 | |
| 
 | |
| 	begin case
 | |
| 
 | |
| 		  case operation = OPBACKUP$
 | |
| 
 | |
| 			* Prompt for creation of backup location.
 | |
| 			msgRow<MTEXT$> = "Backup files do not exist on ": location: ".": CRLF$: "Create?"
 | |
| 			msgRow<MTYPE$> = "BNYC"
 | |
| 			msgRow<MICON$> = '?'
 | |
| 			msgRow<MCAPTION$> = APPNAME$
 | |
| 			bCreate = msg( WINID$, msgRow)
 | |
| 			if bCreate = 1 else return	;* Chose No or Cancel.
 | |
| 
 | |
| 			* Make sure the directory exists.
 | |
| 			mkdir( location:char(0), status)
 | |
| 
 | |
| 			* Create the sysrepos-backup table.
 | |
| 			create_table( location, tempSysRepos, 0, GLOBAL$, '', '')
 | |
| 			if get_status() then
 | |
| 				return
 | |
| 			end
 | |
| 
 | |
| 			utility( "CURSOR", 'H')
 | |
| 
 | |
| 		  case operation = OPRESTORE$
 | |
| 
 | |
| 			* No backup data here!
 | |
| 			msgRow<MTEXT$> = "There is no data on " : location
 | |
| 			msgRow<MTYPE$> = "BOk"
 | |
| 			msgRow<MICON$> = '!'
 | |
| 			msgRow<MCAPTION$> = APPNAME$ : "- Error"
 | |
| 			msg( WINID$, msgRow)
 | |
| 			return
 | |
| 
 | |
| 		  case 1
 | |
| 	end	  case
 | |
| end else
 | |
| 	if operation = OPBACKUP$ then
 | |
| 		* If backing up, prompt for overwriting.
 | |
| 
 | |
| 		msgRow = "Backup files already exist on ": location: "."
 | |
| 		msgRow := "  If this application has been backed up at this"
 | |
| 		msgRow := " location previously, the existing data will be lost."
 | |
| 		msgRow := CRLF$: "Continue?"
 | |
| 		msgRow< MTYPE$> = "BNYC"
 | |
| 		msgRow< MDEFBTN$> = 2
 | |
| 		msgRow< MICON$> = '!'
 | |
| 		bOverwrite = msg( WINID$, msgRow)
 | |
| 		if bOverwrite = 1 else return
 | |
| 		gosub clearData
 | |
| 	end
 | |
| end
 | |
| 
 | |
| * Open required tables.
 | |
| if operation = OPBACKUP$ then
 | |
| 	sysreposSrc = SYSREPOS_FILE$
 | |
| 	sysreposDst = SYSREPOS_FILE$:BACKUP$
 | |
| end else
 | |
| 	sysreposSrc = SYSREPOS_FILE$:BACKUP$
 | |
| 	sysreposDst = SYSREPOS_FILE$
 | |
| end
 | |
| open sysreposSrc to fhSysReposSrc else
 | |
| 	set_fserror()
 | |
| 	return
 | |
| end
 | |
| open sysreposDst to fhSysReposDst else
 | |
| 	set_fserror()
 | |
| 	return
 | |
| end
 | |
| open SYSTABLES_FILE$ to fhSysTables else
 | |
| 	set_fserror()
 | |
| 	return
 | |
| end
 | |
| 
 | |
| moreInfo = TRUE$	;* We can handle over 64k.
 | |
| 
 | |
| loop
 | |
| 
 | |
| 	* Get list of entities for this application.
 | |
| 	set_property( winID:".STATUS_TEXT", "TEXT", "Selecting...")
 | |
| 	if operation = OPBACKUP$ then
 | |
| 		* Backup logic.  Get list of entities, making multiple calls if
 | |
| 		* there is over 64K worth of names.
 | |
| 
 | |
| 		* Arguments are APPID, TYPEID, CLASSID, ReturnFlags, ExpandNames, RemoteRepository, fMoreInfo (>64k).
 | |
| 		entList = get_repos_entities( appid, '', '', FALSE$, TRUE$, FALSE$, moreInfo)
 | |
| 		if len( moreInfo) then
 | |
| 			* List is > 64K...we'll need to make multiple calls.
 | |
| 			bLongList = TRUE$
 | |
| 		end
 | |
| 
 | |
| 	end else
 | |
| 		* Operation is "RESTORE" (OPRESTORE$).
 | |
| 
 | |
| 		if bLongList then
 | |
| 			* 2nd - nth time through this loop.  This occurs only if the
 | |
| 			* list to restore is greater than 64K.
 | |
| 
 | |
| 			gosub ExtractSort
 | |
| 
 | |
| 		end else
 | |
| 			* First time through...select SYSREPOS_BACKUP table and retrieve
 | |
| 			* the list of entities.
 | |
| 
 | |
| 			select fhSysReposSrc	;* 1st time...create list of entities.
 | |
| 			done = FALSE$
 | |
| 			entList = ''
 | |
| 			loop
 | |
| 				readnext entid else done = TRUE$
 | |
| 			until done
 | |
| 
 | |
| 				* Only restore objects from this application.
 | |
| 				if entid[ 1, '*'] = appid then
 | |
| 					entList := entid : @FM
 | |
| 
 | |
| 					if (len( entList) > MAX_LEN$) then
 | |
| 						* List has reached threshold...use temp sort-file.
 | |
| 
 | |
| 						if bLongList else
 | |
| 							* Need to create sort-file.
 | |
| 							gosub InitSort
 | |
| 							if errStat then
 | |
| 								return
 | |
| 							end
 | |
| 							bLongList = TRUE$
 | |
| 						end
 | |
| 
 | |
| 						* Sort and store what we have.  Refresh list.
 | |
| 						gosub DoSort
 | |
| 						entList = ''
 | |
| 
 | |
| 					end
 | |
| 				end
 | |
| 			repeat
 | |
| 
 | |
| 			if bLongList else
 | |
| 				* List is under threshold...no temp-file was necessary.
 | |
| 				moreInfo = NULL$
 | |
| 			end
 | |
| 
 | |
| 			if len( entList) then
 | |
| 				* Sort & process current entity-list.
 | |
| 				gosub DoSort
 | |
| 				if entList[ -1, 1] = @FM then entList[ -1, 1] = ''
 | |
| 			end
 | |
| 
 | |
| 			if bLongList then
 | |
| 				* Merge lists and extract first block.
 | |
| 				entList = ''
 | |
| 				gosub MergeSort
 | |
| 				gosub ExtractSort
 | |
| 			end
 | |
| 		end
 | |
| 	end
 | |
| 	if get_status() then return
 | |
| 
 | |
| 	* Count the number of entities we currently have.
 | |
| 	numEntities = count( entList, @fm) + (entList # NULL$)
 | |
| 
 | |
| 	* Initialize the status & progress bars.
 | |
| 	set_property( winID:".STATUS_TEXT", "TEXT", '')
 | |
| 	gosub InitProgressBar
 | |
| 
 | |
| 	* Process entities...bail out if error flag is set in process loop.
 | |
| 	bProcessErr = FALSE$
 | |
| 	gosub ProcessEntities
 | |
| 	if bProcessErr then goto Exit
 | |
|  
 | |
|  * If there are more entities...get them!
 | |
|  while len( moreInfo)
 | |
| repeat
 | |
| 
 | |
| if (operation = OPRESTORE$) and bLongList then
 | |
| 	* Temporary sort-file was used...delete it.
 | |
| 	gosub deleteSort
 | |
| end
 | |
| 
 | |
| * Detach the backup location.
 | |
| detach_volume( location, status)
 | |
| 
 | |
| * If DBTABLEs were restored...save the database definition.
 | |
| if operation = OPRESTORE$ then
 | |
| 	if tableList then
 | |
| 		set_property( winID:".STATUS_TEXT", "TEXT", "Updating...")
 | |
| 		define_database( @dbid, 1, '', 0)
 | |
| 	end 
 | |
| end
 | |
| 
 | |
| * Clear status & progress controls.
 | |
| controls = winID:".STATUS_TEXT" : @RM : winID:".PROGRESS_BAR"
 | |
| controls := @RM : winID:".ENTITYID"
 | |
| properties = "TEXT" : @RM : "SIZE" : @RM : "TEXT"
 | |
| values = '' : @RM : minBar : @RM : ''
 | |
| set_property( controls, properties, values)
 | |
| 
 | |
| * We're done!
 | |
| msgRow = "The " : operation : " of " : appid : " is complete."
 | |
| exit:
 | |
| if bErrors then
 | |
| 	errorsID = appid:"*ERRORS"
 | |
| 	msgRow = "Error detail has been written"
 | |
| 	msgRow := " to data row":CRLF$:"'":errorsID:"'":CRLF$:"in the 'SYSLISTS'"
 | |
| 	msgRow := " table and can be viewed using the system editor."
 | |
| end
 | |
| msgRow< MICON$> = '!'
 | |
| msgRow< MCAPTION$> = "Application Backup"
 | |
| msg( WINID$, msgRow)
 | |
| 
 | |
| if bErrors then
 | |
| 	open SYSLISTS_FILE$ to fhSysLists then
 | |
| 		write errorSummary to fhSysLists, errorsID else
 | |
| 			set_fserror()
 | |
| 		end
 | |
| 	end else
 | |
| 		set_fserror()
 | |
| 	end
 | |
| end
 | |
| 
 | |
| send_event( WINID$, "CLOSE")
 | |
| 
 | |
| RETURN
 | |
| /* ----------------------------------------------------------------------- */
 | |
| analyze:
 | |
| * Tables with relational indexing cannot be copied.
 | |
| errorList = ''
 | |
| if bCopyData then
 | |
| 	set_property( winId:".STATUS_TEXT", "TEXT", "Analyzing...")
 | |
| 	dbTables = get_repos_entities( appid, "DBTABLE", '')
 | |
| 	numTables = count( dbTables, @FM) + ( dbTables ne '')
 | |
| 	for tableCntr = 1 to numTables
 | |
| 		dbName = field( dbTables< tableCntr>, KEYSEP$, 4, 1)
 | |
| 		if dbName[ 1, 1] = '!' then
 | |
| 			open dbName to fhBang then
 | |
| 				read bangRow from fhBang, dbName then
 | |
| 					indexPos = 4
 | |
| 					loop
 | |
| 						tempInfo = bangRow< 1, 1, indexPos>
 | |
| 					while tempInfo
 | |
| 						convert @TM:'*' to @FM:@VM in tempInfo
 | |
| 						indexType = tempInfo<3>
 | |
| 						if indexType = 3 or indexType = 5 then
 | |
| 							errorList<-1> = dbName
 | |
| 						end
 | |
| 						indexPos += 1
 | |
| 					repeat
 | |
| 				end
 | |
| 			end
 | |
| 		end
 | |
| 	next tableCntr
 | |
| 	set_property( winId:".STATUS_TEXT", "TEXT", '')
 | |
| end
 | |
| return
 | |
| /* ----------------------------------------------------------------------- */
 | |
| clearData:
 | |
| * Clear previous backup data.
 | |
| set_property( winID:".STATUS_TEXT", "TEXT", "Clearing...")
 | |
| sysreposDst = SYSREPOS_FILE$:BACKUP$
 | |
| open sysreposDst to fhTemp then
 | |
| 	select fhTemp
 | |
| 	done = FALSE$
 | |
| 	loop
 | |
| 		readnext tempId else done = TRUE$
 | |
| 	until done
 | |
| 		tempAppid = field( tempId, KEYSEP$, APPID$, 1)
 | |
| 		if tempAppid = appid then
 | |
| 			delete fhTemp, tempId else NULL
 | |
| 		end
 | |
| 	repeat
 | |
| end
 | |
| set_property( winID:".STATUS_TEXT", "TEXT", '')
 | |
| return
 | |
| /* ----------------------------------------------------------------------- */
 | |
| InitProgressBar:
 | |
| * Initialize progress bar.
 | |
| 
 | |
| 	maxBar = get_property( winID:".PROGRESS_BACK", "SIZE")
 | |
| 	maxWidth = maxBar<3>
 | |
| 	minBar = fieldstore( maxBar, @fm, 3, 1, 0)
 | |
| 	currBar = minBar
 | |
| 	backColor = 255
 | |
| 	controls = winID:".PROGRESS_BAR" : @RM : winID:".PROGRESS_BAR"
 | |
| 	controls := @RM : winID:".ENTITY_LABEL"
 | |
| 	properties = "SIZE" : @RM : "BACKCOLOR" : @RM : "ENABLED"
 | |
| 	values = currBar : @RM : backColor : @RM : TRUE$
 | |
| 	set_property( controls, properties, values)
 | |
| 
 | |
| return
 | |
| /* ----------------------------------------------------------------------- */
 | |
| ProcessEntities:
 | |
| * Process the entities.
 | |
| 
 | |
| doneList = ''	;* Keep track of types already processed (for initialization).
 | |
| currType = ''
 | |
| 
 | |
| for entCounter = 1 to numEntities
 | |
| 
 | |
| 	entid = entList< entCounter>
 | |
| 	appid = field( entid, KEYSEP$, APPID$, 1)
 | |
| 	typeid = field( entid, KEYSEP$, TYPEID$, 1)
 | |
| 	classid = field( entid, KEYSEP$, CLASSID$, 1)
 | |
| 	entityid = field( entid, KEYSEP$, ENTITYID$, 1)
 | |
| 	
 | |
| 	locate typeid in TYPEIDS$ using ',' setting typePos then
 | |
| 		backupType = field( TARGETS$, ',', typePos, 1)
 | |
| 		bodySpec = field( DESTLIST$, ',', typePos, 1)
 | |
| 		bCopyHdr = TRUE$
 | |
| 		bCopyBody = TRUE$
 | |
| 		set_property( winId:".ENTITYID", "TEXT", entid)
 | |
| 	end else
 | |
| 		backupType = ''
 | |
| 	end
 | |
| 
 | |
| 	begin case
 | |
| 		  case backupType = "LH"
 | |
| 
 | |
| 			if operation = OPBACKUP$ then
 | |
| 				sourceTable = bodySpec
 | |
| 				destTable = bodySpec:BACKUP$
 | |
| 			end else
 | |
| 				sourceTable = bodySpec:BACKUP$
 | |
| 				destTable = bodySpec
 | |
| 			end
 | |
| 
 | |
| 			* Prepare the destination for the backup.  This is done once for each type.
 | |
| 		  	locate typeid in doneList using @fm setting donePos else
 | |
| 		  		if operation = OPBACKUP$ then
 | |
| 			  		create_table( location, destTable, 0, GLOBAL$, '', 0)
 | |
| 			  		if get_status(errcode) then
 | |
| 						if errcode<1,1> = 'FS':FS_FILE_ALREADY_EXISTS$ then
 | |
| 							set_status( SETSTAT_OK$, TRUE$)
 | |
| 						end else
 | |
| 							gosub promptErr
 | |
| 							if bContinue then
 | |
| 								goto nextEntity
 | |
| 							end else
 | |
| 								bProcessErr = TRUE$
 | |
| 								return
 | |
| 							end
 | |
| 						end
 | |
| 			  		end
 | |
| 				  	attach_table( location, destTable, GLOBAL$, '',status)
 | |
| 				  	if get_status() then
 | |
| 						gosub promptErr
 | |
| 						if bContinue then
 | |
| 							goto nextEntity
 | |
| 						end else
 | |
| 							bProcessErr = TRUE$
 | |
| 							return
 | |
| 						end
 | |
| 				  	end
 | |
| 				  	doneList<-1> = typeid
 | |
| 
 | |
| 					* Retrieve list of system procs.
 | |
| 					open SYSENV_FILE$ to fhSysEnv then
 | |
| 						read SSPList from fhSysEnv, "SYSPROCNAMES" else SSPList = ''
 | |
| 					end else
 | |
| 						SSPList = ''
 | |
| 					end
 | |
| 				end else
 | |
| 					attach_table( location, sourceTable, GLOBAL$, '',status)
 | |
| 					if get_status() then
 | |
| 						gosub promptErr
 | |
| 						if bContinue then
 | |
| 							goto nextEntity
 | |
| 						end else
 | |
| 							bProcessErr = TRUE$
 | |
| 							return
 | |
| 						end
 | |
| 					end
 | |
| 				end
 | |
| 		  	end
 | |
| 
 | |
| 			* Open the table and transfer the body.
 | |
| 			if currType = typeid else
 | |
| 				open sourceTable to fhSrc else			;* Open source table.
 | |
| 					set_fserror()
 | |
| 					gosub promptErr
 | |
| 					if bContinue then
 | |
| 						goto nextEntity
 | |
| 					end else
 | |
| 						bProcessErr = TRUE$
 | |
| 						return
 | |
| 					end
 | |
| 				end				
 | |
| 				open destTable to fhDest else		;* Open Destination table.
 | |
| 					set_fserror()
 | |
| 					gosub promptErr
 | |
| 					if bContinue then
 | |
| 						goto nextEntity
 | |
| 					end else
 | |
| 						bProcessErr = TRUE$
 | |
| 						return
 | |
| 					end
 | |
| 				end				
 | |
| 			end
 | |
| 
 | |
| 			if typeid[ 1, 6] = "STPROC" then
 | |
| 				* Don't backup system procedures.
 | |
| 				if appid = "SYSPROG" and typeid = "STPROCEXE" then
 | |
| 					locate entityid in SSPList using @FM setting nothing then
 | |
| 						bCopyBody = FALSE$
 | |
| 						bCopyHdr = FALSE$
 | |
| 					end
 | |
| 				end
 | |
| 
 | |
| 				begin case
 | |
| 					  case typeid = "STPROCDBG"
 | |
| 					  	procid = '@':entityid
 | |
| 
 | |
| 					  case typeid = "STPROCEXE"
 | |
| 					  	procid = '$':entityid
 | |
| 
 | |
| 					  case 1
 | |
| 					  	procid = entityid
 | |
| 
 | |
| 				end   case
 | |
| 				bodyID = if appid = "SYSPROG" then procid else procid:KEYSEP$:appid
 | |
| 
 | |
| 			end else
 | |
| 				bodyID = appid : KEYSEP$ : classid : KEYSEP$ : entityid
 | |
| 			end
 | |
| 
 | |
| 			if bCopyBody then
 | |
| 			read entBody from fhSrc, bodyID else entBody = ''
 | |
| 				write entBody to fhDest, bodyID else
 | |
| 					set_fserror()
 | |
| 					gosub promptErr
 | |
| 					if bContinue then
 | |
| 						goto nextEntity
 | |
| 					end else
 | |
| 						bProcessErr = TRUE$
 | |
| 						return
 | |
| 					end
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 		  case backupType = "OS"
 | |
| 		    if operation = OPBACKUP$ then
 | |
| 				srcSpec = repository( "GETSUBKEY" , entid)
 | |
| 			  	destDir = location : '\' : bodySpec
 | |
| 				dosfile = srcSpec[ -1, "B\"]
 | |
| 				dstSpec = destDir : '\' : dosfile
 | |
| 			  	* Create the directory (done only once).
 | |
| 			  	locate typeid in doneList using @fm setting nothing else
 | |
| 					mkdir( destDir:char(0), status)
 | |
| 			  	end
 | |
| 			end else
 | |
| 				read entHdr from fhSysReposSrc, entid then
 | |
| 					dstSpec = entHdr< SYSREP_SUB_KEY$>
 | |
| 					dosfile = dstSpec[ -1, "B\"]
 | |
| 					destDir = dstSpec[ 1, (col1() - 1)]
 | |
| 					srcSpec = location : '\' : bodySpec : '\' : dosfile
 | |
| 					mkdir( destDir:char(0), status)
 | |
| 				end else
 | |
| 					@file.error< FSMSG$> = entid
 | |
| 					set_fserror()
 | |
| 					gosub promptErr
 | |
| 					if bContinue then
 | |
| 						goto nextEntity
 | |
| 					end else
 | |
| 						bProcessErr = TRUE$
 | |
| 						return
 | |
| 					end
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			* Transfer the file.
 | |
| 			osopen srcSpec to hSrc else
 | |
| 				@file.error = FS_READ_FILE_DNE$
 | |
| 				@file.error< FSMSG$> = srcSpec
 | |
| 				set_fserror()
 | |
| 				gosub promptErr
 | |
| 				if bContinue then
 | |
| 					goto nextEntity
 | |
| 				end else
 | |
| 					bProcessErr = TRUE$
 | |
| 					return
 | |
| 				end
 | |
| 			end
 | |
| 			osopen dstSpec to hDst else
 | |
| 				oswrite '' to dstSpec
 | |
| 				osopen dstSpec to hDst else
 | |
| 					@file.error = FS_READ_FILE_DNE$
 | |
| 					@file.error< FSMSG$> = dstSpec
 | |
| 					set_fserror()
 | |
| 					gosub promptErr
 | |
| 					if bContinue then
 | |
| 						goto nextEntity
 | |
| 					end else
 | |
| 						bProcessErr = TRUE$
 | |
| 						return
 | |
| 					end
 | |
| 				end
 | |
| 			end
 | |
| 			offset = 0
 | |
| 			loop
 | |
| 				osbread osData from hSrc at offset length 16384
 | |
| 				doserr = status()
 | |
| 			while osData and not(doserr)
 | |
| 				osbwrite osData to hDst at offset
 | |
| 				doserr = status()
 | |
| 			until doserr
 | |
| 				offset += len( osData)
 | |
| 			repeat
 | |
| 
 | |
| 			if doserr then
 | |
| 				set_fserror()
 | |
| 				gosub promptErr
 | |
| 				if bContinue then
 | |
| 					goto nextEntity
 | |
| 				end else
 | |
| 					bProcessErr = TRUE$
 | |
| 					return
 | |
| 				end
 | |
| 			end
 | |
| 			osclose hSrc
 | |
| 			osclose hDst
 | |
| 
 | |
| 		  case backupType = "COLUMN"
 | |
| 
 | |
| 			if operation = OPBACKUP$ then
 | |
| 			  	* Don't copy system-table headers.
 | |
| 			  	if entityid[ 1, 3] = "SYS" or entityid[ 1, '.'] = "ACCESSIBLE_COLUMNS" then
 | |
| 			  		bCopyHdr = FALSE$
 | |
| 			  	end
 | |
| 
 | |
| 				* Post-beta 1 fix...don't copy DBCOLUMNs that are duped in SYSPROG.
 | |
| 				if appid = "CARPARTS" then
 | |
| 					sysprogEnt = "SYSPROG": KEYSEP$: typeid: KEYSEP$: classid: KEYSEP$: entityid
 | |
| 					read sysprogHdr from fhSysReposSrc, sysprogEnt then
 | |
| 						bCopyHdr = FALSE$
 | |
| 					end
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 		  case backupType = "TABLE"
 | |
| 
 | |
| 			if operation = OPBACKUP$ then
 | |
| 				srcName = entityid
 | |
| 				destName = entityid:BACKUP$
 | |
| 				destLocation = location
 | |
| 			  	subkey = repository( "GETSUBKEY", entid)
 | |
| 			  	bfs = subkey< 1, 2>
 | |
| 			  	dbid = subkey< 1, 3>
 | |
| 			end else
 | |
| 				srcName = entityid:BACKUP$
 | |
| 				destName = entityid
 | |
| 				read entHdr from fhSysReposSrc, entid then
 | |
| 					subkey = entHdr< SYSREP_SUB_KEY$>
 | |
| 					destLocation = subkey< 1, 1>
 | |
| 				  	bfs = subkey< 1, 2>
 | |
| 				  	dbid = subkey< 1, 3>
 | |
| 				end else
 | |
| 					@file.error< FSMSG$> = entid
 | |
| 					set_fserror()
 | |
| 					gosub promptErr
 | |
| 					if bContinue then
 | |
| 						goto nextEntity
 | |
| 					end else
 | |
| 						bProcessErr = TRUE$
 | |
| 						return
 | |
| 					end
 | |
| 				end
 | |
| 				if bCopyData then
 | |
| 					attach_table( location, srcName, dbid, '', status)
 | |
| 					if get_status() then
 | |
| 						gosub promptErr
 | |
| 						if bContinue then
 | |
| 							goto nextEntity
 | |
| 						end else
 | |
| 						bProcessErr = TRUE$
 | |
| 						return
 | |
| 						end
 | |
| 					end
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 		  	* Copy the entire table (skip '!' & 'DICT.').
 | |
| 		  	if bCopyData then
 | |
| 			  	if entityid[1,1] = '!' or entityid[1,5] = "DICT." or entityid[1,3] = "SYS" or entityid = "ACCESSIBLE_COLUMNS" else
 | |
| 				  	if bfs = "RTP57" then
 | |
| 				  		read systablesRow from fhSysTables, srcName then
 | |
| 				  		 
 | |
| 				  			copy_table( srcName, destLocation, dbid, destName, '', '', TRUE$, '', status, TRUE$ )
 | |
| 					  								  		
 | |
| 					  		if get_status(errcode) then
 | |
| 								if errcode<1,1> = "FS267" or errcode<1,1> = "FS259" then
 | |
| 									msgRow = "Table ":errcode<1,2>:" has relational indexing on it and"
 | |
| 									msgRow := " cannot be copied until the indexes are removed."
 | |
| 									msgRow< MICON$> = '!'
 | |
| 									msg( WINID$, msgRow)
 | |
| 								end
 | |
| 					  			if errcode<1,1> = "FS100" or errcode<1,1> = "FS109" then
 | |
| 					  				set_status( SETSTAT_OK$, TRUE$)
 | |
| 					  			end else
 | |
| 									gosub promptErr
 | |
| 									if bContinue then
 | |
| 										goto nextEntity
 | |
| 									end else
 | |
| 										bProcessErr = TRUE$
 | |
| 										return
 | |
| 									end
 | |
| 								end
 | |
| 							end
 | |
| 							if operation = OPRESTORE$ then
 | |
| 								attach_table( destLocation, destName, dbid, '',status)
 | |
| 								if get_status() else
 | |
| 									tableList<-1> = destName
 | |
| 								end
 | |
| 							end
 | |
| 						end
 | |
| 					end
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			if operation = OPBACKUP$ then
 | |
| 				* Don't backup system tables.
 | |
| 				if entityid[1,3] = "SYS" or entityid[1,8] = "DICT.SYS" or entityid[1,4] = "!SYS" or entityid = "ACCESSIBLE_COLUMNS" then
 | |
| 					bCopyHdr = FALSE$
 | |
| 				end
 | |
| 
 | |
| 				* Post-beta 1 fix...don't copy DBTABLEs that are duped in SYSPROG.
 | |
| 				if appid = "CARPARTS" then
 | |
| 					sysprogEnt = "SYSPROG": KEYSEP$: typeid: KEYSEP$: classid: KEYSEP$: entityid
 | |
| 					read sysprogHdr from fhSysReposSrc, sysprogEnt then
 | |
| 						bCopyHdr = FALSE$
 | |
| 					end
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 		  case 1
 | |
| 	end   case
 | |
| 
 | |
| 	currType = typeid
 | |
| 
 | |
| 	* Copy the entity header.
 | |
| 	if bCopyHdr then
 | |
| 		read entHdr from fhSysReposSrc, entid then
 | |
| 			write entHdr to fhSysReposDst, entid else
 | |
| 				set_fserror()
 | |
| 				gosub promptErr
 | |
| 				if bContinue then
 | |
| 					goto nextEntity
 | |
| 				end else
 | |
| 					bProcessErr = TRUE$
 | |
| 					return
 | |
| 				end
 | |
| 			end
 | |
| 		end else
 | |
| 			set_fserror()
 | |
| 			gosub promptErr
 | |
| 			if bContinue then
 | |
| 				goto nextEntity
 | |
| 			end else
 | |
| 				bProcessErr = TRUE$
 | |
| 				return
 | |
| 			end
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	* Update progress bar.
 | |
| 	* Cannot update if > 64k because it's an unresolved list.
 | |
| 	if bLongList then
 | |
| 		set_property( winID:".STATUS_TEXT", "TEXT", "Processing...")
 | |
| 	end else
 | |
| 		if not( mod(entCounter,10)) or (entCounter = numEntities) then
 | |
| 			pctText = (int( entCounter/numEntities * 100)) : '%'
 | |
| 			pctText = fmt( pctText, "C#15")
 | |
| 			newWidth = int( (entCounter/numEntities) * maxWidth)
 | |
| 			currBar = fieldstore( currBar, @fm, 3, 1, newWidth)
 | |
| 			controls = winID:".STATUS_TEXT" : @RM : winID:".PROGRESS_BAR"
 | |
| 			properties = "TEXT" : @RM : "SIZE"
 | |
| 			values = pctText : @RM : currBar
 | |
| 			set_property( controls, properties, values)
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
|   nextEntity:
 | |
| next entCounter
 | |
| 
 | |
| return
 | |
| /* ----------------------------------------------------------------------- */
 | |
| PromptErr:
 | |
| * Display error info & prompt for continuing.
 | |
| 	bErrors = TRUE$
 | |
| 	get_status( errcode)
 | |
| 	set_status( SETSTAT_OK$, '')
 | |
| 	msgRow = "An error was encountered." : CRLF$
 | |
| 	msgRow := "Error code: ": errcode<1,1> : CRLF$
 | |
| 	msgRow := "Detail: ": errcode<1,2> : CRLF$ : CRLF$
 | |
| 	msgRow := "Continue?"
 | |
| 	msgRow< MICON$> = '!'
 | |
| 	msgRow< MTYPE$> = "BNY"
 | |
| 	msgRow< MTEXTWIDTH$> = "300"
 | |
| 	msgRow< MCAPTION$> = "Application Backup Error"
 | |
| 	answer = msg( winID, msgRow)
 | |
| 	if answer = 1 then
 | |
| 		bContinue = TRUE$
 | |
| 	end else
 | |
| 		bContinue = FALSE$
 | |
| 	end
 | |
| 	swap @VM with " - " in errcode
 | |
| 	errorSummary<-1> = errcode
 | |
| return
 | |
| /* ----------------------------------------------------------------------- */
 | |
| InitSort:
 | |
| * Initialize the sort file.
 | |
| 
 | |
| 	osdelete sortFile
 | |
| 	v119( V119_INIT$, sortFile, '', '', '', sortStat)
 | |
| 	if sortStat else
 | |
| 		@FILE.ERROR<FSCODE$> = FS_SYS_SORT_INIT_ERR$
 | |
| 		set_fserror()
 | |
| 		errStat = TRUE$
 | |
| 	end
 | |
| 
 | |
| 	return
 | |
| 
 | |
| /* ----------------------------------------------------------------------- */
 | |
| DeleteSort:
 | |
| * Delete the sort file.
 | |
| 
 | |
| 	v119( V119_DELETE$, sortFile, '', '', '', sortStat)
 | |
| 
 | |
| 	return
 | |
| 
 | |
| /* ----------------------------------------------------------------------- */
 | |
| DoSort:
 | |
| * Sort the data.  If long sort, write to temp file.
 | |
| 
 | |
| 	convert \FEFD\ to \FFFE\ in entList
 | |
| 	if entList[ -1, 1] <> @RM then
 | |
| 		entList := @RM
 | |
| 	end
 | |
| 	v119( V119_SORT$, '', 'A', 'L', entList, '')
 | |
| 	if bLongList then
 | |
| 		v119( V119_WRITE$, sortFile, '', '', entList, sortStat)
 | |
| 		if sortStat else
 | |
| 			@FILE.ERROR<FSCODE$> = FS_SYS_SORT_WRITE_ERR$
 | |
| 			set_fserror()
 | |
| 			errStat = TRUE$
 | |
| 		end
 | |
| 	end
 | |
| 	convert \FFFE\ to \FEFD\ in entList
 | |
| 
 | |
| 	return
 | |
| 
 | |
| /* ----------------------------------------------------------------------- */
 | |
| MergeSort:
 | |
| * Merge the data in the temp file.
 | |
| 
 | |
| 	v119( V119_MERGE$, sortFile , 'A', 'L', '', sortStat)
 | |
| 	bMerged = TRUE$
 | |
| 	if sortStat else
 | |
| 		@FILE.ERROR<FSCODE$> = FS_SYS_SORT_MERGE_ERR$
 | |
| 		set_fserror()
 | |
| 		errStat = TRUE$
 | |
| 	end
 | |
| 
 | |
| 	return
 | |
| 
 | |
| /* ----------------------------------------------------------------------- */
 | |
| ExtractSort:
 | |
| * Determine the extract operation (long or short) and do it.
 | |
| 
 | |
| 	if bLongList then
 | |
| 		if bMerged else
 | |
| 			gosub mergeSort
 | |
| 			if errStat then return
 | |
| 		end
 | |
| 		entList = ''
 | |
| 		v119( 'V', sortFile, 'A', 'L', entList, sortStat)
 | |
| 		if sortStat else
 | |
| 			@FILE.ERROR<FSCODE$> = FS_SYS_SORT_EXTRACT_ERR$
 | |
| 			errStat = TRUE$
 | |
| 			return
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	* If less than max size, there's no more in temp file.
 | |
| 	if len( entList) < EXTRACT_SIZE$ then
 | |
| 		moreInfo = ''
 | |
| 	end else
 | |
| 		moreInfo = TRUE$
 | |
| 	end
 | |
| 
 | |
| 	if bLongList then
 | |
| 		convert \FFFE\ to \FEFD\ in entList
 | |
| 	end
 | |
| 	entList[ -1, 1] = ''
 | |
| 
 | |
| 	return
 | |
| 
 |