Skip to content

Commit

Permalink
msi: Implement adding columns using the ALTER command.
Browse files Browse the repository at this point in the history
  • Loading branch information
truiken authored and julliard committed Jul 23, 2007
1 parent 52cc727 commit 0fd733b
Show file tree
Hide file tree
Showing 18 changed files with 174 additions and 49 deletions.
82 changes: 81 additions & 1 deletion dlls/msi/alter.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ typedef struct tagMSIALTERVIEW
MSIVIEW view;
MSIDATABASE *db;
MSIVIEW *table;
column_info *colinfo;
INT hold;
} MSIALTERVIEW;

Expand All @@ -60,6 +61,78 @@ static UINT ALTER_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
return ERROR_FUNCTION_FAILED;
}

static UINT ITERATE_columns(MSIRECORD *row, LPVOID param)
{
(*(UINT *)param)++;
return ERROR_SUCCESS;
}

static BOOL check_column_exists(MSIDATABASE *db, MSIVIEW *columns, LPCWSTR table, LPCWSTR column)
{
MSIQUERY *view;
MSIRECORD *rec;
UINT r;

static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','_','C','o','l','u','m','n','s','`',' ','W','H','E','R','E',' ',
'`','T','a','b','l','e','`','=','\'','%','s','\'',' ','A','N','D',' ',
'`','N','a','m','e','`','=','\'','%','s','\'',0
};

r = MSI_OpenQuery(db, &view, query, table, column);
if (r != ERROR_SUCCESS)
return FALSE;

r = MSI_ViewExecute(view, NULL);
if (r != ERROR_SUCCESS)
goto done;

r = MSI_ViewFetch(view, &rec);
if (r == ERROR_SUCCESS)
msiobj_release(&rec->hdr);

done:
msiobj_release(&view->hdr);
return (r == ERROR_SUCCESS);
}

static UINT alter_add_column(MSIALTERVIEW *av)
{
UINT r, colnum = 1;
MSIQUERY *view;
MSIVIEW *columns;

static const WCHAR szColumns[] = {'_','C','o','l','u','m','n','s',0};
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','_','C','o','l','u','m','n','s','`',' ','W','H','E','R','E',' ',
'`','T','a','b','l','e','`','=','\'','%','s','\'',' ','O','R','D','E','R',' ',
'B','Y',' ','`','N','u','m','b','e','r','`',0
};

r = TABLE_CreateView(av->db, szColumns, &columns);
if (r != ERROR_SUCCESS)
return r;

if (check_column_exists(av->db, columns, av->colinfo->table, av->colinfo->column))
return ERROR_BAD_QUERY_SYNTAX;

r = MSI_OpenQuery(av->db, &view, query, av->colinfo->table, av->colinfo->column);
if (r == ERROR_SUCCESS)
{
r = MSI_IterateRecords(view, NULL, ITERATE_columns, &colnum);
msiobj_release(&view->hdr);
}

r = columns->ops->add_column(columns, av->colinfo->table,
colnum, av->colinfo->column,
av->colinfo->type);

msiobj_release(&columns->hdr);
return r;
}

static UINT ALTER_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{
MSIALTERVIEW *av = (MSIALTERVIEW*)view;
Expand All @@ -70,6 +143,8 @@ static UINT ALTER_execute( struct tagMSIVIEW *view, MSIRECORD *record )
av->table->ops->add_ref(av->table);
else if (av->hold == -1)
av->table->ops->release(av->table);
else
return alter_add_column(av);

return ERROR_SUCCESS;
}
Expand Down Expand Up @@ -147,9 +222,10 @@ static const MSIVIEWOPS alter_ops =
ALTER_find_matching_rows,
NULL,
NULL,
NULL,
};

UINT ALTER_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR name, int hold )
UINT ALTER_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR name, column_info *colinfo, int hold )
{
MSIALTERVIEW *av;
UINT r;
Expand All @@ -164,10 +240,14 @@ UINT ALTER_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR name, int hold )
if (r != ERROR_SUCCESS || !av->table)
return r;

if (colinfo)
colinfo->table = name;

/* fill the structure */
av->view.ops = &alter_ops;
av->db = db;
av->hold = hold;
av->colinfo = colinfo;

*view = &av->view;

Expand Down
1 change: 1 addition & 0 deletions dlls/msi/create.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ static const MSIVIEWOPS create_ops =
CREATE_delete,
NULL,
NULL,
NULL,
};

static UINT check_columns( column_info *col_info )
Expand Down
1 change: 1 addition & 0 deletions dlls/msi/delete.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ static const MSIVIEWOPS delete_ops =
DELETE_find_matching_rows,
NULL,
NULL,
NULL,
};

UINT DELETE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
Expand Down
1 change: 1 addition & 0 deletions dlls/msi/distinct.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ static const MSIVIEWOPS distinct_ops =
DISTINCT_find_matching_rows,
NULL,
NULL,
NULL,
};

UINT DISTINCT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
Expand Down
1 change: 1 addition & 0 deletions dlls/msi/insert.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ static const MSIVIEWOPS insert_ops =
INSERT_find_matching_rows,
NULL,
NULL,
NULL,
};

static UINT count_column_info( const column_info *ci )
Expand Down
1 change: 1 addition & 0 deletions dlls/msi/join.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ static const MSIVIEWOPS join_ops =
JOIN_find_matching_rows,
NULL,
NULL,
NULL,
};

UINT JOIN_CreateView( MSIDATABASE *db, MSIVIEW **view,
Expand Down
5 changes: 5 additions & 0 deletions dlls/msi/msipriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ typedef struct tagMSIVIEWOPS
* release - decreases the reference count of the table
*/
UINT (*release)( struct tagMSIVIEW *view );

/*
* add_column - adds a column to the table
*/
UINT (*add_column)( struct tagMSIVIEW *view, LPCWSTR table, UINT number, LPCWSTR column, UINT type );
} MSIVIEWOPS;

struct tagMSIVIEW
Expand Down
1 change: 1 addition & 0 deletions dlls/msi/order.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ static const MSIVIEWOPS order_ops =
ORDER_find_matching_rows,
NULL,
NULL,
NULL,
};

static UINT ORDER_AddColumn( MSIORDERVIEW *ov, LPCWSTR name )
Expand Down
2 changes: 1 addition & 1 deletion dlls/msi/query.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ UINT DELETE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table );
UINT JOIN_CreateView( MSIDATABASE *db, MSIVIEW **view,
LPCWSTR left, LPCWSTR right );

UINT ALTER_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR name, int hold );
UINT ALTER_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR name, column_info *colinfo, int hold );

UINT STREAMS_CreateView( MSIDATABASE *db, MSIVIEW **view );

Expand Down
1 change: 1 addition & 0 deletions dlls/msi/select.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ static const MSIVIEWOPS select_ops =
SELECT_find_matching_rows,
NULL,
NULL,
NULL,
};

static UINT SELECT_AddColumn( MSISELECTVIEW *sv, LPCWSTR name )
Expand Down
14 changes: 12 additions & 2 deletions dlls/msi/sql.y
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ static struct expr * EXPR_wildcard( void *info );
}

%token TK_ALTER TK_AND TK_BY TK_CHAR TK_COMMA TK_CREATE TK_DELETE
%token TK_DISTINCT TK_DOT TK_EQ TK_FREE TK_FROM TK_GE TK_GT TK_HOLD
%token TK_DISTINCT TK_DOT TK_EQ TK_FREE TK_FROM TK_GE TK_GT TK_HOLD TK_ADD
%token <str> TK_ID
%token TK_ILLEGAL TK_INSERT TK_INT
%token <str> TK_INTEGER
Expand Down Expand Up @@ -231,11 +231,21 @@ onealter:
SQL_input* sql = (SQL_input*) info;
MSIVIEW *alter = NULL;

ALTER_CreateView( sql->db, &alter, $3, $4 );
ALTER_CreateView( sql->db, &alter, $3, NULL, $4 );
if( !alter )
YYABORT;
$$ = alter;
}
| TK_ALTER TK_TABLE table TK_ADD column_and_type
{
SQL_input *sql = (SQL_input *)info;
MSIVIEW *alter = NULL;

ALTER_CreateView( sql->db, &alter, $3, $5, 0 );
if (!alter)
YYABORT;
$$ = alter;
}
;

alterop:
Expand Down
1 change: 1 addition & 0 deletions dlls/msi/streams.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ static const MSIVIEWOPS streams_ops =
STREAMS_find_matching_rows,
NULL,
NULL,
NULL,
};

static UINT add_streams_to_table(MSISTREAMSVIEW *sv)
Expand Down
71 changes: 49 additions & 22 deletions dlls/msi/table.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ static const WCHAR szType[] = { 'T','y','p','e',0 };
* Do not mark them const.
*/
static MSICOLUMNINFO _Columns_cols[4] = {
{ szColumns, 1, szTable, MSITYPE_VALID | MSITYPE_STRING | 64, 0 },
{ szColumns, 2, szNumber, MSITYPE_VALID | 2, 2 },
{ szColumns, 1, szTable, MSITYPE_VALID | MSITYPE_STRING | MSITYPE_KEY | 64, 0 },
{ szColumns, 2, szNumber, MSITYPE_VALID | MSITYPE_KEY | 2, 2 },
{ szColumns, 3, szName, MSITYPE_VALID | MSITYPE_STRING | 64, 4 },
{ szColumns, 4, szType, MSITYPE_VALID | 2, 6 },
};
Expand Down Expand Up @@ -1035,6 +1035,26 @@ static UINT get_tablecolumns( MSIDATABASE *db,
return ERROR_SUCCESS;
}

static void msi_update_table_columns( MSIDATABASE *db, LPCWSTR name )
{
MSITABLE *table;
UINT size, offset;
int n;

table = find_cached_table( db, name );
msi_free( table->colinfo );
table_get_column_info( db, name, &table->colinfo, &table->col_count );

size = msi_table_get_row_size( table->colinfo, table->col_count );
offset = table->colinfo[table->col_count - 1].offset;

for ( n = 0; n < table->row_count; n++ )
{
table->data[n] = msi_realloc( table->data[n], size );
table->data[n][offset] = (BYTE)MSI_NULL_INTEGER;
}
}

/* try to find the table name in the _Tables table */
BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name )
{
Expand Down Expand Up @@ -1674,6 +1694,32 @@ static UINT TABLE_release(struct tagMSIVIEW *view)
return ref;
}

static UINT TABLE_add_column(struct tagMSIVIEW *view, LPCWSTR table, UINT number, LPCWSTR column, UINT type)
{
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
MSIRECORD *rec;
UINT r;

rec = MSI_CreateRecord(4);
if (!rec)
return ERROR_OUTOFMEMORY;

MSI_RecordSetStringW(rec, 1, table);
MSI_RecordSetInteger(rec, 2, number);
MSI_RecordSetStringW(rec, 3, column);
MSI_RecordSetInteger(rec, 4, type);

r = TABLE_insert_row(&tv->view, rec, FALSE);
if (r != ERROR_SUCCESS)
goto done;

msi_update_table_columns(tv->db, table);

done:
msiobj_release(&rec->hdr);
return r;
}

static const MSIVIEWOPS table_ops =
{
TABLE_fetch_int,
Expand All @@ -1690,6 +1736,7 @@ static const MSIVIEWOPS table_ops =
TABLE_find_matching_rows,
TABLE_add_ref,
TABLE_release,
TABLE_add_column,
};

UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view )
Expand Down Expand Up @@ -1977,26 +2024,6 @@ static UINT msi_table_find_row( MSITABLEVIEW *tv, MSIRECORD *rec, UINT *row )
return r;
}

static void msi_update_table_columns( MSIDATABASE *db, LPWSTR name )
{
MSITABLE *table;
UINT size, offset;
int n;

table = find_cached_table( db, name );
msi_free( table->colinfo );
table_get_column_info( db, name, &table->colinfo, &table->col_count );

size = msi_table_get_row_size( table->colinfo, table->col_count );
offset = table->colinfo[table->col_count - 1].offset;

for ( n = 0; n < table->row_count; n++ )
{
table->data[n] = msi_realloc( table->data[n], size );
table->data[n][offset] = (BYTE)MSI_NULL_INTEGER;
}
}

typedef struct
{
struct list entry;
Expand Down

0 comments on commit 0fd733b

Please sign in to comment.