Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Database update, best practices
Message
From
25/01/2002 10:57:45
Hilmar Zonneveld
Independent Consultant
Cochabamba, Bolivia
 
 
To
25/01/2002 10:03:09
Carol Dewar
Magram Computer Services Llc
Saugerties, New York, United States
General information
Forum:
Visual FoxPro
Category:
Databases,Tables, Views, Indexing and SQL syntax
Miscellaneous
Thread ID:
00610172
Message ID:
00610518
Views:
27
This message has been marked as the solution to the initial question of the thread.
>Hmmm,
>So we can, after copying everything to the backup directory:
>Replace all of the client's database/tables with empty, ...

I have an empty copy of the database / tables in the first place, and do all my changes there. For testing I have a copy of the data on my machine, which is updated with the same "updatedb" program.

> ... updated database/tables from the library.
>Run the generate client dictionary and structure compare code to log all the changes.
>DOS COPY tables, for no hits. APPEND FROM (and initialize if needed) for any hits in a table.

>We have no Database considerations.
>This is like my 1st senario only less complex.
>Have you automated this? done this remotely? Any "Lights out" problems? considerations?

I will include my program; one thing I can't include, because it belongs to the framework I use.

You will therefore need to provide the Table_Needs_Update() function. For a quick start, let it provide "new table" for new tables, and "there are changes" for all others. You can add commands to check for changes (and return "no changes" as appropriate) later.

The basis for the following program is: create a list of tables, create a list of relations, loop through all tables and update them, postponing tables that are on the "child" side of a parent-child relation for the next iteration of the loop.

HTH, Hilmar.
* Update the structure of a local database,
* based on the official, empty, database

lParameters tlRealData

#DEFINE DIR_BACKUP		"c:\DataBackup\"
#DEFINE TEMPDIR			"c:\TempData\"
#DEFINE FORCEUPDATE		.F.

local lcEmptyStructure, lcTargetDatabase
lcEmptyStructure = "c:\proyectos\produccion\EmptyStructure\"
lcTargetDatabase = iif(tlRealData, "\\MyServer\MyApp\data\", "c:\Project\MyProject\data\")

UpdateDatabase(lcEmptyStructure, lcTargetDatabase, tlRealData)	&& call main program




FUNCTION UpdateDatabase(tcEmptyStructure, tcTargetDatabase, tlDoBackup)
	if parameters() < 3
		tlDoBackup = .T.	&& assign default
	endif

	* Initialization
	set deleted on
	set safety off
	close databases all
	set talk off
	set procedure to c:\...\MyFrameWork\SpecialFunctions.prg && for Table_Needs_Update()
	clear	&& For showing messages on main screen
	if FORCEUPDATE
		? "FORCED UPDATE. ALL TABLES WILL BE UPDATED."
	endif
	* clear all

	* Don't register auditing information (when appending records)
	* The following variable is used by my audit function
	private pldoaudit
	pldoaudit = .F.

	* Copy data to backup dir
	if tlDoBackup
		? time(), "Copying files to backup folder"
		if not directory(DIR_BACKUP)
			md (DIR_BACKUP)
		endif
		erase (DIR_BACKUP + "*.*")
		copy file (tcTargetDatabase + "*.*") to (DIR_BACKUP + "*.*")
	endif

	* Copy empty structure to temp data
	? time(), "Copying empty structure to " + TEMPDIR
	if not directory(TEMPDIR)
		md TEMPDIR
	endif
	erase (TEMPDIR + "*.*")
	copy file (tcEmptyStructure + "*.*") to (TEMPDIR + "*.*")

	* Create list of tables to be copied
	? time(), "Creating list of tables"
	local array laTables(1,1)
	adir(laTables, tcEmptyStructure + "*.dbf")
	create table TempTableList (table C(30))
	append from array laTables
	replace all table with juststem(table)	&& get rid of extension

	* Create list of relations, for checking order of table copy
	? time(), "Creating list of relations"
	open database tcEmptyStructure + "database"
	local array laRelations(1,1)
	adbobjects(laRelations, "relation")
	create table TempRelations free (child C(30), parent C(30), childtag C(10), parenttag C(10), ri C(10))
	append from array laRelations
	* If a relation doesn't "Restrict" child inserts, it causes no problem.
	delete for substr(ri,3,1) # "R"
	index on child tag child
	index on parent tag parent
	close database

	* Append modified tables; erase others (no need to overwrite non-modified files
	*   back to target data)
	set talk on
	? time(), "Combining data with updated structure"
	local lnNeedUpdate
	local llTablesProcessed
	llTablesProcessed = .T.
	do while llTablesProcessed
		select TempTableList
		llTablesProcessed = .F.
		scan && in TempTableList
			wait window nowait "Searching for next table to copy"
			llTablesProcessed = .T.	&& there still is at least one table in TempTableList
			lcTable = alltrim(TempTableList.table)
			select TempRelations
			set order to "child"
			if seek(padr(lcTable, len(child)))
				* Table depends on un-copied parents. Try to copy next table.
				select TempTableList
				loop
			endif
			lnNeedUpdate = Table_Needs_Update(lcTable + ".dbf", TEMPDIR, tcTargetDatabase)
			if lnNeedUpdate > 0
				? time(), "Table:", padr(lcTable,30, " ."), " "
			endif
			do case
			case lnNeedUpdate = 0 and not FORCEUPDATE	&& no update needed (OS-level copy)
				* ?? "Structure didn't change."
				wait window nowait "Erasing temporary table " + lcTable
				erase (TEMPDIR + lcTable + ".*")
			case lnNeedUpdate = 1 or (lnNeedUpdate = 0 and FORCEUPDATE)	&& need update
				if lnNeedUpdate = 1
					?? "There are changes. Transferring data."
				else
					?? "No changes. Forced update."
				endif
				wait window nowait "Updating table " + lcTable
				select 0
				use (TEMPDIR + lcTable)
				append from (tcTargetDatabase + lcTable)
				use
			case lnNeedUpdate = 2	&& new table
				?? "New table."
				* No additional action is required.
			endcase
			select TempRelations
			set order to "parent"
			delete for parent = padr(lcTable, len(parent))
			select TempTableList
			delete	&& table has been processed.
		endscan
	enddo

	set talk off
	? time(), "Moving to final destination."

	close database all

	erase TempTableList.*
	erase TempRelations.*

	* Move temp to target data
	* Moving is much faster than copying, if moving occurs on the same disk
	local lnFileCount
	local array laFiles(1,1)
	for lnFileCount = 1 to adir(laFiles, TEMPDIR + "*.*")
		erase (tcTargetDatabase + laFiles(lnFileCount, 1))
		rename (TEMPDIR + laFiles(lnFileCount, 1)) to (tcTargetDatabase + laFiles(lnFileCount, 1))
	next
	? time(), "Done."


	* Cleanup
	rd TEMPDIR
	set safety on
	wait clear
	?? chr(7)
ENDFUNC
Difference in opinions hath cost many millions of lives: for instance, whether flesh be bread, or bread be flesh; whether whistling be a vice or a virtue; whether it be better to kiss a post, or throw it into the fire... (from Gulliver's Travels)
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform