@@ -4006,8 +4006,31 @@ public function updateTable(string $tableName, /* object */ $changes): bool
40064006 return true ;
40074007 }
40084008
4009+ public function updateColumnSqlite (string $ tableName , string $ columnName , /* object */ $ changes ): bool
4010+ {
4011+ $ table = $ this ->reflection ->getTable ($ tableName );
4012+ $ column = $ table ->getColumn ($ columnName );
4013+
4014+ // remove constraints on other column
4015+ $ newColumn = ReflectedColumn::fromJson ((object ) array_merge ((array ) $ column ->jsonSerialize (), (array ) $ changes ));
4016+ $ columns = [];
4017+ foreach ($ table ->getColumnNames () as $ name ) {
4018+ if ($ name == $ columnName ) {
4019+ $ columns [] = $ newColumn ;
4020+ } else {
4021+ $ columns [] = $ table ->getColumn ($ name );
4022+ }
4023+ }
4024+ $ newTable = new ReflectedTable ($ table ->getName (), $ table ->getType (), $ columns );
4025+ return $ this ->db ->definition ()->updateColumnsSqlite ($ newTable );
4026+ }
4027+
40094028 public function updateColumn (string $ tableName , string $ columnName , /* object */ $ changes ): bool
40104029 {
4030+ if ($ this ->db ->getDriver () == 'sqlite ' ) {
4031+ return $ this ->updateColumnSqlite ($ tableName , $ columnName , $ changes );
4032+ }
4033+
40114034 $ table = $ this ->reflection ->getTable ($ tableName );
40124035 $ column = $ table ->getColumn ($ columnName );
40134036
@@ -4045,7 +4068,8 @@ public function updateColumn(string $tableName, string $columnName, /* object */
40454068 return false ;
40464069 }
40474070 }
4048- if ($ newColumn ->getType () != $ column ->getType () ||
4071+ if (
4072+ $ newColumn ->getType () != $ column ->getType () ||
40494073 $ newColumn ->getLength () != $ column ->getLength () ||
40504074 $ newColumn ->getPrecision () != $ column ->getPrecision () ||
40514075 $ newColumn ->getScale () != $ column ->getScale ()
@@ -5270,6 +5294,11 @@ class GenericDB
52705294 private $ columns ;
52715295 private $ converter ;
52725296
5297+ public function getDriver (): string
5298+ {
5299+ return $ this ->driver ;
5300+ }
5301+
52735302 private function getDsn (): string
52745303 {
52755304 switch ($ this ->driver ) {
@@ -5302,6 +5331,7 @@ private function getCommands(): array
53025331 case 'sqlite ' :
53035332 return [
53045333 'PRAGMA foreign_keys = on; ' ,
5334+ 'PRAGMA writable_schema = on; ' ,
53055335 ];
53065336 }
53075337 }
@@ -5661,6 +5691,8 @@ private function getColumnAutoIncrement(ReflectedColumn $column, bool $update):
56615691 case 'pgsql ' :
56625692 case 'sqlsrv ' :
56635693 return '' ;
5694+ case 'sqlite ' :
5695+ return $ column ->getPk () ? ' AUTOINCREMENT ' : '' ;
56645696 }
56655697 }
56665698
@@ -5684,6 +5716,8 @@ private function getTableRenameSQL(string $tableName, string $newTableName): str
56845716 return "ALTER TABLE $ p1 RENAME TO $ p2 " ;
56855717 case 'sqlsrv ' :
56865718 return "EXEC sp_rename $ p1, $ p2 " ;
5719+ case 'sqlite ' :
5720+ return "ALTER TABLE $ p1 RENAME TO $ p2 " ;
56875721 }
56885722 }
56895723
@@ -5702,6 +5736,8 @@ private function getColumnRenameSQL(string $tableName, string $columnName, Refle
57025736 case 'sqlsrv ' :
57035737 $ p4 = $ this ->quote ($ tableName . '. ' . $ columnName );
57045738 return "EXEC sp_rename $ p4, $ p3, 'COLUMN' " ;
5739+ case 'sqlite ' :
5740+ return "ALTER TABLE $ p1 RENAME COLUMN $ p2 TO $ p3 " ;
57055741 }
57065742 }
57075743
@@ -5860,12 +5896,22 @@ private function getAddTableSQL(ReflectedTable $newTable): string
58605896 $ f4 = $ this ->quote ($ newColumn ->getFk ());
58615897 $ f5 = $ this ->quote ($ this ->getPrimaryKey ($ newColumn ->getFk ()));
58625898 $ f6 = $ this ->quote ($ tableName . '_ ' . $ pkColumn . '_pkey ' );
5863- $ fields [] = "$ f1 $ f2 " ;
5864- if ($ newColumn ->getPk ()) {
5865- $ constraints [] = "CONSTRAINT $ f6 PRIMARY KEY ( $ f1) " ;
5866- }
5867- if ($ newColumn ->getFk ()) {
5868- $ constraints [] = "CONSTRAINT $ f3 FOREIGN KEY ( $ f1) REFERENCES $ f4 ( $ f5) " ;
5899+ if ($ this ->driver == 'sqlite ' ) {
5900+ if ($ newColumn ->getPk ()) {
5901+ $ f2 = str_replace ('NULL ' , 'NULL PRIMARY KEY ' , $ f2 );
5902+ }
5903+ $ fields [] = "$ f1 $ f2 " ;
5904+ if ($ newColumn ->getFk ()) {
5905+ $ constraints [] = "FOREIGN KEY ( $ f1) REFERENCES $ f4 ( $ f5) " ;
5906+ }
5907+ } else {
5908+ $ fields [] = "$ f1 $ f2 " ;
5909+ if ($ newColumn ->getPk ()) {
5910+ $ constraints [] = "CONSTRAINT $ f6 PRIMARY KEY ( $ f1) " ;
5911+ }
5912+ if ($ newColumn ->getFk ()) {
5913+ $ constraints [] = "CONSTRAINT $ f3 FOREIGN KEY ( $ f1) REFERENCES $ f4 ( $ f5) " ;
5914+ }
58695915 }
58705916 }
58715917 $ p2 = implode (', ' , array_merge ($ fields , $ constraints ));
@@ -5885,6 +5931,8 @@ private function getAddColumnSQL(string $tableName, ReflectedColumn $newColumn):
58855931 return "ALTER TABLE $ p1 ADD COLUMN $ p2 $ p3 " ;
58865932 case 'sqlsrv ' :
58875933 return "ALTER TABLE $ p1 ADD $ p2 $ p3 " ;
5934+ case 'sqlite ' :
5935+ return "ALTER TABLE $ p1 ADD COLUMN $ p2 $ p3 " ;
58885936 }
58895937 }
58905938
@@ -5898,6 +5946,8 @@ private function getRemoveTableSQL(string $tableName): string
58985946 return "DROP TABLE $ p1 CASCADE; " ;
58995947 case 'sqlsrv ' :
59005948 return "DROP TABLE $ p1; " ;
5949+ case 'sqlite ' :
5950+ return "DROP TABLE $ p1; " ;
59015951 }
59025952 }
59035953
@@ -5912,44 +5962,56 @@ private function getRemoveColumnSQL(string $tableName, string $columnName): stri
59125962 return "ALTER TABLE $ p1 DROP COLUMN $ p2 CASCADE; " ;
59135963 case 'sqlsrv ' :
59145964 return "ALTER TABLE $ p1 DROP COLUMN $ p2; " ;
5965+ case 'sqlite ' :
5966+ return "ALTER TABLE $ p1 DROP COLUMN $ p2; " ;
59155967 }
59165968 }
59175969
59185970 public function renameTable (string $ tableName , string $ newTableName )
59195971 {
59205972 $ sql = $ this ->getTableRenameSQL ($ tableName , $ newTableName );
5921- return $ this ->query ($ sql );
5973+ return $ this ->query ($ sql, [] );
59225974 }
59235975
59245976 public function renameColumn (string $ tableName , string $ columnName , ReflectedColumn $ newColumn )
59255977 {
59265978 $ sql = $ this ->getColumnRenameSQL ($ tableName , $ columnName , $ newColumn );
5927- return $ this ->query ($ sql );
5979+ return $ this ->query ($ sql , []);
5980+ }
5981+
5982+ public function updateColumnsSqlite (ReflectedTable $ table )
5983+ {
5984+ $ create = $ this ->getAddTableSQL ($ table );
5985+ $ name = $ table ->getName ();
5986+ $ sql = "UPDATE SQLITE_MASTER SET SQL = ? WHERE NAME = ?; " ;
5987+ $ result = $ this ->query ($ sql , [$ create , $ name ]);
5988+ $ this ->query ('VACUUM; ' , []);
5989+ return $ result ;
59285990 }
59295991
59305992 public function retypeColumn (string $ tableName , string $ columnName , ReflectedColumn $ newColumn )
59315993 {
59325994 $ sql = $ this ->getColumnRetypeSQL ($ tableName , $ columnName , $ newColumn );
5933- return $ this ->query ($ sql );
5995+ return $ this ->query ($ sql, [] );
59345996 }
59355997
59365998 public function setColumnNullable (string $ tableName , string $ columnName , ReflectedColumn $ newColumn )
59375999 {
59386000 $ sql = $ this ->getSetColumnNullableSQL ($ tableName , $ columnName , $ newColumn );
5939- return $ this ->query ($ sql );
6001+ return $ this ->query ($ sql, [] );
59406002 }
59416003
59426004 public function addColumnPrimaryKey (string $ tableName , string $ columnName , ReflectedColumn $ newColumn )
59436005 {
59446006 $ sql = $ this ->getSetColumnPkConstraintSQL ($ tableName , $ columnName , $ newColumn );
5945- $ this ->query ($ sql );
6007+ $ this ->query ($ sql, [] );
59466008 if ($ this ->canAutoIncrement ($ newColumn )) {
59476009 $ sql = $ this ->getSetColumnPkSequenceSQL ($ tableName , $ columnName , $ newColumn );
5948- $ this ->query ($ sql );
6010+ $ this ->query ($ sql, [] );
59496011 $ sql = $ this ->getSetColumnPkSequenceStartSQL ($ tableName , $ columnName , $ newColumn );
5950- $ this ->query ($ sql );
6012+ $ this ->query ($ sql, [] );
59516013 $ sql = $ this ->getSetColumnPkDefaultSQL ($ tableName , $ columnName , $ newColumn );
5952- $ this ->query ($ sql );
6014+ $ this ->query ($ sql, [] );
59536015 }
59546016 return true ;
59556017 }
@@ -5958,56 +6020,56 @@ public function removeColumnPrimaryKey(string $tableName, string $columnName, Re
59586020 {
59596021 if ($ this ->canAutoIncrement ($ newColumn )) {
59606022 $ sql = $ this ->getSetColumnPkDefaultSQL ($ tableName , $ columnName , $ newColumn );
5961- $ this ->query ($ sql );
6023+ $ this ->query ($ sql, [] );
59626024 $ sql = $ this ->getSetColumnPkSequenceSQL ($ tableName , $ columnName , $ newColumn );
5963- $ this ->query ($ sql );
6025+ $ this ->query ($ sql, [] );
59646026 }
59656027 $ sql = $ this ->getSetColumnPkConstraintSQL ($ tableName , $ columnName , $ newColumn );
5966- $ this ->query ($ sql );
6028+ $ this ->query ($ sql, [] );
59676029 return true ;
59686030 }
59696031
59706032 public function addColumnForeignKey (string $ tableName , string $ columnName , ReflectedColumn $ newColumn )
59716033 {
59726034 $ sql = $ this ->getAddColumnFkConstraintSQL ($ tableName , $ columnName , $ newColumn );
5973- return $ this ->query ($ sql );
6035+ return $ this ->query ($ sql, [] );
59746036 }
59756037
59766038 public function removeColumnForeignKey (string $ tableName , string $ columnName , ReflectedColumn $ newColumn )
59776039 {
59786040 $ sql = $ this ->getRemoveColumnFkConstraintSQL ($ tableName , $ columnName , $ newColumn );
5979- return $ this ->query ($ sql );
6041+ return $ this ->query ($ sql, [] );
59806042 }
59816043
59826044 public function addTable (ReflectedTable $ newTable )
59836045 {
59846046 $ sql = $ this ->getAddTableSQL ($ newTable );
5985- return $ this ->query ($ sql );
6047+ return $ this ->query ($ sql, [] );
59866048 }
59876049
59886050 public function addColumn (string $ tableName , ReflectedColumn $ newColumn )
59896051 {
59906052 $ sql = $ this ->getAddColumnSQL ($ tableName , $ newColumn );
5991- return $ this ->query ($ sql );
6053+ return $ this ->query ($ sql, [] );
59926054 }
59936055
59946056 public function removeTable (string $ tableName )
59956057 {
59966058 $ sql = $ this ->getRemoveTableSQL ($ tableName );
5997- return $ this ->query ($ sql );
6059+ return $ this ->query ($ sql, [] );
59986060 }
59996061
60006062 public function removeColumn (string $ tableName , string $ columnName )
60016063 {
60026064 $ sql = $ this ->getRemoveColumnSQL ($ tableName , $ columnName );
6003- return $ this ->query ($ sql );
6065+ return $ this ->query ($ sql, [] );
60046066 }
60056067
6006- private function query (string $ sql ): bool
6068+ private function query (string $ sql, array $ arguments ): bool
60076069 {
60086070 $ stmt = $ this ->pdo ->prepare ($ sql );
6009- //echo "- $sql -- [] \n";
6010- return $ stmt ->execute ();
6071+ //echo "- $sql -- " . json_encode($arguments) . " \n";
6072+ return $ stmt ->execute ($ arguments );
60116073 }
60126074 }
60136075}
@@ -6034,7 +6096,7 @@ public function __construct(LazyPdo $pdo, string $driver, string $database, arra
60346096 $ this ->typeConverter = new TypeConverter ($ driver );
60356097 }
60366098
6037- private function createSqlLiteReflectionTables () /*: void */
6099+ private function updateSqlLiteReflectionTables () /*: void */
60386100 {
60396101 $ reflection = $ this ->query ('SELECT "name" FROM "sqlite_master" WHERE "type" = \'table \' and name like \'sys/% \'; ' , []);
60406102 if (count ($ reflection ) == 0 ) {
@@ -6103,7 +6165,7 @@ private function getTablesSQL(): string
61036165 case 'sqlsrv ' :
61046166 return 'SELECT o.name as "TABLE_NAME", o.xtype as "TABLE_TYPE" FROM sysobjects o WHERE o.xtype IN ( \'U \', \'V \') ORDER BY "TABLE_NAME" ' ;
61056167 case 'sqlite ' :
6106- $ this ->createSqlLiteReflectionTables ();
6168+ $ this ->updateSqlLiteReflectionTables ();
61076169 return 'SELECT t.name as "TABLE_NAME", t.type as "TABLE_TYPE" FROM "sys/tables" t WHERE t.type IN ( \'table \', \'view \') AND \'\' <> ? ORDER BY "TABLE_NAME" ' ;
61086170 }
61096171 }
@@ -6118,6 +6180,7 @@ private function getTableColumnsSQL(): string
61186180 case 'sqlsrv ' :
61196181 return 'SELECT c.name AS "COLUMN_NAME", c.is_nullable AS "IS_NULLABLE", t.Name AS "DATA_TYPE", (c.max_length/2) AS "CHARACTER_MAXIMUM_LENGTH", c.precision AS "NUMERIC_PRECISION", c.scale AS "NUMERIC_SCALE", \'\' AS "COLUMN_TYPE" FROM sys.columns c INNER JOIN sys.types t ON c.user_type_id = t.user_type_id WHERE c.object_id = OBJECT_ID(?) AND \'\' <> ? ' ;
61206182 case 'sqlite ' :
6183+ $ this ->updateSqlLiteReflectionTables ();
61216184 return 'SELECT "name" AS "COLUMN_NAME", case when "notnull"==1 then \'no \' else \'yes \' end as "IS_NULLABLE", "type" AS "DATA_TYPE", 2147483647 AS "CHARACTER_MAXIMUM_LENGTH", 0 AS "NUMERIC_PRECISION", 0 AS "NUMERIC_SCALE", \'\' AS "COLUMN_TYPE" FROM "sys/columns" WHERE "self" = ? AND \'\' <> ? ' ;
61226185 }
61236186 }
0 commit comments