James Hawkins : msi: Implement reference counting for tables,
manipulated with the HOLD and FREE sql commands.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Jul 19 07:59:50 CDT 2007
Module: wine
Branch: master
Commit: 3b1ab76986afccaff08e9b649b42f27b60dd3e33
URL: http://source.winehq.org/git/wine.git/?a=commit;h=3b1ab76986afccaff08e9b649b42f27b60dd3e33
Author: James Hawkins <truiken at gmail.com>
Date: Wed Jul 18 18:21:00 2007 -0700
msi: Implement reference counting for tables, manipulated with the HOLD and FREE sql commands.
---
dlls/msi/alter.c | 23 +++++++++++++++++++----
dlls/msi/create.c | 5 +++--
dlls/msi/delete.c | 4 +++-
dlls/msi/distinct.c | 2 ++
dlls/msi/insert.c | 4 +++-
dlls/msi/join.c | 4 +++-
dlls/msi/msipriv.h | 10 ++++++++++
dlls/msi/order.c | 4 +++-
dlls/msi/select.c | 4 +++-
dlls/msi/streams.c | 4 +++-
dlls/msi/table.c | 35 ++++++++++++++++++++++++++++++++++-
dlls/msi/tests/db.c | 7 +------
dlls/msi/update.c | 4 +++-
dlls/msi/where.c | 4 +++-
14 files changed, 93 insertions(+), 21 deletions(-)
diff --git a/dlls/msi/alter.c b/dlls/msi/alter.c
index b506aa1..2815f11 100644
--- a/dlls/msi/alter.c
+++ b/dlls/msi/alter.c
@@ -38,6 +38,8 @@ typedef struct tagMSIALTERVIEW
{
MSIVIEW view;
MSIDATABASE *db;
+ MSIVIEW *table;
+ INT hold;
} MSIALTERVIEW;
static UINT ALTER_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
@@ -62,7 +64,12 @@ static UINT ALTER_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{
MSIALTERVIEW *av = (MSIALTERVIEW*)view;
- FIXME("%p %p\n", av, record);
+ TRACE("%p %p\n", av, record);
+
+ if (av->hold == 1)
+ av->table->ops->add_ref(av->table);
+ else if (av->hold == -1)
+ av->table->ops->release(av->table);
return ERROR_SUCCESS;
}
@@ -111,6 +118,7 @@ static UINT ALTER_delete( struct tagMSIVIEW *view )
TRACE("%p\n", av );
msi_free( av );
+ av->table->ops->delete( av->table );
return ERROR_SUCCESS;
}
@@ -123,7 +131,6 @@ static UINT ALTER_find_matching_rows( struct tagMSIVIEW *view, UINT col,
return ERROR_FUNCTION_FAILED;
}
-
static const MSIVIEWOPS alter_ops =
{
ALTER_fetch_int,
@@ -137,22 +144,30 @@ static const MSIVIEWOPS alter_ops =
ALTER_get_column_info,
ALTER_modify,
ALTER_delete,
- ALTER_find_matching_rows
+ ALTER_find_matching_rows,
+ NULL,
+ NULL,
};
UINT ALTER_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR name, int hold )
{
MSIALTERVIEW *av;
+ UINT r;
- TRACE("%p\n", view );
+ TRACE("%p %s %d\n", view, debugstr_w(name), hold );
av = msi_alloc_zero( sizeof *av );
if( !av )
return ERROR_FUNCTION_FAILED;
+ r = TABLE_CreateView( db, name, &av->table );
+ if (r != ERROR_SUCCESS || !av->table)
+ return r;
+
/* fill the structure */
av->view.ops = &alter_ops;
av->db = db;
+ av->hold = hold;
*view = &av->view;
diff --git a/dlls/msi/create.c b/dlls/msi/create.c
index 9c3fb39..65a066f 100644
--- a/dlls/msi/create.c
+++ b/dlls/msi/create.c
@@ -117,7 +117,6 @@ static UINT CREATE_delete( struct tagMSIVIEW *view )
return ERROR_SUCCESS;
}
-
static const MSIVIEWOPS create_ops =
{
CREATE_fetch_int,
@@ -130,7 +129,9 @@ static const MSIVIEWOPS create_ops =
CREATE_get_dimensions,
CREATE_get_column_info,
CREATE_modify,
- CREATE_delete
+ CREATE_delete,
+ NULL,
+ NULL,
};
static UINT check_columns( column_info *col_info )
diff --git a/dlls/msi/delete.c b/dlls/msi/delete.c
index bd33956..8d668c4 100644
--- a/dlls/msi/delete.c
+++ b/dlls/msi/delete.c
@@ -192,7 +192,9 @@ static const MSIVIEWOPS delete_ops =
DELETE_get_column_info,
DELETE_modify,
DELETE_delete,
- DELETE_find_matching_rows
+ DELETE_find_matching_rows,
+ NULL,
+ NULL,
};
UINT DELETE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
diff --git a/dlls/msi/distinct.c b/dlls/msi/distinct.c
index 8513823..6d737d9 100644
--- a/dlls/msi/distinct.c
+++ b/dlls/msi/distinct.c
@@ -282,6 +282,8 @@ static const MSIVIEWOPS distinct_ops =
DISTINCT_modify,
DISTINCT_delete,
DISTINCT_find_matching_rows,
+ NULL,
+ NULL,
};
UINT DISTINCT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
diff --git a/dlls/msi/insert.c b/dlls/msi/insert.c
index 95c35f3..207f153 100644
--- a/dlls/msi/insert.c
+++ b/dlls/msi/insert.c
@@ -232,7 +232,9 @@ static const MSIVIEWOPS insert_ops =
INSERT_get_column_info,
INSERT_modify,
INSERT_delete,
- INSERT_find_matching_rows
+ INSERT_find_matching_rows,
+ NULL,
+ NULL,
};
static UINT count_column_info( const column_info *ci )
diff --git a/dlls/msi/join.c b/dlls/msi/join.c
index ab1935e..7ff2b91 100644
--- a/dlls/msi/join.c
+++ b/dlls/msi/join.c
@@ -252,7 +252,9 @@ static const MSIVIEWOPS join_ops =
JOIN_get_column_info,
JOIN_modify,
JOIN_delete,
- JOIN_find_matching_rows
+ JOIN_find_matching_rows,
+ NULL,
+ NULL,
};
UINT JOIN_CreateView( MSIDATABASE *db, MSIVIEW **view,
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index a94866a..39719d5 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -221,6 +221,16 @@ typedef struct tagMSIVIEWOPS
* first call and continued to be passed in to subsequent calls.
*/
UINT (*find_matching_rows)( struct tagMSIVIEW *view, UINT col, UINT val, UINT *row, MSIITERHANDLE *handle );
+
+ /*
+ * add_ref - increases the reference count of the table
+ */
+ UINT (*add_ref)( struct tagMSIVIEW *view );
+
+ /*
+ * release - decreases the reference count of the table
+ */
+ UINT (*release)( struct tagMSIVIEW *view );
} MSIVIEWOPS;
struct tagMSIVIEW
diff --git a/dlls/msi/order.c b/dlls/msi/order.c
index c0ab643..feb9a31 100644
--- a/dlls/msi/order.c
+++ b/dlls/msi/order.c
@@ -281,7 +281,9 @@ static const MSIVIEWOPS order_ops =
ORDER_get_column_info,
ORDER_modify,
ORDER_delete,
- ORDER_find_matching_rows
+ ORDER_find_matching_rows,
+ NULL,
+ NULL,
};
static UINT ORDER_AddColumn( MSIORDERVIEW *ov, LPCWSTR name )
diff --git a/dlls/msi/select.c b/dlls/msi/select.c
index 6953e1f..fc2f7be 100644
--- a/dlls/msi/select.c
+++ b/dlls/msi/select.c
@@ -274,7 +274,9 @@ static const MSIVIEWOPS select_ops =
SELECT_get_column_info,
SELECT_modify,
SELECT_delete,
- SELECT_find_matching_rows
+ SELECT_find_matching_rows,
+ NULL,
+ NULL,
};
static UINT SELECT_AddColumn( MSISELECTVIEW *sv, LPCWSTR name )
diff --git a/dlls/msi/streams.c b/dlls/msi/streams.c
index fbb8b79..6828277 100644
--- a/dlls/msi/streams.c
+++ b/dlls/msi/streams.c
@@ -336,7 +336,9 @@ static const MSIVIEWOPS streams_ops =
STREAMS_get_column_info,
STREAMS_modify,
STREAMS_delete,
- STREAMS_find_matching_rows
+ STREAMS_find_matching_rows,
+ NULL,
+ NULL,
};
static UINT add_streams_to_table(MSISTREAMSVIEW *sv)
diff --git a/dlls/msi/table.c b/dlls/msi/table.c
index 69a033c..33d6aa5 100644
--- a/dlls/msi/table.c
+++ b/dlls/msi/table.c
@@ -71,6 +71,7 @@ struct tagMSITABLE
MSICOLUMNINFO *colinfo;
UINT col_count;
BOOL persistent;
+ INT ref_count;
WCHAR name[1];
};
@@ -632,6 +633,7 @@ UINT msi_create_table( MSIDATABASE *db, LPCWSTR name, column_info *col_info,
if( !table )
return ERROR_FUNCTION_FAILED;
+ table->ref_count = 1;
table->row_count = 0;
table->data = NULL;
table->nonpersistent_row_count = 0;
@@ -1642,6 +1644,35 @@ static UINT TABLE_find_matching_rows( struct tagMSIVIEW *view, UINT col,
return ERROR_SUCCESS;
}
+static UINT TABLE_add_ref(struct tagMSIVIEW *view)
+{
+ MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
+
+ TRACE("%p %d\n", view, tv->table->ref_count);
+
+ return InterlockedIncrement(&tv->table->ref_count);
+}
+
+static UINT TABLE_release(struct tagMSIVIEW *view)
+{
+ MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
+ INT ref = tv->table->ref_count;
+
+ TRACE("%p %d\n", view, ref);
+
+ ref = InterlockedDecrement(&tv->table->ref_count);
+ if (ref == 0)
+ {
+ if (!tv->table->row_count)
+ {
+ list_remove(&tv->table->entry);
+ free_table(tv->table);
+ TABLE_delete(view);
+ }
+ }
+
+ return ref;
+}
static const MSIVIEWOPS table_ops =
{
@@ -1656,7 +1687,9 @@ static const MSIVIEWOPS table_ops =
TABLE_get_column_info,
TABLE_modify,
TABLE_delete,
- TABLE_find_matching_rows
+ TABLE_find_matching_rows,
+ TABLE_add_ref,
+ TABLE_release,
};
UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view )
diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c
index 7d06efb..4b54e8a 100644
--- a/dlls/msi/tests/db.c
+++ b/dlls/msi/tests/db.c
@@ -2932,7 +2932,6 @@ static void test_alter(void)
r = run_query(hdb, 0, query);
ok(r == ERROR_SUCCESS, "failed to free table\n");
- todo_wine {
query = "ALTER TABLE `T` FREE";
r = run_query(hdb, 0, query);
ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to free table\n");
@@ -2940,15 +2939,11 @@ static void test_alter(void)
query = "ALTER TABLE `T` HOLD";
r = run_query(hdb, 0, query);
ok(r == ERROR_BAD_QUERY_SYNTAX, "failed to hold table %d\n", r);
- }
/* table T is removed */
query = "SELECT * FROM `T`";
r = run_query(hdb, 0, query);
- todo_wine
- {
- ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
- }
+ ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
/* create the table again */
query = "CREATE TABLE `U` ( `A` INTEGER, `B` INTEGER PRIMARY KEY `B`)";
diff --git a/dlls/msi/update.c b/dlls/msi/update.c
index bc3fb2e..037c282 100644
--- a/dlls/msi/update.c
+++ b/dlls/msi/update.c
@@ -184,7 +184,9 @@ static const MSIVIEWOPS update_ops =
UPDATE_get_column_info,
UPDATE_modify,
UPDATE_delete,
- UPDATE_find_matching_rows
+ UPDATE_find_matching_rows,
+ NULL,
+ NULL,
};
UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR table,
diff --git a/dlls/msi/where.c b/dlls/msi/where.c
index ab9c9a6..5b5d867 100644
--- a/dlls/msi/where.c
+++ b/dlls/msi/where.c
@@ -446,7 +446,9 @@ static const MSIVIEWOPS where_ops =
WHERE_get_column_info,
WHERE_modify,
WHERE_delete,
- WHERE_find_matching_rows
+ WHERE_find_matching_rows,
+ NULL,
+ NULL,
};
static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr *cond,
More information about the wine-cvs
mailing list