Et si on parlait un peu système…

Introduction

On parle souvent des frameworks, APIs, librairies JavaScript, etc… mais très peu souvent de la partie “back” d’une application. Par là, j’entends serveur, base de données sur lesquels va tourner une application… Et quelquefois (souvent même je dirai), il faut mettre la main à la pâte pour pouvoir faire fonctionner tout ça car ce n’est pas forcément à l’ “administrateur système” ou à l’ “équipe production” de gérer entièrement cela et/ou auquel il faut déléguer cette partie très importante, sur laquelle repose et vit une application ! J’ajouterai même que c’est une étape incontournable lorsqu’on “touche” sérieusement à une application (que ça soit la création ou la maintenance (T.M.A.) de celle-ci).

Par contre, le choix du système d’exploitation et/ou du système de gestion de base de données (plus communément appelé S.G.B.D.) sur lesquels va s’appuyer le serveur et la B.D.D. est assez souvent imposé. Pourquoi ? Tout simplement car d’autres applications du parc de l’entreprise (petite ou grosse) pour laquelle on travaille utilisent déjà un S.G.B.D et un O.S particuliers…

 

Allez c’est parti !

Dans cette partie, je vais donc aborder le sujet de l’export/import d’une B.D.D., tâche qui peut être amenée à se répéter régulièrement lorsqu’on veut mettre à jour son environnement de recette et/ou de développement par rapport aux données de l’environnement de production.

Pour ma part, c’est un S.G.B.D. Oracle et un Windows Server  sur lesquels je me suis appuyé ! Dans la suite de cet article, je vais donc vous montrer comment j’ai pu mettre en place un “script” complet et paramétrable (adaptable assez facilement).

Vous aurez donc certainement deviné que j’ai utilisé un langage de base : le batch (programmation MS-DOS (fichier d’extension .bat)) ! Certes il y a quelques notions de base à avoir mais l’appréhension et la compréhension de ce langage se font très rapidement et très facilement. De plus, il existe des tonnes et des tonnes de sites Web qui en parle…

J’en entends déjà certains dire “Ah mais on pourrait utiliser d’autres langages (Perl, Python, C (Why not !), etc…), des APIs, etc…” ! Oui je pourrai être d’accord avec eux mais ici le but était de réaliser un script fonctionnel rapidement et qui soit simple d’utilisation et d’adaptation (pas besoin d’installer tel ou tel trucs pour faire fonctionner le programme, juste régler et adapter quelques petits paramètres) ! En gros, ce script n’a pas de vocation internationale, juste réaliser ce qu’il faut et rien de plus !

 

Pour commencer, j’ai d’abord mis en place l’arborescence du projet :

Arborescence du programme

Arborescence du programme

Voici quelques explications sur les différents éléments que l’on voit :

  • le dossier bin contient les différents scripts nécessaires à l’import, la suppression et l’export d’une B.D.D..
  • le dossier config contient le script qui contient les paramètres que l’on peut modifier suivant la configuration que l’on veut mettre en place.
  • le dossier dump va contenir le fichier d’export de la B.D.D.
  • le fichier export_import.bat est le fichier principale qui permet de lancer le programme ! Il contient également quelques paramètres modifiables.
  • le dossier logs va contenir tout l’historique de la dernière exécution du programme.
  • le fichier README.txt se passe de commentaires…
  • le dossier sql contient les différents scripts SQL (dont un généré et qui est paramétrable) qui vont permettre de supprimer les données de la B.D.D dans laquelle on va importer des données fraîchement acquises.

 

Décomposons ensuite petit à petit chaque contenu des dossiers et fichiers qui sont énumérés ci-dessus.

 

On va donc commencer par le dossier bin :

Contenu du dossier bin

Contenu du dossier bin

Comme dit précédemment et comme vous pouvez le voir, celui-ci contient 3 fichiers qui effectuent respectivement : la suppression des données dans la B.D.D destinataire, l’export des données de la B.D.D. source et l’import de ces dernières dans la B.D.D. destinataire ! Rien de plus compliqué à part qu’ils utilisent des commandes MS-DOS spécifiques à Oracle

  • DropOracleServerTo.bat
1
2
3
4
5
6
7
8
9
SET DB_HOSTNAME=BDD2_HOST
SET SERVICE_NAME=BDD2_SERVICE
SET DBMS_SCHEMA=BDD2_SCHEMA
SET DBMS_PASSWORD=BDD2_PWD

SET DROP_FILE=%1
SET LOG_FILE=%2

sqlplus -L %DBMS_SCHEMA%/%DBMS_PASSWORD%@//%DB_HOSTNAME%/%SERVICE_NAME% @%DROP_FILE% >> %LOG_FILE%
  • ExportOracleServerFrom.bat
1
2
3
4
5
6
7
8
9
10
11
12
13
SET NLS_LANG=American_america.utf8

SET ORACLE_USER_LOGIN=BDD1_SCHEMA
SET ORACLE_USER_PASSWORD=BDD1_PWD
SET ORACLE_EZCONNECT=//BDD1_HOST:BDD1_PORT/BDD1_SERVICE

SET DUMP_FILE=%1
SET LOG_FILE=%2

exp userid=%ORACLE_USER_LOGIN%/%ORACLE_USER_PASSWORD%@%ORACLE_EZCONNECT% ^
file=%DUMP_FILE% ^
log=%LOG_FILE% ^
statistics=none
  • ImportOracleServerTo.bat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SET NLS_LANG=American_america.utf8

SET ORACLE_SRC_USER=BDD1_SCHEMA

SET ORACLE_USER_LOGIN=BDD2_SCHEMA
SET ORACLE_USER_PASSWORD=BDD2_PWD
SET ORACLE_EZCONNECT=//BDD2_HOST:BDD2_PORT/BDD2_SERVICE

SET DUMP_FILE=%1
SET LOG_FILE=%2

imp userid=%ORACLE_USER_LOGIN%/%ORACLE_USER_PASSWORD%@%ORACLE_EZCONNECT% ^
file=%DUMP_FILE% ^
FROMUSER=%ORACLE_SRC_USER% ^
TOUSER=%ORACLE_USER_LOGIN% ^
log=%LOG_FILE% ^
ignore=y

Je ne vais pas m’attarder à expliquer ce que fait chaque script mais vous pouvez déjà avoir un aperçu de ce que ça donne dans mon cas d’utilisation (avec les bonnes valeurs qu’il faut bien sûr :-))! Et comme vous pouvez le voir également, le batch n’est pas un langage compliqué et ressemble sensiblement au bash !

 

Pour ce qui est du dossier config, il contient en tout et pour tout un fichier de configuration et de vérifications de paramètres :

  • config.bat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
SET ErrorLevel=0

REM <---------------------------
REM : LOG INFO
SET FROM=Server From
SET TO=Server To
REM --------------------------->

REM <---------------------------
REM : DIRECTORIES
SET BIN_DIRECTORY=%CURRENT_DIRECTORY%bin
REM SET SQL_DIRECTORY=%CURRENT_DIRECTORY%\sql
REM SET DUMP_DIRECTORY=%CURRENT_DIRECTORY%\dump
REM SET LOGS_DIRECTORY=%CURRENT_DIRECTORY%\logs

if not exist %BIN_DIRECTORY% (
echo %DATE% %TIME% [ERROR] : Le dossier %BIN_DIRECTORY% n'existe pas !
echo %DATE% %TIME% [ERROR] : Le dossier %BIN_DIRECTORY% n'
existe pas ! >> %ERROR_FILE%
SET ErrorLevel=9
goto :eof
)

echo %BIN_DIRECTORY%
REM echo %SQL_DIRECTORY%
REM echo %DUMP_DIRECTORY%
REM echo %LOGS_DIRECTORY%
REM --------------------------->

REM <---------------------------
REM : BATCH
SET EXPORT_FILE=%BIN_DIRECTORY%\ExportOracleServerTo.bat
SET IMPORT_FILE=%BIN_DIRECTORY%\ImportOracleServerTo.bat
SET DROP_FILE=%BIN_DIRECTORY%\DropOracleServerFrom.bat

echo %EXPORT_FILE%
echo %IMPORT_FILE%
echo %DROP_FILE%
REM --------------------------->

REM <---------------------------
REM : SQL SCRIPT
set SELECT_DROP_FILE_SQL=%SQL_DIRECTORY%\SELECT_DROP.sql

echo %SELECT_DROP_FILE_SQL%
REM --------------------------->

REM <---------------------------
REM : DATE AND TIME
if "%TIME:~0,1%" == " " (
SET HOUR=0%TIME:~1,1%
) else (
SET HOUR=%TIME:~0,2%
)
SET CURRENT_DATE=%DATE:~7,2%-%DATE:~4,2%-%DATE:~10,4%
SET BEGIN_DATE_AND_TIME=%CURRENT_DATE%_%HOUR%-%TIME:~3,2%

echo %CURRENT_DATE%
echo %BEGIN_DATE_AND_TIME%
REM --------------------------->

REM <---------------------------
REM : LOGS FILES
SET LOGS_FILE=%LOGS_DIRECTORY%\logs_%BEGIN_DATE_AND_TIME%.log

SET EXPORT_LOG_FILE=%LOGS_DIRECTORY%\ExportOracle_%BEGIN_DATE_AND_TIME%.log
SET IMPORT_LOG_FILE=%LOGS_DIRECTORY%\ImportOracle_%BEGIN_DATE_AND_TIME%.log
SET DROP_LOG_FILE=%LOGS_DIRECTORY%\DropOracle_%BEGIN_DATE_AND_TIME%.log

echo %LOGS_FILE%
echo %EXPORT_LOG_FILE%
echo %IMPORT_LOG_FILE%
echo %DROP_LOG_FILE%
REM --------------------------->

REM <---------------------------
REM : DUMP FILE
SET DUMP_FILE=%DUMP_DIRECTORY%\dump_%BEGIN_DATE_AND_TIME%.dmp

echo %DUMP_FILE%
REM --------------------------->

Celui-ci a donc pour but de vérifier que les dossiers et fichiers nécessaires à la bonne exécution du programme sont présents. Il définit aussi quelques variables communes à d’autres scripts ! Et pour info, la commande “REM” permet de commenter une ligne (pas vraiment visible ici).

 

Je passe maintenant directement au fichier principal export_import.bat :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
@echo off

REM PAUSE

REM <---------------------------
REM : TO BE DEFINED FOR THE environment
REM SET CURRENT_DIRECTORY="DISK:\PATH"
SET CURRENT_DIRECTORY=%~dp0
SET ERROR_FILE=%CURRENT_DIRECTORY%ERROR.log

SET CONFIG_DIRECTORY=%CURRENT_DIRECTORY%config
if not exist %CONFIG_DIRECTORY% (
echo %DATE% %TIME% [ERROR] : Le dossier %CONFIG_DIRECTORY% n'existe pas !
echo %DATE% %TIME% [ERROR] : Le dossier %CONFIG_DIRECTORY% n'
existe pas ! >> %ERROR_FILE%
goto :eof
)

SET CONFIG_FILE=%CONFIG_DIRECTORY%\config.bat

echo %CURRENT_DIRECTORY%
echo %CONFIG_DIRECTORY%
echo %CONFIG_FILE%
REM --------------------------->

REM <---------------------------
REM : logs, dump, sql DIRECTORIES
SET LOGS_DIRECTORY=%CURRENT_DIRECTORY%logs
SET DUMP_DIRECTORY=%CURRENT_DIRECTORY%dump
SET SQL_DIRECTORY=%CURRENT_DIRECTORY%sql

if not exist %SQL_DIRECTORY% (
echo %DATE% %TIME% [ERROR] : Le dossier %SQL_DIRECTORY% n'existe pas !
echo %DATE% %TIME% [ERROR] : Le dossier %SQL_DIRECTORY% n'
existe pas ! >> %ERROR_FILE%
goto :eof
)

echo %LOGS_DIRECTORY%
echo %DUMP_DIRECTORY%
echo %SQL_DIRECTORY%
REM --------------------------->

REM <---------------------------
REM : DROP.sql FILE
SET DROP_FILE_SQL=%SQL_DIRECTORY%\DROP.sql

echo %DROP_FILE_SQL%
REM --------------------------->
REM <---------------------------
REM :
echo %DATE% %TIME% : [INFO] Suppression du dossier de logs...
rmdir /S /Q %LOGS_DIRECTORY%

echo %DATE% %TIME% : [INFO] Creation du dossier de logs.
mkdir %LOGS_DIRECTORY%

echo %DATE% %TIME% : [INFO] Suppression du dossier de dump...
rmdir /S /Q %DUMP_DIRECTORY%

echo %DATE% %TIME% : [INFO] Creation du dossier de dump.
mkdir %DUMP_DIRECTORY%

echo %DATE% %TIME% : [INFO] Suppression du fichier SQL genere '%DROP_FILE_SQL%'...
del %DROP_FILE_SQL%
REM --------------------------->

 

echo %DATE% %TIME% : [INFO] Initialisation du script...
call %CONFIG_FILE%

if %ErrorLevel% == 9 (
echo %DATE% %TIME% [ERROR] : Erreur dans l'initialisation du script.
echo %DATE% %TIME% [ERROR] : Erreur dans l'
initialisation du script. >> %ERROR_FILE%
goto :eof
)

echo %CURRENT_DATE% %TIME% : [INFO] Initialisation du script OK. >> %LOGS_FILE%

echo %CURRENT_DATE% %TIME% : [INFO] Suppression du dossier de logs OK. >> %LOGS_FILE%
echo %CURRENT_DATE% %TIME% : [INFO] Creation du dossier de logs OK. >> %LOGS_FILE%

echo %CURRENT_DATE% %TIME% : [INFO] Suppression du dossier de dump OK. >> %LOGS_FILE%
echo %CURRENT_DATE% %TIME% : [INFO] Creation du dossier de dump OK. >> %LOGS_FILE%

echo %CURRENT_DATE% %TIME% : [INFO] Suppression du fichier SQL genere %DROP_FILE_SQL% OK. >> %LOGS_FILE%

REM PAUSE

 

REM for the next...
REM - 0 = Success
REM - 1 = Not Supported
REM - 2 = Access Denied
REM - 3 = Dependent Services Running
REM - 4 = Invalid Service Control
REM - 5 = Service Cannot Accept Control
REM - 6 = Service Not Active
REM - 7 = Service Request Timeout
REM - 8 = Unknown Failure
REM - 9 = Path Not Found
REM - 10 = Service Already Running
REM - 11 = Service Database Locked
REM - 12 = Service Dependency Deleted
REM - 13 = Service Dependency Failure
REM - 14 = Service Disabled
REM - 15 = Service Logon Failure
REM - 16 = Service Marked For Deletion
REM - 17 = Service No Thread
REM - 18 = Status Circular Dependency
REM - 19 = Status Duplicate Name
REM - 20 = Status Invalid Name
REM - 21 = Status Invalid Parameter
REM - 22 = Status Invalid Service Account
REM - 23 = Status Service Exists
REM - 24 = Service Already Paused

 

echo %CURRENT_DATE% %TIME% : [INFO] Debut.
echo %CURRENT_DATE% %TIME% : [INFO] Debut. >> %LOGS_FILE%
echo %CURRENT_DATE% %TIME% : [INFO] Export de la BDD "%FROM%".
echo %CURRENT_DATE% %TIME% : [INFO] Export de la BDD "%FROM%". >> %LOGS_FILE%
REM 2 params : bat + log files
call %EXPORT_FILE% %DUMP_FILE% %EXPORT_LOG_FILE%
if NOT %ErrorLevel% == 0 (
REM 3 -> WARNING
if NOT %ErrorLevel% == 3 (
echo %CURRENT_DATE% %TIME% : [ERROR] ErrorLevel : %ErrorLevel%.
echo %CURRENT_DATE% %TIME% : [ERROR] ErrorLevel : %ErrorLevel%. >> %LOGS_FILE%
echo %CURRENT_DATE% %TIME% : [ERROR] Export de la BDD "%FROM%" : KO.
echo %CURRENT_DATE% %TIME% : [ERROR] Export de la BDD "%FROM%" : KO. >> %LOGS_FILE%

goto :ERROR
)
)
echo %CURRENT_DATE% %TIME% : [INFO] Export de la BDD "%FROM%" : OK.
echo %CURRENT_DATE% %TIME% : [INFO] Export de la BDD "%FROM%" : OK. >> %LOGS_FILE%

 

REM PAUSE

 

echo %CURRENT_DATE% %TIME% : [INFO] Suppression de la BDD "%TO%".
echo %CURRENT_DATE% %TIME% : [INFO] Suppression de la BDD "%TO%". >> %LOGS_FILE%
REM 2 params : sql + log files
call %DROP_FILE% %SELECT_DROP_FILE_SQL% %DROP_LOG_FILE%
if NOT %ErrorLevel% == 0 (
REM 3 -> WARNING
if NOT %ErrorLevel% == 3 (
echo %CURRENT_DATE% %TIME% : [ERROR] ErrorLevel : %ErrorLevel%.
echo %CURRENT_DATE% %TIME% : [ERROR] ErrorLevel : %ErrorLevel%. >> %LOGS_FILE%
echo %CURRENT_DATE% %TIME% : [ERROR] Suppression de la BDD "%TO%" : KO.
echo %CURRENT_DATE% %TIME% : [ERROR] Suppression de la BDD "%TO%" : KO. >> %LOGS_FILE%

goto :ERROR
)
)
echo %CURRENT_DATE% %TIME% : [INFO] Suppression de la BDD "%TO%" : OK.
echo %CURRENT_DATE% %TIME% : [INFO] Suppression de la BDD "%TO%" : OK. >> %LOGS_FILE%

 

REM PAUSE

 

echo %CURRENT_DATE% %TIME% : [INFO] Import de la BDD "%FROM%" vers "%TO%".
echo %CURRENT_DATE% %TIME% : [INFO] Import de la BDD "%FROM%" vers "%TO%". >> %LOGS_FILE%
REM 2 params : bat + log files
call %IMPORT_FILE% %DUMP_FILE% %IMPORT_LOG_FILE%
if NOT %ErrorLevel% == 0 (
REM 3 -> WARNING
if NOT %ErrorLevel% == 3 (
echo %CURRENT_DATE% %TIME% : [ERROR] ErrorLevel : %ErrorLevel%.
echo %CURRENT_DATE% %TIME% : [ERROR] ErrorLevel : %ErrorLevel%. >> %LOGS_FILE%
echo %CURRENT_DATE% %TIME% : [ERROR] Import de la BDD "%FROM%" vers "%TO%" : KO.
echo %CURRENT_DATE% %TIME% : [ERROR] Import de la BDD "%FROM%" vers "%TO%" : KO. >> %LOGS_FILE%

goto :ERROR
)
)
echo %CURRENT_DATE% %TIME% : [INFO] Import de la BDD "%FROM%" vers "%TO%" : OK.
echo %CURRENT_DATE% %TIME% : [INFO] Import de la BDD "%FROM%" vers "%TO%" : OK. >> %LOGS_FILE%

goto :END

 

:ERROR
echo %CURRENT_DATE% %TIME% : [ERROR] Le script ne s'est pas termine correctement...
echo %CURRENT_DATE% %TIME% : [INFO] Le script ne s'
est pas termine correctement... >> %LOGS_FILE%
:END
echo %CURRENT_DATE% %TIME% : [INFO] Fin.
echo %CURRENT_DATE% %TIME% : [INFO] Fin. >> %LOGS_FILE%

Ce fichier dirige toutes les actions que l’on veut effectuer : appel aux différents scripts de suppression, d’import et d’export, historisation de ce qui s’est passé, etc… Il gère également l’exécution multiple du programme (nettoyage des dossiers logsdump et sql) et procède également à quelques vérifications, comme le fichier config.bat précédemment décrit.

 

Enfin, on va terminer par le dossier sql qui contient un fichier de base SELECT_DROP.sql et un fichier généré DROP.sql après l’exécution du script :

  • SELECT_DROP.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
SET echo OFF
SET termout OFF
SET feedback OFF
SET heading OFF
SET pages 0
SET LINES 0
SET pagesize 0
SET pause OFF
SET colsep ';'

-- TO BE DEFINED FOR THE environment (cf. line 34 too)
spool '%DROP_FILE_SQL%'

SELECT 'DROP TABLE ' || USER || '.' || TABLE_NAME || ' CASCADE CONSTRAINTS;'
FROM USER_TABLES;

SELECT 'DROP SEQUENCE ' || USER || '.' || SEQUENCE_NAME || ';'
FROM USER_SEQUENCES;

SELECT 'DROP PROCEDURE ' || USER || '.' || OBJECT_NAME || ';'
FROM USER_PROCEDURES
WHERE object_type ='PROCEDURE';

SELECT 'DROP VIEW ' || USER || '.' || VIEW_NAME || ' CASCADE CONSTRAINTS;'
FROM user_views;

spool OFF

SET termout ON
SET feedback ON
SET heading ON
SET pause ON

@'%DROP_FILE_SQL%'

exit

Je l’ai déjà dit mais je le répète, certaines actions présentes dans le code ci-dessus sont spécifiques à Oracle. Pour ce qui est de la compréhension de ce script SQL, il permet de choisir les types que l’on veut supprimer (tables, séquences, procédures, vues, …) et d’extraire ainsi que de  formater dans un autre fichier SQL  (vous comprenez pourquoi il y a un fichier généré ;-)) le code permettant d’exécuter ladite suppression. Un exemple vaut mieux qu’un long discours :

1
2
3
4
5
6
7
8
9
10
11
12
13
DROP TABLE nom_du_schema.nom_de_la_table CASCADE CONSTRAINTS;

...

DROP PROCEDURE nom_du_schema.nom_de_la_procedure;

...

DROP VIEW nom_du_schema.nom_de_la_vue CASCADE CONSTRAINTS;

...

DROP SEQUENCE nom_du_schema.nom_de_la_sequence;

 

Conclusion

Certes, la mise en place de ce programme prend un peu de temps du fait du langage et de ses quelques subtilités, mais au final vous êtes largement gagnant côté temps et performances ! En effet, au lieu de faire toutes les actions précédentes “à la main” :-(, c’est-à-dire :

  • Exécuter un script  qui va exporter les données de la B.D.D. source.
  • Supprimer les données de la B.D.D. destinataire via un outil (DbVisualizer dans mon cas) ou via un script (comme décrit précédemment).
  • Exécuter un dernier script qui va importer les nouvelles données dans la B.D.D destinataire.

Cela prend un certain temps quand même et demande votre présence pour faire les différentes actions…

De plus vous pouvez programmer ce script dans une tâche planifiée (ce que j’ai fait personnellement) pour qu’il s’exécute quand vous le voulez (tous les jours, une fois par semaine, juste du lundi au vendredi, une fois par mois, …).

Ce script est encore optimisable et pourrait même contenir quelques fonctionnalités en plus comme compter le nombre de lignes en plus (ou en moins) pour chaque table, etc…

Si vous avez des questions ou des remarques, n’hésitez pas !

VN:R_U [1.9.22_1171]
Rating: +2 (from 2 votes)
Share
Ce contenu a été publié dans Outils, Trucs & astuces, avec comme mot(s)-clef(s) , , , . Vous pouvez le mettre en favoris avec ce permalien.

Laisser un commentaire