Joomla: On extension update: Change table schema (remove column) - joomla

I have developed a Joomla extension and in the newest version the need to delete one column from a table belonging to my plugin has arisen.
As far as I know there is no easy way to delete a column in Mysql only if it exists. Therefore, the only possibility I see at the moment to achieve that, would be to use custom php upgrade code, as shown here.
But this problem would seem so common to me, that I would suspect to be an easier solution?
Is there maybe an easy way (provided through Joomla) to execute a schema change only when updating from a particular extension version?

Check Managing Component Updates with Joomla; starting with Joomla 1.6 there is a defined way to execute specific SQL instructions for an upgrade from one version to another. Basically, for each version an SQL file has to be created (even if it's empty or only contains comments) in a specific file structure. The linked article explains the details.

Related

Update database on different environments in Joomla3.9 project

We are working on Joomla3.9 project, have different environments and are using git as vcs. So every developer works on is own branch. It would be nice to have a database compare function like in TYPO3 or Contao (see the database differences after updating the project and apply the database changes just by one click). Or like the laravel migration system.
Any developer should easily update his own lokal database after database changes where made due an extension update via backend or by another developer. And of course the staging or live system must be updated easily too. We don't want to execute sql-scripts with the changes in phpMyAdmin.
We have tried https://dbv.vizuina.com/ . This is not the 100% solution. Like there is no cli support to start the migration process by an update script on the server.
Does anyone have a solution or knows an extension that can solve this problem? Or can this be handled with core Joomla functions (maybe with a little adjustment)?
So far, I've seen three possibilities to execute modifications to one ore many extension tables
1: Use the extension - revision control in the schema table. So add a new sql-file with an increased version number compared to the version number in the schema-table for this extension. Increase also the version in the manifest.xml and zip the extension again.
Reinstall the extension via extension->manage->install. So the new sql-file with the increased version number will be executed.
2: like the point above, but install the extension via joomla update mechanism (update server).
3.: create a new sql-file in sql/folder of the extension. No version name is needed for the new file, just update.sql oder another filename. Execute this script in script.php in update()-method, after the extension is installed (in this case it's an update) again.
The third possibility might be interesting. It should be possible to trigger the update()-method with a cli command / function, so that the method can be triggered via a script on the server.
But how can I get the info, which update-scripts have already been executed? Let's say I have 3 update files in sql-folder. update-1.sql, update-2.sql and update-3.sql.
update-1.sql has already been executed. So I don't want to execute this sql-file again - only the other two.
The schema-table is only used with the first two options. Do I have the info somewhere or must I manage the infos which update-scripts have been executed myself?
The answer related to versioning database for extensions depends on whether these extensions are tightly coupled to the application or need to be reusable to other applications also.
The latter case normally means that each extension accesses its own custom tables, in which case you should keep separate versioning for the database than for the extensions.
App version history can be kept in a db_version table. Then an insert statement is added at the end of each update script (adding an incremental version number). e.g.
insert into db_version(version,author,description) values(003,'Verna.Collins', 'removing obsolete column');
Provided that you need to apply data migration on extensions also, you need to maintain a db_version_extensions table which keeps version history for each of the extensions separately. e.g.
'001' 'extension1','Mandy.Aguilar','initial version'
'002' 'extension1','Mandy.Aguilar','adding extra column'
'001' 'extension2','Edna.Potter','initial version'
'002' 'extension2','Elvira.Townsend','dropping unused table'
..etc
Each extension zip should keep initial creation script and all sql-update files(which should normally not interfere with the rest of the app tables).
After pull it will be relatively easy to execute all the scripts with filename version greater than the last version number written in the database. This should be done for the app and for each extension separately.
Now if the extensions are tightly coupled to the app, it means that they might be using/updating tables of the app. For extensions of this type, you can add the updates as part of the application updates. These extensions could even be developed at the same repo, and be kept as directories instead of zip files.
Not sure if joomla supports any tools for automating the process of performing incremental db updates, but a nice tool is flyway, with ports for command-line, maven and graddle. See: how does flyway work

Is it possible to restore a core Joomla Component

I accidentally uninstalled the newsfeed component from my Joomla install. This apparently breaks the database integrity a little and I want to reinstall. I was able to do that at least partially using the "Discover" feature, but there are still a few issues. I get this with a database check:
Table 'sds_newsfeeds' should not have column 'filename'. (From file 3.0.0.sql.)
Table 'sds_newsfeeds' does not have column 'description'. (From file 3.0.0.sql.)
Table 'sds_newsfeeds' does not have column 'version'. (From file 3.0.0.sql.)
Table 'sds_newsfeeds' does not have column 'hits'. (From file 3.0.0.sql.)
Table 'sds_newsfeeds' does not have column 'images'. (From file 3.0.0.sql.)
The component name is com_newsfeed, and the localizations are not set:
e.g.: COM_NEWSFEEDS_FIELD_SHOW_FEED_IMAGE_LABEL is not defined.
Just wondering if I simply need to edit something minor to get it to work again.
Probably could just disable it for that site since I am not using it, and maybe when I update to a newer version of Joomla it'll fix itself ?
/sds
If you're not using it then don't bother - it'll take you an hour or so to resolve this completely and you won't even use it. I suggest your re-uninstall it again.
A Joomla update will most likely not get it back (just so you know).
I personally think it's a good idea to uninstall extensions (even core extensions) that are not being used.

How to update a Filenet document's content without changing the version?

I am trying to change document content and save the changes into current version itself without increment the document version number using filenet java API.
Any one help me on this topic.
Changing content always leads to the creation of a new version. It is not possible to directly accomplish what you want.
If you need the version number intact, delete the current version and save the changes. Then create a new version.
As fnt said, the main goal of an ECM platform is to guarantee that a version content stays unchanged. The only thing doable, is to update as much times as you need the content of the checked out version (reservation). That can be useful for a Save (without CheckIn scenario). Don't know if that is useful to you. If not, you need to delete/re-create a new version to keep the same version number.
Delete, make changes to the document and recreate the same with updated content is the only solution.

debian recover fail from postinst script

I'm a little stuck in a postinst file for Ubuntu.
The problem is when upgrading the package. I have some sqlite databases (marked as config files to save them from upgrades) in which I want to modify in a specific version (add some columns). As only I want to modify the database when installing an specific version (for example from version 3 or older to 4) I check if $2 is not null.
The approach to make the database upgrading is as follows:
first I make a backup of the databases
make new table
Then I alter the tables
copy the rows from the old table to the new one
The problem is if something goes wrong, the database already will be modified but the package will be at the new version (the four) with config version at 3. If I want to try install again the package in order to get the package ok, the postinst will fail because the database was already modified.
One thing that came to my mind was unset -e, but I find this very unpleasant.
I've searched in the documentation about how to revert fails from postinst, such as if it's called another script with different arguments, but in the documentation Debian says nothing useful.
Maybe the postinst script is not the best place to modify databases?
Thanks
Best regards
One thing you could do is check if the field already exists on the table, and alter in that case.
That is not dependent on if this is an upgrade or not.
Like this for example:
if sqlite3 /collection.db '.schema media' | grep -q 'new_field text' ; then
echo field already exists, continuing
else
sqlite3 /collection.db 'alter table media add column new_field text'
fi
Also, I would recommend the database schema to be manipulated by the application, and not dpkg.
Imagine that the user might restore a backup from an older version and "break" your software.
It should be clear to the user that the database of older versions is incompatible with the newer version.
I would recommend you to search the internet for help in creating a "migration plan".
Basically that means that you keep track of what "version" the database is and apply sequentially the database modifications when needed, in a way that is very similar to how a patch works.

Propel and build.properties file

Whenever I run propel-gen on a clean database (no tables defined), it generates errors because it first tries to DROP a table (Which doesnt currently exist) before creating it.
Is there any properties I can change to fix this?
So far I've found this:
http://www.propelorm.org/ticket/732
But it would be nice to do something like "DROP TABLE IF EXISTS name"
I faced the same problem some months ago but couldn't find more than the trac ticket (you will find, as well, that I have commented it :-)).
Maybe try to apply Elan Ruusamäe's patch if you find this bug very annoying...
If I have enough time/motivation, I may write a patch too (to make Propel issue a CREATE TABLE IF NOT EXISTS for DBMS supporting it) and hopefully the fix will be scheduled for one of the next versions.

Resources