|
class ScanTable
{
public:
FILE *fp;
int fd;
char TableName[33]; // Name of the relation
DataDescription DataDes[10]; /* Holds data descriptions
for upto 10 fields */
int n_fields; /* Actual # fields */
int record_size;
char buf[1000]; // Buffer to store a tuple
int Open(char *relname);
int GetNext();
void Close();
int getAttrType( char *attrName ); // Get data type of attr attrName
int getAttrSize( char *attrName ); // Get size of attr attrName
void *getAttrPtr( char *attrName ); // Get pointer to attrName in buf[1000]
void PrintTuple();
void PrintRelationInfo();
};
|
int ScanTable::Open(char *relname)
{
/* ------------------------------------------------
Open the catalog to file the relation definition
------------------------------------------------ */
if ( (fp = fopen("catalog", "r")) == NULL )
{
cout << "Error: cannot open database catalog `./catalog'" << endl;
return 0;
}
n_fields = 0;
record_size = 0;
/* ==================================================
Read attribute information on relation "relname"
================================================== */
while ( fscanf(fp, "%s %s %c %d %d",
DataDes[n_fields].relname, DataDes[n_fields].fieldname,
&DataDes[n_fields].fieldtype, &DataDes[n_fields].startpos,
&DataDes[n_fields].fieldsize) > 0 )
{
if ( strcmp( DataDes[n_fields].relname, relname ) == 0 )
{
/* =========================================
This field belongs to the relation !
Adjust the computation of the record size
========================================= */
if ( DataDes[n_fields].startpos
+ DataDes[n_fields].fieldsize > record_size )
{
record_size = DataDes[n_fields].startpos
+ DataDes[n_fields].fieldsize;
}
n_fields++; // Accept this field
}
}
fclose(fp); // Close the catalog
/* -----------------------------------------
Check if the relation "relname" was found
----------------------------------------- */
if ( n_fields > 0 )
{
/* =======================================
Found: open the data file
======================================= */
if ( (fd = open(relname, O_RDONLY)) == -1 )
{
cout << "Error: canot open relation file " << relname << endl;
return 0;
}
strcpy( TableName, relname);
return 1; // Return success code
}
else
{
return 0; // Return error code
}
}
|
Note:
|
int ScanTable::GetNext()
{
int n;
n = read(fd, buf, record_size+1);
/* ----------------------------------------
Return a success or error code
---------------------------------------- */
if ( n == record_size+1 )
{
return 1;
}
else
{
return 0;
}
}
|
void ScanTable::Close()
{
close(fd); // Close relation file
}
|
ScanTable *f = new ScanTable();
if ( f->Open( "relationName" ) == 0 )
{
cout << "Relation not found !" << endl;
exit(1);
}
while ( f->GetNext() != 0 )
{
/* ------------------
Print it...
------------------ */
f->PrintTuple(); // I added a print tuple method in the class....
}
f->Close();
|
How to run the program:
|
|
|
|
/* ================================================================
PrintTuple(): print the tuple in buf[ ]
================================================================ */
void ScanTable::PrintTuple()
{
int j;
for (j = 0; j < n_fields; j++)
{
int *i_ptr; // To access an int variable
double *f_ptr; // To access a "float" (= double) variable
char *c_ptr; // To access a char[ ] variable (string)
if ( DataDes[j].fieldtype == 'I' )
{
i_ptr = (int *) &(buf[ DataDes[j].startpos]) ;
printf("%d ", *i_ptr ); // *i_ptr is an int variable
}
else if ( DataDes[j].fieldtype == 'F' )
{
f_ptr = (double *) &(buf[ DataDes[j].startpos]) ;
printf("%lf ", *f_ptr ); // *f_ptr is a double variable
}
else // String
{
c_ptr = (char *) &(buf[ DataDes[j].startpos]) ;
printf("`%s' ", c_ptr ); // String is a (char *)
}
}
/* =====================================================
The last field in the record is a "tomb stone" flag
"Y" = valid record
"N" = deleted record
===================================================== */
printf("|| -- Valid flag: %c\n", buf[record_size] );
}
|