Mike McCormack : msi: Load all folders in one query, rather one per query.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Nov 22 05:21:58 CST 2006


Module: wine
Branch: master
Commit: 7eb270265f143861553cbf64f23024f7b2b2221e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7eb270265f143861553cbf64f23024f7b2b2221e

Author: Mike McCormack <mike at codeweavers.com>
Date:   Wed Nov 22 15:13:12 2006 +0900

msi: Load all folders in one query, rather one per query.

---

 dlls/msi/action.c  |  177 +++++++++++++++++++++++++---------------------------
 dlls/msi/helpers.c |    5 +-
 dlls/msi/msipriv.h |    2 +-
 3 files changed, 88 insertions(+), 96 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index c49d26d..668b49e 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -1439,6 +1439,89 @@ static UINT load_all_files(MSIPACKAGE *p
     return ERROR_SUCCESS;
 }
 
+static UINT load_folder( MSIRECORD *row, LPVOID param )
+{
+    MSIPACKAGE *package = param;
+    static const WCHAR szDot[] = { '.',0 };
+    static WCHAR szEmpty[] = { 0 };
+    LPWSTR p, tgt_short, tgt_long, src_short, src_long;
+    MSIFOLDER *folder;
+
+    folder = msi_alloc_zero( sizeof (MSIFOLDER) );
+    if (!folder)
+        return ERROR_NOT_ENOUGH_MEMORY;
+
+    folder->Directory = msi_dup_record_field( row, 1 );
+
+    TRACE("%s\n", debugstr_w(folder->Directory));
+
+    p = msi_dup_record_field(row, 3);
+
+    /* split src and target dir */
+    tgt_short = p;
+    src_short = folder_split_path( p, ':' );
+
+    /* split the long and short paths */
+    tgt_long = folder_split_path( tgt_short, '|' );
+    src_long = folder_split_path( src_short, '|' );
+
+    /* check for no-op dirs */
+    if (!lstrcmpW(szDot, tgt_short))
+        tgt_short = szEmpty;
+    if (!lstrcmpW(szDot, src_short))
+        src_short = szEmpty;
+
+    if (!tgt_long)
+        tgt_long = tgt_short;
+
+    if (!src_short) {
+        src_short = tgt_short;
+        src_long = tgt_long;
+    }
+
+    if (!src_long)
+        src_long = src_short;
+
+    /* FIXME: use the target short path too */
+    folder->TargetDefault = strdupW(tgt_long);
+    folder->SourceShortPath = strdupW(src_short);
+    folder->SourceLongPath = strdupW(src_long);
+    msi_free(p);
+
+    TRACE("TargetDefault = %s\n",debugstr_w( folder->TargetDefault ));
+    TRACE("SourceLong = %s\n", debugstr_w( folder->SourceLongPath ));
+    TRACE("SourceShort = %s\n", debugstr_w( folder->SourceShortPath ));
+
+    folder->Parent = msi_dup_record_field( row, 2 );
+
+    folder->Property = msi_dup_property( package, folder->Directory );
+
+    list_add_tail( &package->folders, &folder->entry );
+
+    TRACE("returning %p\n", folder);
+
+    return ERROR_SUCCESS;
+}
+
+static UINT load_all_folders( MSIPACKAGE *package )
+{
+    static const WCHAR query[] = {
+        'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ',
+         '`','D','i','r','e','c','t','o','r','y','`',0 };
+    MSIQUERY *view;
+    UINT r;
+
+    if (!list_empty(&package->folders))
+        return ERROR_SUCCESS;
+
+    r = MSI_DatabaseOpenViewW( package->db, query, &view );
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    r = MSI_IterateRecords(view, NULL, load_folder, package);
+    msiobj_release(&view->hdr);
+    return r;
+}
 
 /*
  * I am not doing any of the costing functionality yet.
@@ -1468,6 +1551,7 @@ static UINT ACTION_CostInitialize(MSIPAC
     load_all_components( package );
     load_all_features( package );
     load_all_files( package );
+    load_all_folders( package );
 
     return ERROR_SUCCESS;
 }
@@ -1504,98 +1588,6 @@ static UINT ACTION_FileCost(MSIPACKAGE *
     return ERROR_SUCCESS;
 }
 
-static MSIFOLDER *load_folder( MSIPACKAGE *package, LPCWSTR dir )
-{
-    static const WCHAR Query[] =
-        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
-         '`','D','i','r','e','c', 't','o','r','y','`',' ',
-         'W','H','E','R','E',' ', '`', 'D','i','r','e','c','t', 'o','r','y','`',
-         ' ','=',' ','\'','%','s','\'',
-         0};
-    static const WCHAR szDot[] = { '.',0 };
-    static WCHAR szEmpty[] = { 0 };
-    LPWSTR p, tgt_short, tgt_long, src_short, src_long;
-    LPCWSTR parent;
-    MSIRECORD *row;
-    MSIFOLDER *folder;
-
-    TRACE("Looking for dir %s\n",debugstr_w(dir));
-
-    folder = get_loaded_folder( package, dir );
-    if (folder)
-        return folder;
-
-    TRACE("Working to load %s\n",debugstr_w(dir));
-
-    row = MSI_QueryGetRecord(package->db, Query, dir);
-    if (!row)
-        return NULL;
-
-    folder = msi_alloc_zero( sizeof (MSIFOLDER) );
-    if (!folder)
-        return NULL;
-
-    folder->Directory = strdupW(dir);
-
-    p = msi_dup_record_field(row, 3);
-
-    /* split src and target dir */
-    tgt_short = p;
-    src_short = folder_split_path( p, ':' );
-
-    /* split the long and short paths */
-    tgt_long = folder_split_path( tgt_short, '|' );
-    src_long = folder_split_path( src_short, '|' );
-
-    /* check for no-op dirs */
-    if (!lstrcmpW(szDot, tgt_short))
-        tgt_short = szEmpty;
-    if (!lstrcmpW(szDot, src_short))
-        src_short = szEmpty;
-
-    if (!tgt_long)
-        tgt_long = tgt_short;
-	
-    if (!src_short) {
-        src_short = tgt_short;
-        src_long = tgt_long;
-    }
-    
-    if (!src_long)
-        src_long = src_short;
-
-    /* FIXME: use the target short path too */
-    folder->TargetDefault = strdupW(tgt_long);
-    folder->SourceShortPath = strdupW(src_short);
-    folder->SourceLongPath = strdupW(src_long);
-    msi_free(p);
-
-    TRACE("TargetDefault = %s\n",debugstr_w( folder->TargetDefault ));
-    TRACE("SourceLong = %s\n", debugstr_w( folder->SourceLongPath ));
-    TRACE("SourceShort = %s\n", debugstr_w( folder->SourceShortPath ));
-
-    parent = MSI_RecordGetString(row, 2);
-    if (parent) 
-    {
-        folder->Parent = load_folder( package, parent );
-        if ( folder->Parent )
-            TRACE("loaded parent %p %s\n", folder->Parent,
-                  debugstr_w(folder->Parent->Directory));
-        else
-            ERR("failed to load parent folder %s\n", debugstr_w(parent));
-    }
-
-    folder->Property = msi_dup_property( package, dir );
-
-    msiobj_release(&row->hdr);
-
-    list_add_tail( &package->folders, &folder->entry );
-
-    TRACE("%s returning %p\n",debugstr_w(dir),folder);
-
-    return folder;
-}
-
 static void ACTION_GetComponentInstallStates(MSIPACKAGE *package)
 {
     MSICOMPONENT *comp;
@@ -1873,7 +1865,6 @@ static UINT ITERATE_CostFinalizeDirector
 
     /* This helper function now does ALL the work */
     TRACE("Dir %s ...\n",debugstr_w(name));
-    load_folder(package,name);
     path = resolve_folder(package,name,FALSE,TRUE,NULL);
     TRACE("resolves to %s\n",debugstr_w(path));
     msi_free(path);
diff --git a/dlls/msi/helpers.c b/dlls/msi/helpers.c
index 3da5a05..e0ec6e6 100644
--- a/dlls/msi/helpers.c
+++ b/dlls/msi/helpers.c
@@ -293,7 +293,7 @@ LPWSTR resolve_folder(MSIPACKAGE *packag
     if (!f->Parent)
         return path;
 
-    parent = f->Parent->Directory;
+    parent = f->Parent;
 
     TRACE(" ! Parent is %s\n", debugstr_w(parent));
 
@@ -496,6 +496,7 @@ void ACTION_free_package_structures( MSI
         MSIFOLDER *folder = LIST_ENTRY( item, MSIFOLDER, entry );
 
         list_remove( &folder->entry );
+        msi_free( folder->Parent );
         msi_free( folder->Directory );
         msi_free( folder->TargetDefault );
         msi_free( folder->SourceLongPath );
@@ -509,7 +510,7 @@ void ACTION_free_package_structures( MSI
     LIST_FOR_EACH_SAFE( item, cursor, &package->components )
     {
         MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry );
-        
+
         list_remove( &comp->entry );
         msi_free( comp->Component );
         msi_free( comp->ComponentId );
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 23879a4..f6089da 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -318,6 +318,7 @@ typedef struct tagMSIFOLDER
 {
     struct list entry;
     LPWSTR Directory;
+    LPWSTR Parent;
     LPWSTR TargetDefault;
     LPWSTR SourceLongPath;
     LPWSTR SourceShortPath;
@@ -325,7 +326,6 @@ typedef struct tagMSIFOLDER
     LPWSTR ResolvedTarget;
     LPWSTR ResolvedSource;
     LPWSTR Property;   /* initially set property */
-    struct tagMSIFOLDER *Parent;
     INT   State;
         /* 0 = uninitialized */
         /* 1 = existing */




More information about the wine-cvs mailing list