1+ <?php
2+ /**
3+ * Created by PhpStorm.
4+ * User: aguidet
5+ * Date: 28/02/15
6+ * Time: 17:32
7+ */
8+
9+ namespace Migrate \Command ;
10+
11+
12+ use Migrate \Migration ;
13+ use Migrate \Utils \ArrayUtil ;
14+ use Symfony \Component \Config \FileLocator ;
15+ use Symfony \Component \Console \Input \InputInterface ;
16+ use Symfony \Component \Console \Output \OutputInterface ;
17+ use Symfony \Component \Yaml \Yaml ;
18+
19+ class AbstractEnvCommand extends AbstractComand
20+ {
21+
22+ protected static $ progressBarFormat = '%current%/%max% [%bar%] %percent% % %memory% [%message%] ' ;
23+
24+ /**
25+ * @var \PDO
26+ */
27+ private $ db ;
28+
29+ /**
30+ * @var array
31+ */
32+ private $ config ;
33+
34+ /**
35+ * @return \PDO
36+ */
37+ public function getDb ()
38+ {
39+ return $ this ->db ;
40+ }
41+
42+ /**
43+ * @return array
44+ */
45+ public function getConfig ()
46+ {
47+ return $ this ->config ;
48+ }
49+
50+ public function getChangelogTable ()
51+ {
52+ return ArrayUtil::get ($ this ->getConfig (), 'changelog ' );
53+ }
54+
55+ protected function init (InputInterface $ input , OutputInterface $ output , $ env = null )
56+ {
57+ $ configDirectory = array (getcwd () . '/.php-database-migration/environments ' );
58+ $ locator = new FileLocator ($ configDirectory );
59+
60+ if ($ env == null ) {
61+ $ env = $ input ->getArgument ('env ' );
62+ }
63+
64+ $ envFile = $ locator ->locate ($ env . '.yml ' );
65+
66+ $ loader = new Yaml ();
67+ $ conf = $ loader ->parse ($ envFile );
68+
69+ $ this ->config = $ conf ;
70+
71+ $ driver = ArrayUtil::get ($ conf ['connection ' ], 'driver ' );
72+ $ port = ArrayUtil::get ($ conf ['connection ' ], 'port ' );
73+ $ host = ArrayUtil::get ($ conf ['connection ' ], 'host ' );
74+ $ dbname = ArrayUtil::get ($ conf ['connection ' ], 'database ' );
75+ $ username = ArrayUtil::get ($ conf ['connection ' ], 'username ' );
76+ $ password = ArrayUtil::get ($ conf ['connection ' ], 'password ' );
77+
78+ $ uri = $ driver ;
79+ $ uri .= ($ dbname == null ) ?: ":dbname= $ dbname " ;
80+ $ uri .= ($ host == null ) ?: ";host= $ host " ;
81+ $ uri .= ($ port == null ) ?: ";port= $ port " ;
82+
83+ $ this ->db = new \PDO (
84+ $ uri ,
85+ $ username ,
86+ $ password ,
87+ array ()
88+ );
89+
90+ $ output ->writeln ('<info>connected</info> ' );
91+ }
92+
93+ /**
94+ * @return array(Migration)
95+ */
96+ public function getLocalMigrations ()
97+ {
98+ $ fileList = scandir ($ this ->getMigrationDir ());
99+ $ fileList = ArrayUtil::filter ($ fileList );
100+
101+ foreach ($ fileList as $ file ) {
102+ $ migration = Migration::createFromFile ($ file , $ this ->getMigrationDir ());
103+ $ migrations [$ migration ->getId ()] = $ migration ;
104+ }
105+
106+ ksort ($ migrations );
107+
108+ return $ migrations ;
109+ }
110+
111+ /**
112+ * @return array(Migration)
113+ */
114+ public function getRemoteMigrations ()
115+ {
116+ $ migrations = array ();
117+ $ result = $ this ->getDb ()->query ("SELECT * FROM {$ this ->getChangelogTable ()} ORDER BY id " );
118+ if ($ result ) {
119+ foreach ($ result as $ row ) {
120+ $ migration = Migration::createFromRow ($ row , $ this ->getMigrationDir ());
121+ $ migrations [$ migration ->getId ()] = $ migration ;
122+ }
123+
124+ ksort ($ migrations );
125+ }
126+ return $ migrations ;
127+ }
128+
129+ /**
130+ * @return array(Migration)
131+ */
132+ public function getRemoteAndLocalMigrations ()
133+ {
134+ $ local = $ this ->getLocalMigrations ();
135+ $ remote = $ this ->getRemoteMigrations ();
136+
137+ foreach ($ remote as $ aRemote ) {
138+ $ local [$ aRemote ->getId ()] = $ aRemote ;
139+ }
140+
141+ ksort ($ local );
142+
143+ return $ local ;
144+ }
145+
146+ public function getToUpMigrations ()
147+ {
148+ $ locales = $ this ->getLocalMigrations ();
149+ $ remotes = $ this ->getRemoteMigrations ();
150+
151+ foreach ($ remotes as $ remote ) {
152+ unset($ locales [$ remote ->getId ()]);
153+ }
154+
155+ ksort ($ locales );
156+
157+ return $ locales ;
158+ }
159+
160+ public function getToDownMigrations ()
161+ {
162+ $ locales = $ this ->getLocalMigrations ();
163+ $ remotes = $ this ->getRemoteMigrations ();
164+
165+ ksort ($ remotes );
166+
167+ $ remotes = array_reverse ($ remotes , true );
168+
169+ return $ remotes ;
170+ }
171+
172+
173+ public function saveToChangelog (Migration $ migration )
174+ {
175+ $ appliedAt = date ('Y-m-d H:i:s ' );
176+ $ sql = "INSERT INTO {$ this ->getChangelogTable ()}
177+ (id, version, applied_at, description)
178+ VALUES
179+ ( {$ migration ->getId ()},' {$ migration ->getVersion ()}',' {$ appliedAt }',' {$ migration ->getDescription ()}');
180+ " ;
181+ $ result = $ this ->getDb ()->exec ($ sql );
182+
183+ if (! $ result ) {
184+ throw new \RuntimeException ("changelog table has not been initialized " );
185+ }
186+ }
187+
188+ public function removeFromChangelog (Migration $ migration )
189+ {
190+ $ sql = "DELETE FROM {$ this ->getChangelogTable ()} WHERE id = {$ migration ->getId ()}" ;
191+ $ result = $ this ->getDb ()->exec ($ sql );
192+ if (! $ result ) {
193+ throw new \RuntimeException ("Impossible to delete migration from changelog table " );
194+ }
195+ }
196+
197+ /**
198+ * @param Migration $migration
199+ */
200+ public function executeUpMigration (Migration $ migration )
201+ {
202+ $ this ->getDb ()->query ($ migration ->getSqlUp ());
203+ $ this ->saveToChangelog ($ migration );
204+ }
205+
206+ /**
207+ * @param Migration $migration
208+ */
209+ public function executeDownMigration (Migration $ migration )
210+ {
211+ $ this ->getDb ()->query ($ migration ->getSqlDown ());
212+ $ this ->removeFromChangelog ($ migration );
213+ }
214+
215+ protected function filterMigrationsToExecute (InputInterface $ input , OutputInterface $ output )
216+ {
217+
218+ $ down = false ;
219+
220+ $ toExecute = array ();
221+ if (strpos ($ this ->getName (), 'up ' ) > 0 ) {
222+ $ toExecute = $ this ->getToUpMigrations ();
223+ } else {
224+ $ down = true ;
225+ $ toExecute = $ this ->getToDownMigrations ();
226+ }
227+
228+ $ only = $ input ->getOption ('only ' );
229+ if ($ only != null ) {
230+ if (! array_key_exists ($ only , $ toExecute )) {
231+ throw new \RuntimeException ("Impossible to execute migration $ only! " );
232+ }
233+ $ theMigration = $ toExecute [$ only ];
234+ $ toExecute = array ($ theMigration ->getId () => $ theMigration );
235+ }
236+
237+ $ to = $ input ->getOption ('to ' );
238+ if ($ to != null ) {
239+ if (! array_key_exists ($ to , $ toExecute )) {
240+ throw new \RuntimeException ("Target migration $ to does not exists or has already been executed/downed! " );
241+ }
242+
243+ $ temp = $ toExecute ;
244+ $ toExecute = array ();
245+ foreach ($ temp as $ migration ) {
246+ $ toExecute [$ migration ->getId ()] = $ migration ;
247+ if ($ migration ->getId () == $ to ) {
248+ break ;
249+ }
250+ }
251+
252+ } else if ($ down && count ($ toExecute ) > 1 ) {
253+ // WARNING DOWN SPECIAL TREATMENT
254+ // we dont want all the database to be downed because
255+ // of a bad command!
256+ $ theMigration = array_shift ($ toExecute );
257+ $ toExecute = array ($ theMigration ->getId () => $ theMigration );
258+ }
259+
260+ return $ toExecute ;
261+ }
262+ }
0 commit comments