Module: wine Branch: master Commit: 3b1ab76986afccaff08e9b649b42f27b60dd3e33 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3b1ab76986afccaff08e9b649b...
Author: James Hawkins truiken@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,