//------------------------------------------------------------------------------ // Source file used to generate binary import files for test011. // // Two copies of the binary files are created. The copies are identical, // except for the "mode" column flag. The files with mode=1 are to be // imported using binary mode1. The files with mode=2 are to be imported // using binary mode2. The import files can be imported into the same db // table, and the "mode" column flag can be used to interpret which rows // were imported using mode1 vs mode2. // // Local NULL constants and Date and DateTime structures are declared, so // that this source file can easily be compiled without any dependencies on // any genii include files or libraries. //------------------------------------------------------------------------------ #include #include #include #include #include #include namespace { //..NULL constants const uint64_t BIGINTNULL = 0x8000000000000000ULL; const uint32_t INTNULL = 0x80000000; const uint16_t SMALLINTNULL = 0x8000; const uint8_t TINYINTNULL = 0x80; const uint64_t UBIGINTNULL = 0xFFFFFFFFFFFFFFFEULL; const uint32_t UINTNULL = 0xFFFFFFFE; const uint16_t USMALLINTNULL= 0xFFFE; const uint8_t UTINYINTNULL = 0xFE; const uint32_t FLOATNULL = 0xFFAAAAAA; const uint64_t DOUBLENULL = 0xFFFAAAAAAAAAAAAAULL; const uint32_t DATENULL = 0xFFFFFFFE; const uint64_t DATETIMENULL = 0xFFFFFFFFFFFFFFFEULL; //..Length of character columns const int CH_LEN = 5; const int VCH_LEN = 11; const int VBIN_LEN = 20; //..Structure for constructing/storing date columns struct Date { unsigned spare : 6; unsigned day : 6; unsigned month : 4; unsigned year : 16; // NULL column value = 0xFFFFFFFE Date( ) : spare(0x3E), day(0x3F), month(0xF), year(0xFFFF) {} // Construct a Date from a 64 bit integer Calpont date. Date(unsigned y, unsigned m, unsigned d) : year(y), month(m), day(d) { } }; //..Structure for constructing/storing datetime columns struct DateTime { unsigned msecond : 20; unsigned second : 6; unsigned minute : 6; unsigned hour : 6; unsigned day : 6; unsigned month : 4; unsigned year : 16; // NULL column value = 0xFFFFFFFFFFFFFFFE DateTime( ) : msecond(0xFFFFE), second(0x3F), minute(0x3F), hour(0x3F), day(0x3F), month(0xF), year(0xFFFF) {} // Construct using passed in parameters, no value checking DateTime(unsigned y, unsigned m, unsigned d, unsigned h, unsigned min, unsigned sec, unsigned msec) : msecond(msec), second(sec), minute(min), hour(h), day(d), month(m), year(y) {} }; } //------------------------------------------------------------------------------ // Open an output *.tbl file //------------------------------------------------------------------------------ int openOutputfile(char* filename,FILE** fp) { *fp = fopen( filename, "w+" ); if (*fp == 0) { int err = errno; std::cerr << "Error opening " << filename << "; " << strerror(err) << std::endl; return -1; } return 0; } //------------------------------------------------------------------------------ // Write a "signed" numeric record //------------------------------------------------------------------------------ void writeSignedNumRec(FILE* fp, int mode, int id, int8_t t , int16_t s , int32_t m , int64_t b , int8_t td, int16_t sd, int32_t md, int64_t bd, float* f , double* d) { fwrite(&mode,4,1,fp); fwrite(&id ,4,1,fp); fwrite(&t ,1,1,fp); fwrite(&s ,2,1,fp); fwrite(&m ,4,1,fp); fwrite(&b ,8,1,fp); fwrite(&td ,1,1,fp); fwrite(&sd ,2,1,fp); fwrite(&md ,4,1,fp); fwrite(&bd ,8,1,fp); if (f) fwrite(f ,4,1,fp); else fwrite(&FLOATNULL,4,1,fp); if (d) fwrite(d ,8,1,fp); else fwrite(&DOUBLENULL,8,1,fp); } //------------------------------------------------------------------------------ // The ASCII equivalent for the import file generated by this function, // is as follows. The file is to be used to import/test signed numeric // columns. (The 'm' in column 1 is the import mode.) // // m|1001|11|12|13|14|1.5|1.61|1.72|1.83|1.9|1.11| // m|1002|21|22|23|24|2.5|2.61|2.72|2.83|2.9|2.11| // m|1003|||||||||| // m|1004|-41|-42|-43|-44|-4.5|-4.61|-4.72|-4.83|-4.9|-4.11| // m|1005|-51|-52|-53|-54|-5.5|-5.61|-5.72|-5.83|-5.9|-5.11| // m|1006|||||||||| // m|1007|-128|-32768|-2147483648|-9223372036854775808|-128|-32768|-2147483648|-9223372036854775808|-1.0E+30|-1.0E+300| // m|1008|127|32767|2147483647|9223372036854775807|127|32767|2147483647|9223372036854775807|1.0E+30|1.0E+300| // m|1009|||||||||| // //------------------------------------------------------------------------------ int genNumSignedFile(const char* filename, int mode) { FILE* fp = 0; int rc = openOutputfile((char*)filename, &fp); if (rc != 0) return rc; //..Record #1 int id = 1001; int8_t t = 11; int16_t s = 12; int32_t m = 13; int64_t b = 14; int8_t td = 15; int16_t sd = 161; int32_t md = 172; int64_t bd = 183; float f = 1.9; double d = 1.11; writeSignedNumRec(fp,mode,id,t,s,m,b,td,sd,md,bd,&f,&d); //..Record #2 id++; t += 10; s += 10; m += 10; b += 10; td += 10; sd += 100; md += 100; bd += 100; f += 1.0; d += 1.0; writeSignedNumRec(fp,mode,id,t,s,m,b,td,sd,md,bd,&f,&d); //..Record #3 id++; writeSignedNumRec(fp,mode,id, static_cast (TINYINTNULL), static_cast(SMALLINTNULL), static_cast(INTNULL), static_cast(BIGINTNULL), static_cast (TINYINTNULL), static_cast(SMALLINTNULL), static_cast(INTNULL), static_cast(BIGINTNULL), 0, 0); //..Record #4 id++; t = -41; s = -42; m = -43; b = -44; td = -45; sd = -461; md = -472; bd = -483; f = -4.9; d = -4.11; writeSignedNumRec(fp,mode,id,t,s,m,b,td,sd,md,bd,&f,&d); //..Record #5 id++; t -= 10; s -= 10; m -= 10; b -= 10; td -= 10; sd -= 100; md -= 100; bd -= 100; f -= 1.0;d -= 1.0; writeSignedNumRec(fp,mode,id,t,s,m,b,td,sd,md,bd,&f,&d); //..Record #6 id++; writeSignedNumRec(fp,mode,id, static_cast (TINYINTNULL), static_cast(SMALLINTNULL), static_cast(INTNULL), static_cast(BIGINTNULL), static_cast (TINYINTNULL), static_cast(SMALLINTNULL), static_cast(INTNULL), static_cast(BIGINTNULL), 0, 0); //..Record #7 id++; t = -128; s = -32768; m = -2147483648; b = LLONG_MIN; td = -128; sd = -32768; md = -2147483648; bd = LLONG_MIN; f = -1.0E+30; d = -1.0E+300; writeSignedNumRec(fp,mode,id,t,s,m,b,td,sd,md,bd,&f,&d); //..Record #8 id++; t = 127; s = 32767; m = 2147483647; b = 9223372036854775807; td = 127; sd = 32767; md = 2147483647; bd = 9223372036854775807; f = 1.0E+30; d = 1.0E+300; writeSignedNumRec(fp,mode,id,t,s,m,b,td,sd,md,bd,&f,&d); //..Record #9 id++; writeSignedNumRec(fp,mode,id, static_cast (TINYINTNULL), static_cast(SMALLINTNULL), static_cast(INTNULL), static_cast(BIGINTNULL), static_cast (TINYINTNULL), static_cast(SMALLINTNULL), static_cast(INTNULL), static_cast(BIGINTNULL), 0, 0); fclose( fp ); return rc; } //------------------------------------------------------------------------------ // Write an "unsigned" numeric record //------------------------------------------------------------------------------ void writeUnsignedNumRec(FILE* fp, int mode, int id, uint8_t t, uint16_t s, uint32_t m, uint64_t b , int8_t td, int16_t sd, int32_t md, int64_t bd, float* f , double* d) { fwrite(&mode,4,1,fp); fwrite(&id ,4,1,fp); fwrite(&t ,1,1,fp); fwrite(&s ,2,1,fp); fwrite(&m ,4,1,fp); fwrite(&b ,8,1,fp); fwrite(&td ,1,1,fp); fwrite(&sd ,2,1,fp); fwrite(&md ,4,1,fp); fwrite(&bd ,8,1,fp); if (f) fwrite(f ,4,1,fp); else fwrite(&FLOATNULL,4,1,fp); if (d) fwrite(d ,8,1,fp); else fwrite(&DOUBLENULL,8,1,fp); } //------------------------------------------------------------------------------ // The ASCII equivalent for the import file generated by this function, // is as follows. The file is to be used to import/test unsigned numeric // columns. (The 'm' in column 1 is the import mode.) // // m|1001|11|12|13|14|1.5|1.61|1.72|1.83|1.9|1.11| // m|1002|21|22|23|24|2.5|2.61|2.72|2.83|2.9|2.11| // m|1003|||||||||| // m|1004|0|0|0|0|-4.5|-4.61|-4.72|-4.83|-4.9|-4.11| // m|1005|0|0|0|0|-5.5|-5.61|-5.72|-5.83|-5.9|-5.11| // m|1006|||||||||| // m|1007|0|0|0|0|-128|-32768|-2147483648|-9223372036854775808|-1.0E+30|-1.0E+300| // m|1008|255|65535|4294967295|18446744073709551615|127|32767|2147483647|9223372036854775807|1.0E+30|1.0E+300| // m|1009|||||||||| // //------------------------------------------------------------------------------ int genNumUnsignedFile(const char* filename, int mode) { FILE* fp = 0; int rc = openOutputfile((char*)filename, &fp); if (rc != 0) return rc; //..Record #1 int id = 1001; uint8_t t = 11; uint16_t s = 12; uint32_t m = 13; uint64_t b = 14; int8_t td = 15; int16_t sd = 161; int32_t md = 172; int64_t bd = 183; float f = 1.9; double d = 1.11; writeUnsignedNumRec(fp,mode,id,t,s,m,b,td,sd,md,bd,&f,&d); //..Record #2 id++; t += 10; s += 10; m += 10; b += 10; td += 10; sd += 100; md += 100; bd += 100; f += 1.0; d += 1.0; writeUnsignedNumRec(fp,mode,id,t,s,m,b,td,sd,md,bd,&f,&d); //..Record #3 id++; writeUnsignedNumRec(fp,mode,id, UTINYINTNULL, USMALLINTNULL, UINTNULL, UBIGINTNULL, static_cast (TINYINTNULL), static_cast(SMALLINTNULL), static_cast(INTNULL), static_cast(BIGINTNULL), 0, 0); //..Record #4 id++; t = 0; s = 0; m = 0; b = 0; td = -45; sd = -461; md = -472; bd = -483; f = -4.9; d = -4.11; writeUnsignedNumRec(fp,mode,id,t,s,m,b,td,sd,md,bd,&f,&d); //..Record #5 id++; td -= 10; sd -= 100; md -= 100; bd -= 100; f -= 1.0;d -= 1.0; writeUnsignedNumRec(fp,mode,id,t,s,m,b,td,sd,md,bd,&f,&d); //..Record #6 id++; writeUnsignedNumRec(fp,mode,id, UTINYINTNULL, USMALLINTNULL, UINTNULL, UBIGINTNULL, static_cast (TINYINTNULL), static_cast(SMALLINTNULL), static_cast(INTNULL), static_cast(BIGINTNULL), 0, 0); //..Record #7 id++; t = 0; s = 0; m = 0; b = 0; td = -128; sd = -32768; md = -2147483648; bd = LLONG_MIN; f = -1.0E+30; d = -1.0E+300; writeUnsignedNumRec(fp,mode,id,t,s,m,b,td,sd,md,bd,&f,&d); //..Record #8 id++; t = 255; s = 65535; m = 4294967295; b = 18446744073709551615ULL; td = 127; sd = 32767; md = 2147483647; bd = 9223372036854775807; f = 1.0E+30; d = 1.0E+300; writeUnsignedNumRec(fp,mode,id,t,s,m,b,td,sd,md,bd,&f,&d); //..Record #9 id++; writeUnsignedNumRec(fp,mode,id, UTINYINTNULL, USMALLINTNULL, UINTNULL, UBIGINTNULL, static_cast (TINYINTNULL), static_cast(SMALLINTNULL), static_cast(INTNULL), static_cast(BIGINTNULL), 0, 0); return rc; } //------------------------------------------------------------------------------ // Write a non-numeric record //------------------------------------------------------------------------------ void writeCharRec(FILE* fp, int mode, int id, char* ch, char* vch, Date d, DateTime dt, char* vbin) { fwrite(&mode,4, 1,fp); fwrite(&id ,4, 1,fp); fwrite(ch ,CH_LEN, 1,fp); fwrite(vch ,VCH_LEN, 1,fp); fwrite(&d ,4, 1,fp); fwrite(&dt ,8, 1,fp); //Skip writing out varbinary column since most servers don't have this enabled //The following line can be enabled to test varbinary. //fwrite(vbin ,VBIN_LEN,1,fp); } //------------------------------------------------------------------------------ // The ASCII equivalent for the import file generated by this function, // is as follows. The file is to be used to import/test non-numeric // columns. (The 'm' in column 1 is the import mode.) // // m|1001|abc|abcdefghij|2011-01-01|2011-01-02 11:11:11|313233343536 // m|1002|defgh|klmnop|2011-02-01|2011-02-02 22:22:22|31323334353637 // m|1003|ijkl|qrstuvwx|2011-13-01|2011-03-55 22:22:22|3132333435363738 // m|1004|qurst|wxyzzzzzzzz|2011-04-01|2011-04-03 22:63:22|313233343536373839 // m|1005||||| // // Note: the last column (a varbinary column) in this table is omitted since // most stacks don't have this feature enabled. writeCharRec() can // be changed to output the varbinary column if needed for testing. // //------------------------------------------------------------------------------ int genCharFile(const char* filename, int mode) { FILE* fp = 0; int rc = openOutputfile((char*)filename, &fp); if (rc != 0) return rc; char ch[CH_LEN]; char vch[VCH_LEN]; char vbin[VBIN_LEN]; //..Record #1 int id = 1001; memset(ch, 0,CH_LEN ); memset(vch, 0,VCH_LEN ), memset(vbin,0,VBIN_LEN), memcpy(ch, "abc", 3); memcpy(vch, "abcdefghij", 10); Date d1 (2011,1,1); DateTime dt1(2011,1,2,11,11,11,0); memcpy(vbin,"313233343536", 12); writeCharRec(fp,mode,id,ch,vch,d1,dt1,vbin); //..Record #2 id++; memset(ch, 0,CH_LEN ); memset(vch, 0,VCH_LEN ), memset(vbin,0,VBIN_LEN), memcpy(ch, "defgh", 5); memcpy(vch, "klmnop", 6); Date d2 (2011,2,1); DateTime dt2(2011,2,2,22,22,22,0); memcpy(vbin,"31323334353637", 14); writeCharRec(fp,mode,id,ch,vch,d2,dt2,vbin); //..Record #3 id++; memset(ch, 0,CH_LEN ); memset(vch, 0,VCH_LEN ), memset(vbin,0,VBIN_LEN), memcpy(ch, "ijkl", 4); memcpy(vch, "qrstuvwx", 8); Date d3 (2011,13,1); DateTime dt3(2011,3,55,22,22,22,0); memcpy(vbin,"3132333435363738", 16); writeCharRec(fp,mode,id,ch,vch,d3,dt3,vbin); //..Record #4 id++; memset(ch, 0,CH_LEN ); memset(vch, 0,VCH_LEN ), memset(vbin,0,VBIN_LEN), memcpy(ch, "qurst", 5); memcpy(vch, "wxyzzzzzzzz", 11); Date d4 (2011,4,1); DateTime dt4(2011,4,3,22,63,22,0); memcpy(vbin,"313233343536373839", 18); writeCharRec(fp,mode,id,ch,vch,d4,dt4,vbin); //..Record #5 id++; memset(ch, 0,CH_LEN ); memset(vch, 0,VCH_LEN ); memset(vbin,0,VBIN_LEN); Date d5; DateTime dt5; writeCharRec(fp,mode,id,ch,vch,d5,dt5,vbin); return rc; } //------------------------------------------------------------------------------ // Binary mode1 and binary mode2 files have the same contents "except" // for the mode column which is different, so that we can distinguish // the rows during a query. //------------------------------------------------------------------------------ int main() { int rc = 0; //..Generate 2 binary files used to test signed numeric columns for (int i=1; i<=2; i++) { std::ostringstream filename; filename << "binary" << i << "signed.tbl"; std::cout << "Generating " << filename.str() << "..." << std::endl; rc = genNumSignedFile(filename.str().c_str(), i); if (rc != 0) { std::cerr << "Error building " << filename << " file" << std::endl; return rc; } } //..Generate 2 binary files used to test unsigned numeric columns for (int i=1; i<=2; i++) { std::ostringstream filename; filename << "binary" << i << "unsigned.tbl"; std::cout << "Generating " << filename.str() << "..." << std::endl; rc = genNumUnsignedFile(filename.str().c_str(), i); if (rc != 0) { std::cerr << "Error building " << filename << " file" << std::endl; return rc; } } //..Generate 2 binary files used to test non-numeric columns for (int i=1; i<=2; i++) { std::ostringstream filename; filename << "binary" << i << "char.tbl"; std::cout << "Generating " << filename.str() << "..." << std::endl; rc = genCharFile(filename.str().c_str(), i); if (rc != 0) { std::cerr << "Error building " << filename << " file" << std::endl; return rc; } } return rc; }