Bug 384820

Summary: Allow matching library paths across different operating systems?
Product: [Applications] digikam Reporter: Hampton <k4kfh.radio>
Component: Database-MysqlAssignee: Digikam Developers <digikam-bugs-null>
Status: RESOLVED FIXED    
Severity: normal CC: caulier.gilles, metzpinguin, nrv9999, spam-receiver
Priority: NOR    
Version: 5.7.0   
Target Milestone: ---   
Platform: unspecified   
OS: All   
Latest Commit: Version Fixed In: 8.0.0
Sentry Crash Report:
Attachments: multiOSAlbumRoots.patch

Description Hampton 2017-09-18 17:47:38 UTC
I think a really powerful way to set up Digikam would be with a centralized MySQL server, that way many networked machines could use Digikam with a common photo library (on a NAS or something) without having to maintain a separate Digikam DB on each box.

I tried to set this up and everything worked except one thing: the library paths. If you're just using Windows and you map a network drive (to Z:\ for example) then Digikam will associate your SQL database with the Z:\Whatever\Path\You\Set\Initially regardless of what PC you're on. This is fine on Windows but the second you bring a Mac or Linux PC into the equation, it makes the database useless. Digikam won't let you say "this database goes with this folder on my local machine" or anything, it just tries to find Z:\Whatever and of course fails on a Nix system.

Any chance we could add this as a feature? A simple dialog box in the SQL settings window that's like "Associated Library Path Override" would suffice, then you just set up your DB and fix the path on each machine. Even if it's experimental I would be happy to test it out and give feedback, and when it's working I would probably write a guide for a multi-PC digiKam setup if you guys would like.
Comment 1 Nurullin Rustem 2018-12-31 16:41:42 UTC
I also get this bug.. unrealised functionality.
If you add collection from one machine, and add that collection (with such name) from another, digikam understand this as 2 different collection and scan twice (also metadata will not synchronize if it not stored in EXIF).

Looking at db structure, I see that collections identifier is full path, that different on Windows and Linux, it can be different on two Windows machines.
But presents column "specificPath".

I do next thing:

MariaDB [digikam]> select * from AlbumRoots;
+----+-------+--------+------+------------------------------------+-----------------------------------------------------------+
| id | label | status | type | identifier                         | specificPath                                              |
+----+-------+--------+------+------------------------------------+-----------------------------------------------------------+
|  8 | disc  |      0 |    3 | networkshareid:?mountpath=Pictures | //bananapi/disc/                                          |
|  9 | disc  |      0 |    3 | networkshareid:?mountpath=Pictures | /run/user/1000/gvfs/smb-share:server=bananapi,share=disc/ |
+----+-------+--------+------+------------------------------------+---------------------------------------------------

So identifiers are same. I hoped, that digikam will concat it (specificPath + mountpath). It didn't. It not see my collection.
Comment 2 Maik Qualmann 2018-12-31 22:52:31 UTC
Created attachment 117218 [details]
multiOSAlbumRoots.patch

This patch solves the problem. The database columns "identifier" and "specificPath" become a string list. A new path can be defined under the respective operating system with the new collection update function. It would be nice if someone could test the patch.

Maik
Comment 3 caulier.gilles 2019-01-02 10:33:09 UTC
Maik,

How you patch preserve the compatibility with previous collections recorded in database. A migration is done after to apply the patch and run digiKam ?

Gilles
Comment 4 Maik Qualmann 2019-01-02 18:39:57 UTC
Yes, the function has no problems with existing "old" entries. But I will update the patch again.

Maik
Comment 5 caulier.gilles 2022-01-10 11:27:15 UTC
Hi Maik,

what's the plan for this patch ?

Gilles
Comment 6 Maik Qualmann 2022-07-15 10:55:59 UTC
*** Bug 456749 has been marked as a duplicate of this bug. ***
Comment 7 Maik Qualmann 2022-07-15 11:08:38 UTC
Comment on attachment 117218 [details]
multiOSAlbumRoots.patch

>diff --git a/core/libs/database/coredb/coredb.cpp b/core/libs/database/coredb/coredb.cpp
>index 227a1ce63c..153c4125ec 100644
>--- a/core/libs/database/coredb/coredb.cpp
>+++ b/core/libs/database/coredb/coredb.cpp
>@@ -53,6 +53,7 @@ extern "C"
> 
> // Local includes
> 
>+#include "digikam_config.h"
> #include "digikam_debug.h"
> #include "coredbbackend.h"
> #include "collectionmanager.h"
>@@ -61,6 +62,14 @@ extern "C"
> #include "tagscache.h"
> #include "album.h"
> 
>+#ifdef Q_OS_WIN
>+    static const char* DK_CURRENT_OS = "WIN:";
>+#elif defined Q_OS_OSX
>+    static const char* DK_CURRENT_OS = "OSX:";
>+#else
>+    static const char* DK_CURRENT_OS = "LNX:";
>+#endif
>+
> namespace Digikam
> {
> 
>@@ -191,9 +200,9 @@ QList<AlbumRootInfo> CoreDB::getAlbumRoots()
>         ++it;
>         info.type         = (AlbumRoot::Type)(*it).toInt();
>         ++it;
>-        info.identifier   = (*it).toString();
>+        info.identifier   = decodeOSString((*it).toString());
>         ++it;
>-        info.specificPath = (*it).toString();
>+        info.specificPath = decodeOSString((*it).toString());
>         ++it;
> 
>         list << info;
>@@ -205,9 +214,14 @@ QList<AlbumRootInfo> CoreDB::getAlbumRoots()
> int CoreDB::addAlbumRoot(AlbumRoot::Type type, const QString& identifier, const QString& specificPath, const QString& label)
> {
>     QVariant id;
>+    QString osIdentifier   = identifier;
>+    QString osSpecificPath = specificPath;
>+    osIdentifier.prepend(QLatin1String(DK_CURRENT_OS));
>+    osSpecificPath.prepend(QLatin1String(DK_CURRENT_OS));
>+
>     d->db->execSql(QString::fromUtf8("REPLACE INTO AlbumRoots (type, label, status, identifier, specificPath) "
>                                      "VALUES(?, ?, 0, ?, ?);"),
>-                   (int)type, label, identifier, specificPath, 0, &id);
>+                   (int)type, label, osIdentifier, osSpecificPath, 0, &id);
> 
>     d->db->recordChangeset(AlbumRootChangeset(id.toInt(), AlbumRootChangeset::Added));
>     return id.toInt();
>@@ -230,8 +244,14 @@ void CoreDB::deleteAlbumRoot(int rootId)
> 
> void CoreDB::migrateAlbumRoot(int rootId, const QString& identifier)
> {
>+    QList<QVariant> values;
>+
>+    d->db->execSql(QString::fromUtf8("SELECT identifier FROM AlbumRoots "
>+                                     "WHERE id=?;"),
>+                   rootId, &values);
>+
>     d->db->execSql(QString::fromUtf8("UPDATE AlbumRoots SET identifier=? WHERE id=?;"),
>-                   identifier, rootId);
>+                   encodeOSString(values, identifier), rootId);
>     d->db->recordChangeset(AlbumRootChangeset(rootId, AlbumRootChangeset::PropertiesChanged));
> }
> 
>@@ -251,8 +271,14 @@ void CoreDB::changeAlbumRootType(int rootId, AlbumRoot::Type newType)
> 
> void CoreDB::setAlbumRootPath(int rootId, const QString& newPath)
> {
>+    QList<QVariant> values;
>+
>+    d->db->execSql(QString::fromUtf8("SELECT specificPath FROM AlbumRoots "
>+                                     "WHERE id=?;"),
>+                   rootId, &values);
>+
>     d->db->execSql(QString::fromUtf8("UPDATE AlbumRoots SET specificPath=? WHERE id=?;"),
>-                   newPath, rootId);
>+                   encodeOSString(values, newPath), rootId);
>     d->db->recordChangeset(AlbumRootChangeset(rootId, AlbumRootChangeset::PropertiesChanged));
> }
> 
>@@ -5029,4 +5055,49 @@ void CoreDB::writeSettings()
>     group.writeEntry(d->configRecentlyUsedTags, d->recentlyAssignedTags);
> }
> 
>+QString CoreDB::decodeOSString(const QString& str)
>+{
>+    QStringList list = str.split(QLatin1Char(';'));
>+    QString osString = str;
>+
>+    foreach (const QString& s, list)
>+    {
>+        if (s.startsWith(QLatin1String(DK_CURRENT_OS)))
>+        {
>+            osString = s.mid(4);
>+            break;
>+        }
>+    }
>+
>+    return osString;
>+}
>+
>+QString CoreDB::encodeOSString(const QList<QVariant>& values, const QString& str)
>+{
>+    QString osString;
>+
>+    if (values.size() == 1)
>+    {
>+        QStringList list = values.first().toString().split(QLatin1Char(';'));
>+
>+        foreach (const QString& s, list)
>+        {
>+            if (s.startsWith(QLatin1String(DK_CURRENT_OS)) || s == str)
>+            {
>+                continue;
>+            }
>+
>+            osString.append(s).append(QLatin1Char(';'));
>+        }
>+
>+        osString.append(QLatin1String(DK_CURRENT_OS)).append(str);
>+    }
>+    else
>+    {
>+        osString = str;
>+    }
>+
>+    return osString;
>+}
>+
> } // namespace Digikam
>diff --git a/core/libs/database/coredb/coredb.h b/core/libs/database/coredb/coredb.h
>index ad507f9b11..c8cd498759 100644
>--- a/core/libs/database/coredb/coredb.h
>+++ b/core/libs/database/coredb/coredb.h
>@@ -1392,6 +1392,9 @@ private:
>     void readSettings();
>     void writeSettings();
> 
>+    QString decodeOSString(const QString& str);
>+    QString encodeOSString(const QList<QVariant>& values, const QString& str);
>+
> private:
> 
>     class Private;
Comment 8 Maik Qualmann 2022-07-16 15:16:23 UTC
Git commit 6a630aeab30849225015826aa185cc8a8516cc74 by Maik Qualmann.
Committed on 16/07/2022 at 15:14.
Pushed by mqualmann into branch 'master'.

add support for alternate network paths in the collection view
Related: bug 456749
FIXED-IN: 8.0.0

M  +3    -1    NEWS
M  +4    -0    core/libs/database/collection/collectionlocation.h
M  +6    -3    core/libs/database/collection/collectionmanager.h
M  +5    -3    core/libs/database/collection/collectionmanager_location.cpp
M  +7    -2    core/libs/database/collection/collectionmanager_p.cpp
M  +2    -3    core/libs/database/collection/collectionmanager_p.h
M  +206  -17   core/utilities/setup/collections/setupcollectionview.cpp
M  +21   -8    core/utilities/setup/collections/setupcollectionview.h

https://invent.kde.org/graphics/digikam/commit/6a630aeab30849225015826aa185cc8a8516cc74