mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 04:39:45 +00:00
msi: Implement reference counting for tables, manipulated with the HOLD and FREE sql commands.
This commit is contained in:
parent
0169533be8
commit
3b1ab76986
@ -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;
|
||||
|
||||
|
@ -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 )
|
||||
|
@ -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 )
|
||||
|
@ -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 )
|
||||
|
@ -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 )
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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 )
|
||||
|
@ -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 )
|
||||
|
@ -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)
|
||||
|
@ -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 )
|
||||
|
@ -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`)";
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user