Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

SQL Script to get Object's File System Path?
PaulR
#1 Posted : Friday, 27 August 2010 6:01:20 PM(UTC)
Rank: Member

Joined: 30/06/2009(UTC)
Posts: 5
Location: Sydney, Australia

I have just started looking at the SQLIte database for a Gallery Server Pro installation.

My question is:

- Does anyone have a SQL scipt to get the "relative file system directory" of a MediaOject?


BACKGROUND

The objective I have was to be able to extract:
- Object Title
- OriginalFileName
- Directory on web server of the original image.

I am wanting to use this to run some reports from time to time about what titles have changed since a certain date.


MY FINDINGS

I understand that I can get the base Original File Directory from:
- galleryserverpro.config property: mediaObjectPath

Looking a the database, I was happy to find the tables gs_mediaobject and gs_album. I ran the following queries (excuse the lack of indenting from the forum post):

select
MediaObjectID,
FKAlbumId,
Title,
OriginalFileName,
DateLastModified
from
gs_mediaobject
;

select
AlbumID,
AlbumParentID,
DirectoryName
from
gs_Album
;

Naturally, I then found that the full, relative "file system" path is not stored explicitly in the database.

Hence, before I put my brain and SQL knowledge to the test, does anyone have a SQL script that does this?
(Or have some pointers for suqueries that recurse up FKAlbumID and AlbumID?)
Roger Martin
#2 Posted : Saturday, 28 August 2010 4:37:27 AM(UTC)
Roger Martin

Rank: Administration

Joined: 3/08/2007(UTC)
Posts: 3,301
Location: Fort Atkinson, WI

You are on the right track. I don't have the perfect sample script for you, but I dug up a couple things that might help.

Here is a stored procedure for SQL Server that - given an album - recursively finds all child album IDs:

Code:
CREATE PROCEDURE {schema}[{objectQualifier}gs_Role_AlbumSelectAllAlbumsByRoleName]
(    @RoleName nvarchar(256), @GalleryId int )

AS
SET NOCOUNT ON

/* Retrieve all the album IDs that are affected by the specified role name. The album IDs that are stored in
the gs_Role_Album table only hold the highest ranking album ID. */

/* If the role is applied to the root album, then we can just return all albums in the gallery. This is
much cheaper than drilling down by album. */
DECLARE @RootAlbumId int
SELECT @RootAlbumId = AlbumId FROM {schema}[{objectQualifier}gs_Album] WHERE AlbumParentId = 0 AND FKGalleryId = @GalleryId

IF EXISTS (SELECT * FROM {schema}[{objectQualifier}gs_Role_Album] WHERE FKRoleName = @RoleName AND FKAlbumId = @RootAlbumId)
BEGIN
    SELECT AlbumId FROM {schema}[{objectQualifier}gs_Album] WHERE FKGalleryId = @GalleryId
END
ELSE
BEGIN
    /* The role applies to an album or albums below the root album, so we need to drill down and retrieve all
the children. Start by creating a temporary table to hold our data. */
    DECLARE @AlbumList table
        (AlbumId int not null,
        AlbumParentId int not null,
        AlbumDepth int not null)

    /* Insert the top level album IDs. */
    INSERT @AlbumList (AlbumId, AlbumParentId, AlbumDepth)
    SELECT FKAlbumId, 0, 1
    FROM {schema}[{objectQualifier}gs_Role_Album] ra INNER JOIN {schema}[{objectQualifier}gs_Album] a ON ra.FKAlbumId = a.AlbumId
    WHERE (ra.FKRoleName = @RoleName) AND (a.FKGalleryId = @GalleryId)

    /* Continue drilling down, level by level, until we reach a level where there are no more child albums. */
    WHILE (@@rowcount > 0) BEGIN
        INSERT @AlbumList (AlbumId, AlbumParentId, AlbumDepth)
        SELECT a.AlbumId, a.AlbumParentId, al.AlbumDepth + 1
        FROM {schema}[{objectQualifier}gs_Album] a JOIN @AlbumList al ON a.AlbumParentId = al.AlbumId
        WHERE al.AlbumDepth = (SELECT MAX(AlbumDepth) FROM @AlbumList)
    END

    /* Retrieve the list of album IDs. */
    SELECT AlbumId
    FROM @AlbumList
END

RETURN


And here is the equivalent SQLite code, but it is a mixture of C# and SQL because I couldn't figure out how to do the while thing in SQL:

Code:
private static IDataReader GetDataReaderRoleAllAlbums(string roleName)
{
    // Retrieve all the album IDs that are affected by the specified role name. The album IDs that are stored in
    // the gs_Role_Album table only hold the highest ranking album ID. If the role is applied to the root album,
    // then we can just return all albums in the gallery. If not, we need to drill down and retrieve all
    // the children. Follow these basic steps:
    // 1. Find out if the role applies to the root album. If it does, return all album ID's for the current gallery.
    // Otherwise, continue with next step.
    // 2. Create a temporary table to hold our working set of data.
    // 3. Insert the top level album IDs.
    // 4. Continue drilling down, level by level, until we reach a level where there are no more child albums.
    // 5. Retrieve the list of album IDs from the temporary table.
    DbTransaction tran = null;
    SQLiteConnection cn = GetDBConnectionForGallery();
    try
    {
        if (cn.State == ConnectionState.Closed)
            cn.Open();

        if (!IsTransactionInProgress())
            tran = cn.BeginTransaction();

        int galleryId = ConfigManager.GetGalleryServerProConfigSection().Core.GalleryId;

        using (SQLiteCommand cmd = cn.CreateCommand())
        {
            string sql = "SELECT EXISTS (SELECT * FROM gs_Role_Album ra INNER JOIN gs_Album a ON ra.FKAlbumId = a.AlbumId WHERE (a.AlbumParentId = 0) AND (ra.FKRoleName = @RoleName ) AND (a.FKGalleryId = @GalleryId))";
            cmd.CommandText = sql;
            cmd.Parameters.AddWithValue("@RoleName", roleName);
            cmd.Parameters.AddWithValue("@GalleryId", galleryId);

            bool roleAffectsAllAlbums = Convert.ToBoolean(cmd.ExecuteScalar());

            if (roleAffectsAllAlbums)
            {
                // The role affects all albums, so we can just get a list of all albums rather than drill down album by album.
                sql = "SELECT AlbumId FROM gs_Album WHERE FKGalleryId = @GalleryId";
                cmd.Parameters.Clear();
                cmd.CommandText = sql;
                cmd.Parameters.AddWithValue("@GalleryId", galleryId);

                if (IsTransactionInProgress())
                    return cmd.ExecuteReader();
                else
                {
                    // Commit the transaction if it's the one we created in this method.
                    if (tran != null)
                        tran.Commit();
                    return cmd.ExecuteReader(CommandBehavior.CloseConnection);
                }
            }
            else
            {
                // The role applies to an album or albums below the root album, so we need to drill down and retrieve all
                // the children. Start by creating a temporary table to hold our data.
                string tempTableName = "tmp" + Guid.NewGuid().ToString().Replace("-", String.Empty);
                sql = String.Format(@"
CREATE TEMP TABLE {0} (
[AlbumId] INTEGER NOT NULL,
[AlbumParentId] INTEGER NOT NULL,
[AlbumDepth] INTEGER NOT NULL);

INSERT INTO {0} (AlbumId, AlbumParentId, AlbumDepth)
SELECT FKAlbumId, 0, 1
FROM gs_Role_Album INNER JOIN gs_Album ON gs_Role_Album.FKAlbumId = gs_Album.AlbumId
WHERE (gs_Role_Album.FKRoleName = @RoleName) AND (gs_Album.FKGalleryId = @GalleryId);", tempTableName);
                cmd.Parameters.Clear();
                cmd.CommandText = sql;
                cmd.Parameters.AddWithValue("@RoleName", roleName);
                cmd.Parameters.AddWithValue("@GalleryId", galleryId);
                cmd.ExecuteNonQuery();

                sql = String.Format(@"
INSERT INTO {0} (AlbumId, AlbumParentId, AlbumDepth)
SELECT a.AlbumId, a.AlbumParentId, al.AlbumDepth + 1
FROM gs_Album a JOIN {0} al ON a.AlbumParentId = al.AlbumId
WHERE al.AlbumDepth = (SELECT MAX(AlbumDepth) FROM {0})
", tempTableName);
                cmd.Parameters.Clear();
                cmd.CommandText = sql;
                int numRows;
                do
                {
                    numRows = cmd.ExecuteNonQuery();
                } while (numRows > 0);

                sql = String.Format("SELECT AlbumId FROM {0};", tempTableName);
                cmd.CommandText = sql;

                if (IsTransactionInProgress())
                    return cmd.ExecuteReader();
                else
                {
                    // Commit the transaction if it's the one we created in this method.
                    if (tran != null)
                        tran.Commit();
                    return cmd.ExecuteReader(CommandBehavior.CloseConnection);
                }
            }
        }
    }
    catch
    {
        if (tran != null)
            tran.Rollback();
        throw;
    }
    finally
    {
        if (tran != null)
            tran.Dispose();
    }
}


Both of these were copied from the 2.3.3750 source code, so download it if you want additional context.

You are going in the other direction - finding parents given a child album, but you still might find it helpful.
Roger Martin
Creator and Lead Developer of Gallery Server Pro
Rss Feed  Atom Feed
Users browsing this topic
Guest
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.