Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Two way database synching
Message
De
25/08/2017 04:56:12
 
 
À
23/08/2017 15:20:37
Information générale
Forum:
Visual FoxPro
Catégorie:
Base de données, Tables, Vues, Index et syntaxe SQL
Versions des environnements
Visual FoxPro:
VFP 9 SP2
OS:
Windows 7
Network:
SAMBA Server
Database:
MySQL
Application:
Desktop
Divers
Thread ID:
01652594
Message ID:
01653739
Vues:
60
Hi Koen,

Depends how you wanna test ;) -- you need the FoxInCloud Application Server; on some dev machine you can use the trial version, to test on a live server and/or get the source code, you need the full version.

client side:
you'll get a container that you can drop on a VFP form (wrapper around the sync class, see attached screenshot):
modify class atCntSync of at
you create a subclass of the sync class; attached is a sample sub-class.

you setup the properties of this container as documented

server side:
you need your FoxInCloud app server up and running.
in the config prog (xxxSets.prg), make sure to SET PATH to where your tables or database reside.
* ------------------------------------------------------------------------------
function ipDBCsync_test

AC()
local oSync as ipDBCsync of ipData.prg
oSync = CreateObject('ipDBCsync')
? m.oSync.DBCsyncDown()

* ==============================================================================
define class ipDBCsync as acDataSyncVFP of acData.prg && synchronisation base locale - base Web App
* ==============================================================================

* Connexion à Internet
nHTTPConnectType = 0	&& Mode de connexion à Internet [Selon InternetOpen() de WININET.DLL]
	&& 0 - Use IE connection and Proxy settings
	&& 1 - Direct 
	&& 3 - Proxy (connecting through a Proxy)
	&& 4 - Use IE connection and Proxy settings EXCEPT startup script execution
&& Si this.nHTTPConnectType = 3, régler les 4 propriétés suivantes:
cHTTPProxyName = Space(0) && Adresse du proxy
cHTTPProxyUserName = Space(0) && Nom d'utilisateur pour connexion via proxy
cHTTPProxyPassword = Space(0) && Mot de passe pour connexion via proxy
cHTTPProxyByPass = .NULL. && Host names or IP Addresses that should NOT be routed through the proxy server

* Connexion au site
cSite = 'void' && Nom du site
cSiteDomain = '' && Domaine ou adresse IP du site
lHTTPS = .F. && Connecter en mode sécurisé HTTPS
nHTTPPort = 80 && [80/443 selon lHTTPS] Port HTTP /!\ Régler APRÈS this.lHTTPS
nTimeOut = 20 && Secondes d'attente avant que le site réponde

* Base de données
cDBCdest = '' && Adresse de la base de données destination

&& modify command awServer!awProcess.TableGet_lUser()/awProcess.TableSyncUp_lUser()
cUserIDfield = 'cEMAIL' && champ identifiant dans la table des utilisateurs && 'cEMAIL' est le standard Zenbuyer
 cUserIDvalue = '' && valeur de l'identifiant utilisateur 
cUserPWfield = 'cPW' && champ mot de passe dans la table des utilisateurs && 'cPW' est le standard Zenbuyer
 cUserPWvalue = '' && valeur du mot de passe utilisateur

* Méthodes du site
cScript = 'ip' && Adresse de la dll ou scriptmap équivalent
cErrorHeader = '/!\' && Mention en tête du résultat retourné par le site en cas d'erreur
cTimeStampMethod = 'TableTimeStamp' && méthode du site qui retourne la date et heure de dernière modification d'une table && pour IT

* Local
cFolderTemp = Addbs(Sys(2023)) && Adresse du dossier où les tables temporaires sont stockées
cTablesIgnore = Space(0) && tables à ignorer (cf. this.DBCsync())

* Résultat d'exécution
lResultXML = .F. && Demander au site de retourner le résultat d'exécution sous forme XML représentant l'objet oResult

*-------------------------------------------------
protected procedure TableSyncUp_Rec && {en} Record of a table sent to site for synchronization {fr} Enregistrement d'une table envoyé au site pour synchronisation
lparameters ;
	tcTable; && {en} Table name
, toRecord && {en} Record object obtained by scatter name loRecord memo

&& {en} Alias() = cursor holding the records to be synchronized - same structure as (tcTable)
&& {fr} Alias() = cursor des enregistrements à synchronizer - structure identique à (tcTable)

&& {en} Implement invoice pdf upload when server is hosted outside STI

&& {en} return .F. to ignore files in record
&& {fr} return .F. ignore les fichiers de l'enregistrement
endproc

*-------------------------------------------------
protected function TableSyncUp_lFile && {en} A File mentioned in a table should be sent to client {fr} Un fichier dans une table doit être envoyé au client
lparameters ;
  tcFile;
, tcTable; && Upper()
, tcField; && Upper()

return .T.;
 and InList(Upper(m.tcTable), Upper('carrier'), Upper('company'), Upper('division'));
 and InList(Upper(m.tcField), Upper('Logo'), Upper('LogoName'));
 and .T.

*-------------------------------------------------
protected function TableSyncDown_lFile && {en} A File mentioned in a table should be downloaded and saved {fr} Un fichier mentionné dans une table doit être téléchargé et sauvegardé
lparameters ;
  tcFile;
, tcTable; && Upper()
, tcField; && Upper()

return this.TableSyncUp_lFile(; && same rule
	  m.tcFile;
	, m.tcTable;
	, m.tcField;
	)

*-------------------------------------------------
protected function TableSyncUp_File_cPath && Addresse complète d'un fichier à envoyer au site
lparameters tcFile

return ForcePath(m.tcFile, FullPath(ICase(;
	Directory('Graphics'),;
		'Graphics',;
	Directory('..\Graphics'),;
		'..\Graphics',;
		'';
	)))

*-------------------------------------------------
protected function TableSyncDown_File_cPath && Adresse où ranger un fichier téléchargé depuis le site
LPARAMETERS tcFile && NOM du fichier

return this.TableSyncUp_File_cPath(m.tcFile)

*-------------------------------------------------
protected function  TableSyncUp_File_cType && Type d'un fichier à envoyer au site pour savoir où le ranger
LPARAMETERS tcFile

return 'Graphics'

*---------------------------------------
protected procedure DBCSync_Table_Ante && méthode shell avant synchronisation
lparameters ;
  tlUp; && [.F.] {fr} Synchronisation montante
, tcTable; && {fr} Table sur le point d'être synchronisée
, tuFieldsIgnore; && @ {fr} Ignorer si ces champs de la table destination sont absents de la table source ; .T.: aucune vérification de structure
, tlReplace; && @ {fr} Remplacer toute la table destination
, tlCKmatch; && @ {fr} Matcher les enregistrements sur la première clé candidate de la table destination
, tlPKreplace; && @ [.F.] {fr} Si m.tlCKmatch et clé primaire différente, remplacer && 2016-12-13 thn -- {FiC V 2.23.0-beta.8} {en} added

tlCKmatch = m.tlCKmatch or !m.tlUp and Upper(m.tcTable) == Upper('glCode')
tlPKreplace = m.tlCKmatch

endproc

*---------------------------------------
PROTECTED PROCEDURE DBCsync_Table_Post && méthode shell après synchronisation
lparameters ;
	tlUp,; &&[.F.] Synchronisation montante
	tcTable,; && Table qui vient d'être synchronisée
	toResult && Résultat de la synchronisation

if Type('thisForm') == 'O'
	thisForm.log(m.this.cResult, !m.this.lResult)
endif

return DoDefault(m.tlUp, m.tcTable, m.toResult)

* ==============================================================================
enddefine && class ipDBCsync
* ==============================================================================
>Thierry,
>OK sounds good. How should I proceed to test this?
>Regards,
>Koen
>
>>Sure, you can pair the synchronized DBs the way you want; eg.:
>>- central = web app
>>- central = subsidiary 1
>>etc.
>>
>>subsidiary 1 will get web app changes after sync into central.
>>
>>>Hi Thierry,
>>>
>>>I am in for a synch class which synchronizes tables with the centraldatabase not behind a Web Application just on a central server, suppose that would be possible with FiC?
>>>
>>>Regards,
>>>
>>>Koen
>>>
>>>>Hi Dennis,
>>>>
>>>>FoxInCloud includes a synchronization class that does all your requirements, including support of
>>>>- deleted records
>>>>- sync set of tables or full database (top-down using relations)
>>>>- 2-ways or either way
>>>>- rollback in case of an error
>>>>- comprehensive log including records where sync failed
>>>>- various other settings
>>>>- you can sub-class for whatever extension you see fit
>>>>
>>>>Conditions:
>>>>- 'central' database is behind a Web Application
>>>>- each table has a primary or candidate key and 2 normalized fields: 'last update' and 'updated by sync'
>>>>- batch execution, not real time: each 'client' runs a program periodically (can be every minute)
>>>>
>>>>In production since 2009.
>>>>
>>>>>Hi Guys,
>>>>>
>>>>>Basically, I am doing a POS app which will be used by a handful of branches and one head office. All will be connected via internet.
>>>>>
>>>>>We would like for the following to be implemented:
>>>>>
>>>>>1. Whenever head office say creates, deletes or modifies a new product, it will be propagated to the Products table of each branch.
>>>>>
>>>>>2. Conversely, branch sales data feeds are pushed to the head office.
>>>>>
>>>>>3. In the event that internet connection fails during this "synching", how does one know where "we left off" to continue?
>>>>>
>>>>>Thank you very much in advance for all your efforts!
>>>>>
>>>>>Long live the Fox!
Thierry Nivelet
FoxinCloud
Give your VFP application a second life, web-based, in YOUR cloud
http://foxincloud.com/
Never explain, never complain (Queen Elizabeth II)
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform