Пример #1
0
PWMIUT InitWMI(PGLOBAL g, char *nsp, char *classname)
{
  IWbemLocator *loc;
  char         *p;
  HRESULT       res;
  PWMIUT        wp = (PWMIUT)PlugSubAlloc(g, NULL, sizeof(WMIUTIL));

  if (trace)
    htrc("WMIColumns class %s space %s\n", SVP(classname), SVP(nsp));

  /*********************************************************************/
  /*  Set default values for the namespace and class name.             */
  /*********************************************************************/
  if (!nsp)
    nsp = "root\\cimv2";

  if (!classname) {
    if (!stricmp(nsp, "root\\cimv2"))
      classname = "ComputerSystemProduct";
    else if (!stricmp(nsp, "root\\cli"))
      classname = "Msft_CliAlias";
    else {
      strcpy(g->Message, "Missing class name");
      return NULL;
      } // endif classname

    } // endif classname

  /*********************************************************************/
  /*  Initialize WMI.                                                  */
  /*********************************************************************/
//res = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

  if (FAILED(res)) {
    sprintf(g->Message, "Failed to initialize COM library. " 
            "Error code = %p", res);
    return NULL;
    } // endif res

#if 0 // irrelevant for a DLL
  res = CoInitializeSecurity(NULL, -1, NULL, NULL,
                       RPC_C_AUTHN_LEVEL_CONNECT,
                       RPC_C_IMP_LEVEL_IMPERSONATE,
                       NULL, EOAC_NONE, NULL);
  
  if (res != RPC_E_TOO_LATE && FAILED(res)) {
    sprintf(g->Message, "Failed to initialize security. " 
            "Error code = %p", res);
    CoUninitialize();
    return NULL;
    }  // endif Res
#endif // 0

  res = CoCreateInstance(CLSID_WbemLocator, NULL, 
                         CLSCTX_INPROC_SERVER, IID_IWbemLocator, 
                         (void**) &loc);
  if (FAILED(res)) {
    sprintf(g->Message, "Failed to create Locator. " 
            "Error code = %p", res);
    CoUninitialize();
    return NULL;
    }  // endif res
    
  res = loc->ConnectServer(_bstr_t(nsp), 
                    NULL, NULL, NULL, 0, NULL, NULL, &wp->Svc);

  if (FAILED(res)) {
    sprintf(g->Message, "Could not connect. Error code = %p", res); 
    loc->Release();     
    CoUninitialize();
    return NULL;
    }  // endif res

  loc->Release();

  if (trace)
    htrc("Successfully connected to namespace.\n");

  /*********************************************************************/
  /*  Perform a full class object retrieval.                           */
  /*********************************************************************/
  p = (char*)PlugSubAlloc(g, NULL, strlen(classname) + 7);

  if (strchr(classname, '_'))
    strcpy(p, classname);
  else
    strcat(strcpy(p, "Win32_"), classname);

  res = wp->Svc->GetObject(bstr_t(p), 0, 0, &wp->Cobj, 0);

  if (FAILED(res)) {
    sprintf(g->Message, "failed GetObject %s in %s\n", classname, nsp);
    wp->Svc->Release();
    wp->Svc = NULL;    // MUST be set to NULL  (why?)
    return NULL;
    }  // endif res

  return wp;
} // end of InitWMI
Пример #2
0
int TDBINI::ReadDB(PGLOBAL g)
  {
  /*********************************************************************/
  /*  Now start the pseudo reading process.                            */
  /*********************************************************************/
#if 0                // INI tables are not indexable
  if (To_Kindex) {
    /*******************************************************************/
    /*  Reading is by an index table.                                  */
    /*******************************************************************/
    int recpos = To_Kindex->Fetch(g);

    switch (recpos) {
      case -1:           // End of file reached
        return RC_EF;
      case -2:           // No match for join
        return RC_NF;
      case -3:           // Same record as last non null one
        return RC_OK;
      default:
        Section = (char*)recpos;    // No good on 64 bit machines
      } // endswitch recpos

  } else {
#endif // 0
    if (!Section)
      Section = Seclist;
    else
      Section += (strlen(Section) + 1);

    if (trace > 1)
      htrc("INI ReadDB: section=%s N=%d\n", Section, N);

    N++;
//} // endif To_Kindex

  return (*Section) ? RC_OK : RC_EF;
  } // end of ReadDB

/***********************************************************************/
/*  WriteDB: Data Base write routine for INI access methods.           */
/***********************************************************************/
int TDBINI::WriteDB(PGLOBAL g)
  {
  // This is to check that section name was given when inserting
  if (Mode == MODE_INSERT)
    Section = NULL;

  // Nothing else to do because all was done in WriteColumn
  return RC_OK;
  } // end of WriteDB

/***********************************************************************/
/*  Data Base delete line routine for INI access methods.              */
/***********************************************************************/
int TDBINI::DeleteDB(PGLOBAL g, int irc)
  {
  switch (irc) {
    case RC_EF:
      break;
    case RC_FX:
      while (ReadDB(g) == RC_OK)
        if (!WritePrivateProfileString(Section, NULL, NULL, Ifile)) {
          sprintf(g->Message, "Error %d accessing %s", 
                              GetLastError(), Ifile);
          return RC_FX;
          } // endif

      break;
    default:
      if (!Section) {
        strcpy(g->Message, MSG(NO_SECTION_NAME));
        return RC_FX;
      } else
        if (!WritePrivateProfileString(Section, NULL, NULL, Ifile)) {
          sprintf(g->Message, "Error %d accessing %s", 
                              GetLastError(), Ifile);
          return RC_FX;
          } // endif rc

    } // endswitch irc

  return RC_OK;
  } // end of DeleteDB

/***********************************************************************/
/*  Data Base close routine for INI access methods.                    */
/***********************************************************************/
void TDBINI::CloseDB(PGLOBAL g)
  {
#if !defined(WIN32)
  PROFILE_Close(Ifile);
#endif   // !WIN32
  } // end of CloseDB
Пример #3
0
PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b)
  {
  const char  *sp = NULL;
  char        *db, *name;
  bool         mysql = true;
  PTDB         tdbp = NULL;
  TABLE_SHARE *s = NULL;
  Field*      *fp = NULL;
  PCATLG       cat = To_Def->GetCat();
  PHC          hc = ((MYCAT*)cat)->GetHandler();
  LPCSTR       cdb, curdb = hc->GetDBName(NULL);
  THD         *thd = (hc->GetTable())->in_use;

  db = (char*)tabp->GetQualifier();
  name = (char*)tabp->GetName();

  // Check for eventual loop
  for (PTABLE tp = To_Table; tp; tp = tp->Next) {
    cdb = (tp->Qualifier) ? tp->Qualifier : curdb;

    if (!stricmp(name, tp->Name) && !stricmp(db, cdb)) {
      sprintf(g->Message, "Table %s.%s pointing on itself", db, name);
      return NULL;
      } // endif

    } // endfor tp

  if (!tabp->GetSrc()) {
    if (!(s = GetTableShare(g, thd, db, name, mysql)))
      return NULL;

    if (s->is_view && !b)
      s->field = hc->get_table()->s->field;

    hc->tshp = s;
  } else if (b) {
    // Don't use caller's columns
    fp = hc->get_table()->field;
    hc->get_table()->field = NULL;

    // Make caller use the source definition
    sp = hc->get_table()->s->option_struct->srcdef;
    hc->get_table()->s->option_struct->srcdef = tabp->GetSrc();
  } // endif srcdef

  if (mysql) {
#if defined(MYSQL_SUPPORT)
    // Access sub-table via MySQL API
    if (!(tdbp= cat->GetTable(g, tabp, Mode, "MYPRX"))) {
      char buf[MAX_STR];

      strcpy(buf, g->Message);
      sprintf(g->Message, "Error accessing %s.%s: %s", db, name, buf);
      hc->tshp = NULL;
      goto err;
      } // endif Define

    if (db)
      ((PTDBMY)tdbp)->SetDatabase(tabp->GetQualifier());

    if (Mode == MODE_UPDATE || Mode == MODE_DELETE)
      tdbp->SetName(Name);      // For Make_Command

#else   // !MYSQL_SUPPORT
      sprintf(g->Message, "%s.%s is not a CONNECT table",
                          db, tblp->Name);
      goto err;
#endif   // MYSQL_SUPPORT
  } else {
    // Sub-table is a CONNECT table
    tabp->Next = To_Table;          // For loop checking
    tdbp = cat->GetTable(g, tabp, Mode);
  } // endif mysql

  if (s) {
    if (s->is_view && !b)
      s->field = NULL;

    hc->tshp = NULL;
  } else if (b) {
    // Restore s structure that can be in cache
    hc->get_table()->field = fp;
    hc->get_table()->s->option_struct->srcdef = sp;
  } // endif s

  if (trace && tdbp)
    htrc("Subtable %s in %s\n", 
          name, SVP(((PTDBASE)tdbp)->GetDef()->GetDB()));
 
 err:
  if (s)
    free_table_share(s);

  return (PTDBASE)tdbp;
  } // end of GetSubTable
Пример #4
0
void TDBASE::MarkDB(PGLOBAL, PTDB tdb2)
  {
  if (trace)
    htrc("DOS MarkDB: tdbp=%p tdb2=%p\n", this, tdb2);

  } // end of MarkDB
Пример #5
0
int TDBFMT::ReadBuffer(PGLOBAL g)
  {
  int  i, len, n, deb, fin, nwp, pos = 0, rc;
  bool bad = false;

  if ((rc = Txfp->ReadBuffer(g)) != RC_OK || !Fields)
    return rc;
  else
    ++Linenum;

  if (trace > 1)
    htrc("FMT: Row %d is '%s' rc=%d\n", Linenum, To_Line, rc);

  // Find the offsets and lengths of the columns for this row
  for (i = 0; i < Fields; i++) {
    if (!bad) {
      deb = fin = -1;

      if (!FldFormat[i]) {
        n = 0;
      } else if (FmtTest[i] == 1) {
        nwp = -1;
        n = sscanf(To_Line + pos, FldFormat[i], &deb, To_Fld, &fin, &nwp);
      } else {
        n = sscanf(To_Line + pos, FldFormat[i], &deb, To_Fld, &fin);

        if (n != 1 && (deb >= 0 || i == Fields - 1) && FmtTest[i] == 2) {
          // Missing optional field, not an error
          n = 1;

          if (i == Fields - 1)
            fin = deb = 0;
          else
            fin = deb;

          } // endif n

        nwp = fin;
      } // endif i

      if (n != 1 || deb < 0 || fin < 0 || nwp < 0) {
        // This is to avoid a very strange sscanf bug occuring
        // with fields that ends with a null character.
        // This bug causes subsequent sscanf to return in error,
        // so next lines are not parsed correctly.
        sscanf("a", "%*c");       // Seems to reset things Ok

        if (CheckErr()) {
          sprintf(g->Message, MSG(BAD_LINEFLD_FMT), Linenum, i + 1, Name);
          return RC_FX;
        } else if (Accept)
          bad = true;
        else
          return RC_NF;

        } // endif n...

      } // endif !bad

    if (!bad) {
      Offset[i] = pos + deb;
      len = fin - deb;
    } else {
      nwp = 0;
      Offset[i] = pos;
      len = 0;
    } // endif bad

//  if (Mode != MODE_UPDATE)
      Fldlen[i] = len;
//  else if (len > Fldlen[i]) {
//    sprintf(g->Message, MSG(FIELD_TOO_LONG), i+1, To_Tdb->RowNumber(g));
//    return RC_FX;
//  } else {
//    strncpy(Field[i], To_Line + pos, len);
//    Field[i][len] = '\0';
//  } // endif Mode

    pos += nwp;
    } // endfor i

  if (bad)
    Nerr++;
  else
    sscanf("a", "%*c");             // Seems to reset things Ok

  return rc;
  } // end of ReadBuffer
Пример #6
0
bool DOSFAM::OpenTableFile(PGLOBAL g)
  {
  char    opmode[4], filename[_MAX_PATH];
//int     ftype = Tdbp->GetFtype();
  MODE    mode = Tdbp->Mode;
  PDBUSER dbuserp = PlgGetUser(g);

  // This is required when using Unix files under Windows
  Bin = (Ending == 1);

  switch (mode) {
    case MODE_READ:
      strcpy(opmode, "r");
      break;
    case MODE_DELETE:
      if (!Tdbp->Next) {
        // Store the number of deleted lines
        DelRows = Cardinality(g);

        if (Blocked) {
          // Cardinality must return 0
          Block = 0;
          Last = Nrec;
          } // endif blocked

        // This will erase the entire file
        strcpy(opmode, "w");
        Tdbp->ResetSize();
        break;
        } // endif

      // Selective delete, pass thru
      Bin = true;
    case MODE_UPDATE:
      if ((UseTemp = Tdbp->IsUsingTemp(g))) {
        strcpy(opmode, "r");
        Bin = true;
      } else
        strcpy(opmode, "r+");

      break;
    case MODE_INSERT:
      strcpy(opmode, "a+");
      break;
    default:
      sprintf(g->Message, MSG(BAD_OPEN_MODE), mode);
      return true;
    } // endswitch Mode

  // For blocked I/O or for moving lines, open the table in binary
  strcat(opmode, (Blocked || Bin) ? "b" : "t");

  // Now open the file stream
  PlugSetPath(filename, To_File, Tdbp->GetPath());

  if (!(Stream = PlugOpenFile(g, filename, opmode))) {
    if (trace)
      htrc("%s\n", g->Message);

    return (mode == MODE_READ && errno == ENOENT)
            ? PushWarning(g, Tdbp) : true;
    } // endif Stream

  if (trace)
    htrc("File %s open Stream=%p mode=%s\n", filename, Stream, opmode);

  To_Fb = dbuserp->Openlist;     // Keep track of File block

  /*********************************************************************/
  /*  Allocate the line buffer. For mode Delete a bigger buffer has to */
  /*  be allocated because is it also used to move lines into the file.*/
  /*********************************************************************/
  return AllocateBuffer(g);
  } // end of OpenTableFile
Пример #7
0
PQRYRES DBFColumns(PGLOBAL g, char *dp, const char *fn, bool info)
  {
  int  buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
                   TYPE_INT,    TYPE_INT,   TYPE_SHORT};
  XFLD fldtyp[] = {FLD_NAME, FLD_TYPE,   FLD_TYPENAME,
                   FLD_PREC, FLD_LENGTH, FLD_SCALE};
  unsigned int length[] = {11, 6, 8, 10, 10, 6};
  char       buf[2], filename[_MAX_PATH];
  int        ncol = sizeof(buftyp) / sizeof(int);
  int        rc, type, len, field, fields;
  bool       bad;
  DBFHEADER  mainhead;
  DESCRIPTOR thisfield;
  FILE      *infile = NULL;
  PQRYRES    qrp;
  PCOLRES    crp;

  if (trace)
    htrc("DBFColumns: File %s\n", SVP(fn));

  if (!info) {
    if (!fn) {
      strcpy(g->Message, MSG(MISSING_FNAME));
      return NULL;
      } // endif fn

    /************************************************************************/
    /*  Open the input file.                                                */
    /************************************************************************/
    PlugSetPath(filename, fn, dp);

    if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb")))
      return NULL;

    /************************************************************************/
    /*  Get the first 32 bytes of the header.                               */
    /************************************************************************/
    if ((rc = dbfhead(g, infile, filename, &mainhead)) == RC_FX) {
      fclose(infile);
      return NULL;
      } // endif dbfhead

    /************************************************************************/
    /*  Allocate the structures used to refer to the result set.            */
    /************************************************************************/
    fields = mainhead.Fields;
  } else
    fields = 0;

  qrp = PlgAllocResult(g, ncol, fields, IDS_COLUMNS + 3,
                          buftyp, fldtyp, length, true, false);

  if (info || !qrp) {
  	if (infile)
      fclose(infile);
      
    return qrp;
    } // endif info

  if (trace) {
    htrc("Structure of %s\n", filename);
    htrc("headlen=%hd reclen=%hd degree=%d\n",
          mainhead.Headlen, mainhead.Reclen, fields);
    htrc("flags(iem)=%d,%d,%d cp=%d\n", mainhead.Incompleteflag,
          mainhead.Encryptflag, mainhead.Mdxflag, mainhead.Language);
    htrc("%hd records, last changed %02d/%02d/%d\n",
          mainhead.Records, mainhead.Filedate[1], mainhead.Filedate[2],
          mainhead.Filedate[0] + (mainhead.Filedate[0] <= 30) ? 2000 : 1900);
    htrc("Field    Type  Offset  Len  Dec  Set  Mdx\n");
    } // endif trace

  buf[1] = '\0';

  /**************************************************************************/
  /*  Do it field by field.  We are at byte 32 of file.                     */
  /**************************************************************************/
  for (field = 0; field < fields; field++) {
    bad = FALSE;

    if (fread(&thisfield, HEADLEN, 1, infile) != 1) {
      sprintf(g->Message, MSG(ERR_READING_REC), field+1, fn);
      goto err;
    } else
      len = thisfield.Length;

    if (trace)
      htrc("%-11s %c  %6ld  %3d   %2d  %3d  %3d\n",
           thisfield.Name, thisfield.Type, thisfield.Offset, len,
           thisfield.Decimals, thisfield.Setfield, thisfield.Mdxfield);

    /************************************************************************/
    /*  Now get the results into blocks.                                    */
    /************************************************************************/
    switch (thisfield.Type) {
      case 'C':                      // Characters
      case 'L':                      // Logical 'T' or 'F'
        type = TYPE_STRING;
        break;
      case 'N':
        type = (thisfield.Decimals) ? TYPE_DOUBLE
             : (len > 10) ? TYPE_BIGINT : TYPE_INT;
        break;
      case 'F':
        type = TYPE_DOUBLE;
        break;
      case 'D':
        type = TYPE_DATE;            // Is this correct ???
        break;
      default:
        if (!info) {
          sprintf(g->Message, MSG(BAD_DBF_TYPE), thisfield.Type);
          goto err;
          } // endif info

        type = TYPE_ERROR;
        bad = TRUE;
      } // endswitch Type

    crp = qrp->Colresp;                    // Column Name
    crp->Kdata->SetValue(thisfield.Name, field);
    crp = crp->Next;                       // Data Type
    crp->Kdata->SetValue((int)type, field);
    crp = crp->Next;                       // Type Name

    if (bad) {
      buf[0] = thisfield.Type;
      crp->Kdata->SetValue(buf, field);
    } else
      crp->Kdata->SetValue(GetTypeName(type), field);

    crp = crp->Next;                       // Precision
    crp->Kdata->SetValue((int)thisfield.Length, field);
    crp = crp->Next;                       // Length
    crp->Kdata->SetValue((int)thisfield.Length, field);
    crp = crp->Next;                       // Scale (precision)
    crp->Kdata->SetValue((int)thisfield.Decimals, field);
    } // endfor field

  qrp->Nblin = field;
  fclose(infile);

#if 0
  if (info) {
    /************************************************************************/
    /*  Prepare return message for dbfinfo command.                         */
    /************************************************************************/
    char buf[64];

    sprintf(buf,
      "Ver=%02x ncol=%hu nlin=%u lrecl=%hu headlen=%hu date=%02d/%02d/%02d",
      mainhead.Version, fields, mainhead.Records, mainhead.Reclen,
      mainhead.Headlen, mainhead.Filedate[0], mainhead.Filedate[1],
      mainhead.Filedate[2]);

    strcat(g->Message, buf);
    } // endif info
#endif // 0

  /**************************************************************************/
  /*  Return the result pointer for use by GetData routines.                */
  /**************************************************************************/
  return qrp;

 err:
  fclose(infile);
  return NULL;
  } // end of DBFColumns
Пример #8
0
PARRAY MakeValueArray(PGLOBAL g, PPARM pp)
  {
  int    n, valtyp = 0;
  size_t len = 0;
  PARRAY par;
  PPARM  parmp;

  if (!pp)
    return NULL;

  /*********************************************************************/
  /*  New version with values coming in a list.                        */
  /*********************************************************************/
  if ((valtyp = pp->Type) != TYPE_STRING)
    len = 1;

 	if (trace)
 		htrc("valtyp=%d len=%d\n", valtyp, len);
  		
  /*********************************************************************/
  /*  Firstly check the list and count the number of values in it.     */
  /*********************************************************************/
  for (n = 0, parmp = pp; parmp; n++, parmp = parmp->Next)
    if (parmp->Type != valtyp) {
      sprintf(g->Message, MSG(BAD_PARAM_TYPE), "MakeValueArray", parmp->Type);
      return NULL;
    } else if (valtyp == TYPE_STRING)
      len = MY_MAX(len, strlen((char*)parmp->Value));

  /*********************************************************************/
  /*  Make an array object with one block of the proper size.          */
  /*********************************************************************/
  par = new(g) ARRAY(g, valtyp, n, (int)len);

  if (par->GetResultType() == TYPE_ERROR)
    return NULL;          // Memory allocation error in ARRAY

  /*********************************************************************/
  /*  All is right now, fill the array block.                          */
  /*********************************************************************/
  for (parmp = pp; parmp; parmp = parmp->Next)
    switch (valtyp) {
      case TYPE_STRING:
        par->AddValue(g, (PSZ)parmp->Value);
        break;
      case TYPE_SHORT:
        par->AddValue(g, *(short*)parmp->Value);
        break;
      case TYPE_INT:
        par->AddValue(g, *(int*)parmp->Value);
        break;
      case TYPE_DOUBLE:
        par->AddValue(g, *(double*)parmp->Value);
        break;
      case TYPE_PCHAR:
        par->AddValue(g, parmp->Value);
        break;
      case TYPE_VOID:
        // Integer stored inside pp->Value
        par->AddValue(g, parmp->Intval);
        break;
      } // endswitch valtyp

  /*********************************************************************/
  /*  Send back resulting array.                                       */
  /*********************************************************************/
  return par;
  } // end of MakeValueArray
Пример #9
0
LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
  {
  char newname[_MAX_PATH];
  char direc[_MAX_DIR], defdir[_MAX_DIR], tmpdir[_MAX_DIR];
  char fname[_MAX_FNAME];
  char ftype[_MAX_EXT];
#if defined(__WIN__)
  char drive[_MAX_DRIVE], defdrv[_MAX_DRIVE];
#else
  char *drive = NULL, *defdrv = NULL;
#endif

  if (!strncmp(FileName, "//", 2) || !strncmp(FileName, "\\\\", 2)) {
    strcpy(pBuff, FileName);       // Remote file
    return pBuff;
    } // endif

  if (PlugIsAbsolutePath(FileName))
  {
    strcpy(pBuff, FileName); // FileName includes absolute path
    return pBuff;
  } // endif
  
#if !defined(__WIN__)
  if (*FileName == '~') {
    if (_fullpath(pBuff, FileName, _MAX_PATH)) {
      if (trace > 1)
        htrc("pbuff='%s'\n", pBuff);

     return pBuff;
    } else
      return FileName;     // Error, return unchanged name
      
    } // endif FileName  
#endif   // !__WIN__
  
  if (prefix && strcmp(prefix, ".") && !PlugIsAbsolutePath(defpath))
  {
    char tmp[_MAX_PATH];
    int len= snprintf(tmp, sizeof(tmp) - 1, "%s%s%s",
                      prefix, defpath, FileName);
    memcpy(pBuff, tmp, (size_t) len);
    pBuff[len]= '\0';
    return pBuff;
  }

  _splitpath(FileName, drive, direc, fname, ftype);

  if (defpath) {
    char c = defpath[strlen(defpath) - 1];

    strcpy(tmpdir, defpath);

    if (c != '/' && c != '\\')
      strcat(tmpdir, "/");

  } else
    strcpy(tmpdir, "./");

  _splitpath(tmpdir, defdrv, defdir, NULL, NULL);

  if (trace > 1) {
    htrc("after _splitpath: FileName=%s\n", FileName);
#if defined(__WIN__)
    htrc("drive=%s dir=%s fname=%s ext=%s\n", drive, direc, fname, ftype);
    htrc("defdrv=%s defdir=%s\n", defdrv, defdir);
#else
    htrc("dir=%s fname=%s ext=%s\n", direc, fname, ftype);
#endif
    } // endif trace

  if (drive && !*drive)
    strcpy(drive, defdrv);

  switch (*direc) {
    case '\0':
      strcpy(direc, defdir);
      break;
    case '\\':
    case '/':
      break;
    default:
      // This supposes that defdir ends with a SLASH
      strcpy(direc, strcat(defdir, direc));
    } // endswitch

  _makepath(newname, drive, direc, fname, ftype);

  if (trace > 1)
    htrc("newname='%s'\n", newname);

  if (_fullpath(pBuff, newname, _MAX_PATH)) {
    if (trace > 1)
      htrc("pbuff='%s'\n", pBuff);

    return pBuff;
  } else
    return FileName;     // Error, return unchanged name

  } // end of PlugSetPath
Пример #10
0
PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
                  const char *user, const char *pwd,
                  const char *table, const char *colpat,
                  int port, bool info)
  {
  int  buftyp[] = {TYPE_STRING, TYPE_SHORT,  TYPE_STRING, TYPE_INT,
                   TYPE_STRING, TYPE_SHORT,  TYPE_SHORT,  TYPE_SHORT,
                   TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING,
                   TYPE_STRING};
  XFLD fldtyp[] = {FLD_NAME, FLD_TYPE,  FLD_TYPENAME, FLD_PREC,
                   FLD_KEY,  FLD_SCALE, FLD_RADIX,    FLD_NULL,
                   FLD_REM,  FLD_NO,    FLD_DEFAULT,  FLD_EXTRA,
                   FLD_CHARSET};
  unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0};
  char   *fld, *colname, *chset, *fmt, v, buf[128], uns[16], zero[16];
  int     i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
  int     len, type, prec, rc, k = 0;
  PQRYRES qrp;
  PCOLRES crp;
  MYSQLC  myc;

  if (!port)
    port = mysqld_port;

  if (!info) {
    /********************************************************************/
    /*  Open the connection with the MySQL server.                      */
    /********************************************************************/
    if (myc.Open(g, host, db, user, pwd, port))
      return NULL;

    /********************************************************************/
    /*  Do an evaluation of the result size.                            */
    /********************************************************************/
    STRING cmd(g, 64, "SHOW FULL COLUMNS FROM ");
    bool   b = cmd.Append((PSZ)table);

    b |= cmd.Append(" FROM ");
    b |= cmd.Append((PSZ)(db ? db : PlgGetUser(g)->DBName));

    if (colpat) {
      b |= cmd.Append(" LIKE ");
      b |= cmd.Append((PSZ)colpat);
      } // endif colpat

    if (b) {
      strcpy(g->Message, "Out of memory");
      return NULL;
      } // endif b

    if (trace)
      htrc("MyColumns: cmd='%s'\n", cmd.GetStr());

    if ((n = myc.GetResultSize(g, cmd.GetStr())) < 0) {
      myc.Close();
      return NULL;
      } // endif n

    /********************************************************************/
    /*  Get the size of the name and default columns.                   */
    /********************************************************************/
    length[0] = myc.GetFieldLength(0);
//  length[10] = myc.GetFieldLength(5);
  } else {
    n = 0;
    length[0] = 128;
  } // endif info

  /**********************************************************************/
  /*  Allocate the structures used to refer to the result set.          */
  /**********************************************************************/
  if (!(qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
                             buftyp, fldtyp, length, false, true)))
    return NULL;

  // Some columns must be renamed
  for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
    switch (++i) {
      case  2: crp->Nulls = (char*)PlugSubAlloc(g, NULL, n); break;
      case  4: crp->Name = "Length";    break;
      case  5: crp->Name = "Key";       break;
      case 10: crp->Name = "Date_fmt";  break;
      case 11: crp->Name = "Default";   break;
      case 12: crp->Name = "Extra";     break;
      case 13: crp->Name = "Collation"; break;
      } // endswitch i

  if (info)
    return qrp;

  /**********************************************************************/
  /*  Now get the results into blocks.                                  */
  /**********************************************************************/
  for (i = 0; i < n; /*i++*/) {
    if ((rc = myc.Fetch(g, -1)) == RC_FX) {
      myc.Close();
      return NULL;
    } else if (rc == RC_EF)
      break;

    // Get column name
    colname = myc.GetCharField(0);
    crp = qrp->Colresp;                    // Column_Name
    crp->Kdata->SetValue(colname, i);

    // Get type, type name, precision, unsigned and zerofill
    chset = myc.GetCharField(2);
    fld = myc.GetCharField(1);
    prec = 0;
    len = 0;
    v = (chset && !strcmp(chset, "binary")) ? 'B' : 0;
    *uns = 0;
    *zero = 0;

    switch ((nf = sscanf(fld, "%[^(](%d,%d", buf, &len, &prec))) {
      case 3:
        nf = sscanf(fld, "%[^(](%d,%d) %s %s", buf, &len, &prec, uns, zero);
        break;
      case 2:
        nf = sscanf(fld, "%[^(](%d) %s %s", buf, &len, uns, zero) + 1;
        break;
      case 1:
        nf = sscanf(fld, "%s %s %s", buf, uns, zero) + 2;
        break;
      default:
        sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld);
        myc.Close();
        return NULL;
      } // endswitch nf

    if ((type = MYSQLtoPLG(buf, &v)) == TYPE_ERROR) {
      if (v == 'K') {
        // Skip this column
        sprintf(g->Message, "Column %s skipped (unsupported type %s)",
                colname, buf);
        PushWarning(g, thd);
        continue;
        } // endif v

      sprintf(g->Message, "Column %s unsupported type %s", colname, buf);
      myc.Close();
      return NULL;
    } else if (type == TYPE_STRING) {
      if (v == 'X') {
        len = GetConvSize();
        sprintf(g->Message, "Column %s converted to varchar(%d)",
                colname, len);
        PushWarning(g, thd);
        v = 'V';
      } else
        len = MY_MIN(len, 4096);

    } // endif type

    qrp->Nblin++;
    crp = crp->Next;                       // Data_Type
    crp->Kdata->SetValue(type, i);

    switch (nf) {
      case 5:  crp->Nulls[i] = 'Z'; break;
      case 4:  crp->Nulls[i] = 'U'; break;
      default: crp->Nulls[i] = v;   break;
      } // endswitch nf

    crp = crp->Next;                       // Type_Name
    crp->Kdata->SetValue(buf, i);

    if (type == TYPE_DATE) {
      // When creating tables we do need info about date columns
      fmt = MyDateFmt(buf);
      len = strlen(fmt);
    } else
      fmt = NULL;

    crp = crp->Next;                       // Precision
    crp->Kdata->SetValue(len, i);

    crp = crp->Next;                       // key (was Length)
    fld = myc.GetCharField(4);
    crp->Kdata->SetValue(fld, i);

    crp = crp->Next;                       // Scale
    crp->Kdata->SetValue(prec, i);

    crp = crp->Next;                       // Radix
    crp->Kdata->SetValue(0, i);

    crp = crp->Next;                       // Nullable
    fld = myc.GetCharField(3);
    crp->Kdata->SetValue((toupper(*fld) == 'Y') ? 1 : 0, i);

    crp = crp->Next;                       // Remark
    fld = myc.GetCharField(8);
    crp->Kdata->SetValue(fld, i);

    crp = crp->Next;                       // Date format
//  crp->Kdata->SetValue((fmt) ? fmt : (char*) "", i);
    crp->Kdata->SetValue(fmt, i);

    crp = crp->Next;                       // New (default)
    fld = myc.GetCharField(5);
    crp->Kdata->SetValue(fld, i);

    crp = crp->Next;                       // New (extra)
    fld = myc.GetCharField(6);
    crp->Kdata->SetValue(fld, i);

    crp = crp->Next;                       // New (charset)
    fld = chset;
    crp->Kdata->SetValue(fld, i);

    i++;                                   // Can be skipped
    } // endfor i

#if 0
  if (k > 1) {
    // Multicolumn primary key
    PVBLK vbp = qrp->Colresp->Next->Next->Next->Next->Kdata;

    for (i = 0; i < n; i++)
      if (vbp->GetIntValue(i))
        vbp->SetValue(k, i);

    } // endif k
#endif // 0

  /**********************************************************************/
  /*  Close MySQL connection.                                           */
  /**********************************************************************/
  myc.Close();

  /**********************************************************************/
  /*  Return the result pointer for use by GetData routines.            */
  /**********************************************************************/
  return qrp;
  } // end of MyColumns
Пример #11
0
bool DBFFAM::OpenTableFile(PGLOBAL g)
  {
  char    opmode[4], filename[_MAX_PATH];
//int     ftype = Tdbp->GetFtype();
  MODE    mode = Tdbp->GetMode();
  PDBUSER dbuserp = PlgGetUser(g);

  switch (mode) {
    case MODE_READ:
      strcpy(opmode, "rb");
      break;
    case MODE_DELETE:
      if (!Tdbp->GetNext()) {
        // Store the number of deleted lines
        DelRows = -1;      // Means all lines deleted
//      DelRows = Cardinality(g); no good because of soft deleted lines

        // This will erase the entire file
        strcpy(opmode, "w");
        Tdbp->ResetSize();
        Records = 0;
        break;
        } // endif

      // Selective delete, pass thru
    case MODE_UPDATE:
      UseTemp = Tdbp->IsUsingTemp(g);
      strcpy(opmode, (UseTemp) ? "rb" : "r+b");
      break;
    case MODE_INSERT:
      // Must be in text mode to remove an eventual EOF character
      strcpy(opmode, "a+");
      break;
    default:
      sprintf(g->Message, MSG(BAD_OPEN_MODE), mode);
      return true;
    } // endswitch Mode

  // Now open the file stream
  PlugSetPath(filename, To_File, Tdbp->GetPath());

  if (!(Stream = PlugOpenFile(g, filename, opmode))) {
#ifdef DEBTRACE
 htrc("%s\n", g->Message);
#endif
    return (mode == MODE_READ && errno == ENOENT)
            ? PushWarning(g, Tdbp) : true;
    } // endif Stream

#ifdef DEBTRACE
 htrc("File %s is open in mode %s\n", filename, opmode);
#endif

  To_Fb = dbuserp->Openlist;     // Keep track of File block

  /*********************************************************************/
  /*  Allocate the line buffer. For mode Delete a bigger buffer has to */
  /*  be allocated because is it also used to move lines into the file.*/
  /*********************************************************************/
  return AllocateBuffer(g);
  } // end of OpenTableFile
Пример #12
0
int DOSFAM::DeleteRecords(PGLOBAL g, int irc)
  {
  bool moved;
  int curpos = ftell(Stream);

  /*********************************************************************/
  /*  There is an alternative here:                                    */
  /*  1 - use a temporary file in which are copied all not deleted     */
  /*      lines, at the end the original file will be deleted and      */
  /*      the temporary file renamed to the original file name.        */
  /*  2 - directly move the not deleted lines inside the original      */
  /*      file, and at the end erase all trailing records.             */
  /*  This will be experimented, but method 1 must be used for Unix as */
  /*  the function needed to erase trailing records is not available.  */
  /*********************************************************************/
  if (trace)
    htrc(
  "DOS DeleteDB: rc=%d UseTemp=%d curpos=%d Fpos=%d Tpos=%d Spos=%d\n",
                irc, UseTemp, curpos, Fpos, Tpos, Spos);

  if (irc != RC_OK) {
    /*******************************************************************/
    /*  EOF: position Fpos at the end-of-file position.                */
    /*******************************************************************/
    fseek(Stream, 0, SEEK_END);
    Fpos = ftell(Stream);

    if (trace)
      htrc("Fpos placed at file end=%d\n", Fpos);

    } // endif irc

  if (Tpos == Spos) {
    /*******************************************************************/
    /*  First line to delete, Open temporary file.                     */
    /*******************************************************************/
    if (UseTemp) {
      if (OpenTempFile(g))
        return RC_FX;

    } else {
      /*****************************************************************/
      /*  Move of eventual preceeding lines is not required here.      */
      /*  Set the target file as being the source file itself.         */
      /*  Set the future Tpos, and give Spos a value to block copying. */
      /*****************************************************************/
      T_Stream = Stream;
      Spos = Tpos = Fpos;
    } // endif UseTemp

    } // endif Tpos == Spos

  /*********************************************************************/
  /*  Move any intermediate lines.                                     */
  /*********************************************************************/
  if (MoveIntermediateLines(g, &moved))
    return RC_FX;

  if (irc == RC_OK) {
    /*******************************************************************/
    /*  Reposition the file pointer and set Spos.                      */
    /*******************************************************************/
    if (!UseTemp || moved)
      if (fseek(Stream, curpos, SEEK_SET)) {
        sprintf(g->Message, MSG(FSETPOS_ERROR), 0);
        return RC_FX;
        } // endif

    Spos = GetNextPos();                     // New start position

    if (trace)
      htrc("after: Tpos=%d Spos=%d\n", Tpos, Spos);

  } else {
    /*******************************************************************/
    /*  Last call after EOF has been reached.                          */
    /*  The UseTemp case is treated in CloseTableFile.                 */
    /*******************************************************************/
    if (!UseTemp) {
      /*****************************************************************/
      /*  Because the chsize functionality is only accessible with a   */
      /*  system call we must close the file and reopen it with the    */
      /*  open function (_fopen for MS ??) this is still to be checked */
      /*  for compatibility with Text files and other OS's.            */
      /*****************************************************************/
      char filename[_MAX_PATH];
      int  h;                           // File handle, return code

      PlugSetPath(filename, To_File, Tdbp->GetPath());
      /*rc=*/ PlugCloseFile(g, To_Fb);

      if ((h= global_open(g, MSGID_OPEN_STRERROR, filename, O_WRONLY)) <= 0)
        return RC_FX;

      /*****************************************************************/
      /*  Remove extra records.                                        */
      /*****************************************************************/
#if defined(UNIX)
      if (ftruncate(h, (off_t)Tpos)) {
        sprintf(g->Message, MSG(TRUNCATE_ERROR), strerror(errno));
        close(h);
        return RC_FX;
        } // endif
#else
      if (chsize(h, Tpos)) {
        sprintf(g->Message, MSG(CHSIZE_ERROR), strerror(errno));
        close(h);
        return RC_FX;
        } // endif
#endif

      close(h);

      if (trace)
        htrc("done, h=%d irc=%d\n", h, irc);

      } // endif !UseTemp

  } // endif irc

  return RC_OK;                                      // All is correct
  } // end of DeleteRecords
Пример #13
0
int DOSFAM::ReadBuffer(PGLOBAL g)
  {
  char *p;
  int   rc;

  if (!Stream)
    return RC_EF;

  if (trace)
    htrc("ReadBuffer: Tdbp=%p To_Line=%p Placed=%d\n",
                      Tdbp, Tdbp->To_Line, Placed); 

  if (!Placed) {
    /*******************************************************************/
    /*  Record file position in case of UPDATE or DELETE.              */
    /*******************************************************************/
    if (RecordPos(g))
      return RC_FX;

    CurBlk = (int)Rows++;

     if (trace)
      htrc("ReadBuffer: CurBlk=%d\n", CurBlk); 

  } else
    Placed = false;

  if (trace)
    htrc(" About to read: stream=%p To_Buf=%p Buflen=%d\n",
                          Stream, To_Buf, Buflen);

  if (fgets(To_Buf, Buflen, Stream)) {
    p = To_Buf + strlen(To_Buf) - 1;

    if (trace)
      htrc(" Read: To_Buf=%p p=%c\n", To_Buf, To_Buf, p);

#if defined(UNIX)
    if (true) {
      // Data files can be imported from Windows (having CRLF)
#else
    if (Bin) {
      // Data file is read in binary so CRLF remains
#endif
      if (*p == '\n' || *p == '\r') {
        // is this enough for Unix ???
        *p = '\0';          // Eliminate ending CR or LF character

        if (p > To_Buf) {
          // is this enough for Unix ???
          p--;

          if (*p == '\n' || *p == '\r')
            *p = '\0';      // Eliminate ending CR or LF character

          } // endif To_Buf

        } // endif p

    } else if (*p == '\n')
      *p = '\0';          // Eliminate ending new-line character

    if (trace)
      htrc(" To_Buf='%s'\n", To_Buf);

    strcpy(Tdbp->To_Line, To_Buf);
    num_read++;
    rc = RC_OK;
  } else if (feof(Stream)) {
    rc = RC_EF;
  } else {
#if defined(UNIX)
    sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(0));
#else
    sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL));
#endif

    if (trace)
      htrc("%s\n", g->Message);

    rc = RC_FX;
  } // endif's fgets

  if (trace)
    htrc("ReadBuffer: rc=%d\n", rc);

  IsRead = true;
  return rc;
  } // end of ReadBuffer

/***********************************************************************/
/*  WriteBuffer: File write routine for DOS access method.             */
/***********************************************************************/
int DOSFAM::WriteBuffer(PGLOBAL g)
  {
  char *crlf = "\n";
  int  curpos = 0;
  bool  moved = true;

  // T_Stream is the temporary stream or the table file stream itself
  if (!T_Stream)
    if (UseTemp && Tdbp->Mode == MODE_UPDATE) {
      if (OpenTempFile(g))
        return RC_FX;

    } else
      T_Stream = Stream;

  if (Tdbp->Mode == MODE_UPDATE) {
    /*******************************************************************/
    /*  Here we simply rewrite a record on itself. There are two cases */
    /*  were another method should be used, a/ when Update apply to    */
    /*  the whole file, b/ when updating the last field of a variable  */
    /*  length file. The method could be to rewrite a new file, then   */
    /*  to erase the old one and rename the new updated file.          */
    /*******************************************************************/
    curpos = ftell(Stream);

    if (trace)
      htrc("Last : %d cur: %d\n", Fpos, curpos);

    if (UseTemp) {
      /*****************************************************************/
      /*  We are using a temporary file. Before writing the updated    */
      /*  record, we must eventually copy all the intermediate records */
      /*  that have not been updated.                                  */
      /*****************************************************************/
      if (MoveIntermediateLines(g, &moved))
        return RC_FX;

      Spos = curpos;                          // New start position
    } else
      // Update is directly written back into the file,
      //   with this (fast) method, record size cannot change.
      if (fseek(Stream, Fpos, SEEK_SET)) {
        sprintf(g->Message, MSG(FSETPOS_ERROR), 0);
        return RC_FX;
        } // endif

    } // endif mode

  /*********************************************************************/
  /*  Prepare the write buffer.                                        */
  /*********************************************************************/
#if defined(WIN32)
  if (Bin)
    crlf = "\r\n";
#endif   // WIN32
  strcat(strcpy(To_Buf, Tdbp->To_Line), crlf);

  /*********************************************************************/
  /*  Now start the writing process.                                   */
  /*********************************************************************/
  if ((fputs(To_Buf, T_Stream)) == EOF) {
    sprintf(g->Message, MSG(FPUTS_ERROR), strerror(errno));
    return RC_FX;
    } // endif EOF

  if (Tdbp->Mode == MODE_UPDATE && moved)
    if (fseek(Stream, curpos, SEEK_SET)) {
      sprintf(g->Message, MSG(FSEEK_ERROR), strerror(errno));
      return RC_FX;
      } // endif

  if (trace)
    htrc("write done\n");

  return RC_OK;
  } // end of WriteBuffer
Пример #14
0
void XINCOL::WriteColumn(PGLOBAL g)
  {
  char   *p;
  bool    rc;
  PTDBXIN tdbp = (PTDBXIN)To_Tdb;

  if (trace > 1)
    htrc("XIN WriteColumn: col %s R%d coluse=%.4X status=%.4X\n",
          Name, tdbp->GetTdb_No(), ColUse, Status);

  /*********************************************************************/
  /*  Get the string representation of Value according to column type. */
  /*********************************************************************/
  if (Value != To_Val)
    Value->SetValue_pval(To_Val, false);    // Convert the updated value

  p = Value->GetCharString(Valbuf);

  if (strlen(p) > (unsigned)Long) {
    sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, Long);
    longjmp(g->jumper[g->jump_level], 31);
  } else if (Flag == 1) {
    if (tdbp->Mode == MODE_UPDATE) {
      strcpy(g->Message, MSG(NO_SEC_UPDATE));
      longjmp(g->jumper[g->jump_level], 31);
    } else if (*p) {
      tdbp->Section = p;
    } else
      tdbp->Section = NULL;

    return;
  } else if (Flag == 2) {
    if (tdbp->Mode == MODE_UPDATE) {
      strcpy(g->Message, MSG(NO_KEY_UPDATE));
      longjmp(g->jumper[g->jump_level], 31);
    } else if (*p) {
      tdbp->Keycur = p;
    } else
      tdbp->Keycur = NULL;

    return;
  } else if (!tdbp->Section || !tdbp->Keycur) {
    strcpy(g->Message, MSG(SEC_KEY_FIRST));
    longjmp(g->jumper[g->jump_level], 31);
  } // endif's

  /*********************************************************************/
  /*  Updating must be done only when not in checking pass.            */
  /*********************************************************************/
  if (Status) {
    rc = WritePrivateProfileString(tdbp->Section, tdbp->Keycur, p, tdbp->Ifile);
    
    if (!rc) {
      sprintf(g->Message, "Error %d writing to %s", 
                          GetLastError(), tdbp->Ifile);
      longjmp(g->jumper[g->jump_level], 31);
      } // endif rc

    } // endif Status

  } // end of WriteColumn
Пример #15
0
void DBFFAM::CloseTableFile(PGLOBAL g, bool abort)
  {
  int rc = RC_OK, wrc = RC_OK;
  MODE mode = Tdbp->GetMode();

  Abort = abort;

  // Closing is True if last Write was in error
  if (mode == MODE_INSERT && CurNum && !Closing) {
    // Some more inserted lines remain to be written
    Rbuf = CurNum--;
//  Closing = true;
    wrc = WriteBuffer(g);
  } else if (mode == MODE_UPDATE || mode == MODE_DELETE) {
    if (Modif && !Closing) {
      // Last updated block remains to be written
      Closing = true;
      wrc = WriteModifiedBlock(g);
      } // endif Modif

    if (UseTemp && T_Stream && wrc == RC_OK) {
      if (!Abort) {
        // Copy any remaining lines
        bool b;
    
        Fpos = Tdbp->Cardinality(g);
        Abort = MoveIntermediateLines(g, &b) != RC_OK;
        } // endif Abort

      // Delete the old file and rename the new temp file.
      RenameTempFile(g);
      goto fin;
      } // endif UseTemp

  } // endif's mode

  if (Tdbp->GetMode() == MODE_INSERT) {
    int n = ftell(Stream) - Headlen;

    rc = PlugCloseFile(g, To_Fb);

    if (n >= 0 && !(n % Lrecl)) {
      n /= Lrecl;                       // New number of lines

      if (n > Records) {
        // Update the number of rows in the file header
        char filename[_MAX_PATH];

        PlugSetPath(filename, To_File, Tdbp->GetPath());
        if ((Stream= global_fopen(g, MSGID_OPEN_MODE_STRERROR, filename, "r+b")))
        {
          fseek(Stream, 4, SEEK_SET);     // Get header.Records position
          fwrite(&n, sizeof(int), 1, Stream);
          fclose(Stream);
          Stream= NULL;
          Records= n;                    // Update Records value
        }
      } // endif n

    } // endif n

  } else  // Finally close the file
    rc = PlugCloseFile(g, To_Fb);

 fin:
  if (trace)
    htrc("DBF CloseTableFile: closing %s mode=%d wrc=%d rc=%d\n",
         To_File, mode, wrc, rc);

  Stream = NULL;           // So we can know whether table is open
  } // end of CloseTableFile
Пример #16
0
bool TDBTBM::OpenDB(PGLOBAL g)
  {
  if (trace)
    htrc("TBM OpenDB: tdbp=%p tdb=R%d use=%d key=%p mode=%d\n",
                      this, Tdb_No, Use, To_Key_Col, Mode);

  if (Use == USE_OPEN) {
    /*******************************************************************/
    /*  Table already open, replace it at its beginning.               */
    /*******************************************************************/
    ResetDB();
    return (Tdbp) ? Tdbp->OpenDB(g) : false;  // Re-open fist table
    } // endif use

#if 0
  /*********************************************************************/
  /*  When GetMaxsize was called, To_CondFil was not set yet.          */
  /*********************************************************************/
  if (To_CondFil && Tablist) {
    Tablist = NULL;
    Nbc = 0;
    } // endif To_CondFil
#endif // 0

  /*********************************************************************/
  /*  Make the table list.                                             */
  /*********************************************************************/
  if (/*!Tablist &&*/ InitTableList(g))
    return TRUE;

  /*********************************************************************/
  /*  Open all remote tables of the list.                              */
  /*********************************************************************/
  if (OpenTables(g))
    return TRUE;

  /*********************************************************************/
  /*  Proceed with local tables.                                       */
  /*********************************************************************/
  if ((CurTable = Tablist)) {
    Tdbp = (PTDBASE)CurTable->GetTo_Tdb();
//  Tdbp->SetMode(Mode);

    // Check and initialize the subtable columns
    for (PCOL cp = Columns; cp; cp = cp->GetNext())
      if (cp->GetAmType() == TYPE_AM_TABID)
        cp->COLBLK::Reset();
      else if (((PPRXCOL)cp)->Init(g, NULL) && !Accept)
        return TRUE;
        
    if (trace)
      htrc("Opening subtable %s\n", Tdbp->GetName());

    // Now we can safely open the table
    if (Tdbp->OpenDB(g))
      return TRUE;

    } // endif *Tablist

  Use = USE_OPEN;
  return FALSE;
  } // end of OpenDB
Пример #17
0
int TDBCSV::ReadBuffer(PGLOBAL g)
  {
  char *p1, *p2, *p = NULL;
  int   i, n, len, rc = Txfp->ReadBuffer(g);
  bool  bad = false;

  if (trace > 1)
    htrc("CSV: Row is '%s' rc=%d\n", To_Line, rc);

  if (rc != RC_OK || !Fields)
    return rc;
  else
    p2 = To_Line;

  // Find the offsets and lengths of the columns for this row
  for (i = 0; i < Fields; i++) {
    if (!bad) {
      if (Qot && *p2 == Qot) {                // Quoted field
        for (n = 0, p1 = ++p2; (p = strchr(p1, Qot)); p1 = p + 2)
          if (*(p + 1) == Qot)
            n++;                              // Doubled internal quotes
          else
            break;                            // Final quote

        if (p) {
          len = p++ - p2;

//        if (Sep != ' ')
//          for (; *p == ' '; p++) ;          // Skip blanks

          if (*p != Sep && i != Fields - 1) { // Should be the separator
            if (CheckErr()) {
              sprintf(g->Message, MSG(MISSING_FIELD),
                                  i+1, Name, RowNumber(g));
              return RC_FX;
            } else if (Accept)
              bad = true;
            else
              return RC_NF;

            } // endif p

          if (n) {
            int j, k;

            // Suppress the double of internal quotes
            for (j = k = 0; j < len; j++, k++) {
              if (p2[j] == Qot)
                j++;                          // skip first one

              p2[k] = p2[j];
              } // endfor i, j

            len -= n;
            } // endif n

        } else if (CheckErr()) {
          sprintf(g->Message, MSG(BAD_QUOTE_FIELD),
                              Name, i+1, RowNumber(g));
          return RC_FX;
        } else if (Accept) {
          len = strlen(p2);
          bad = true;
        } else
          return RC_NF;

      } else if ((p = strchr(p2, Sep)))
        len = p - p2;
      else if (i == Fields - 1)
        len = strlen(p2);
      else if (Accept && Maxerr == 0) {
        len = strlen(p2);
        bad = true;
      } else if (CheckErr()) {
        sprintf(g->Message, MSG(MISSING_FIELD), i+1, Name, RowNumber(g));
        return RC_FX;
      } else if (Accept) {
        len = strlen(p2);
        bad = true;
      } else
        return RC_NF;

    } else
      len = 0;

    Offset[i] = p2 - To_Line;

    if (Mode != MODE_UPDATE)
      Fldlen[i] = len;
    else if (len > Fldlen[i]) {
      sprintf(g->Message, MSG(FIELD_TOO_LONG), i+1, RowNumber(g));
      return RC_FX;
    } else {
      strncpy(Field[i], p2, len);
      Field[i][len] = '\0';
    } // endif Mode

    if (p)
      p2 = p + 1;

    } // endfor i

  return rc;
  } // end of ReadBuffer
Пример #18
0
PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
                               int prec, bool check, bool blank, bool un)
  {
  PVBLK blkp;

  if (trace)
    htrc("AVB: mp=%p type=%d nval=%d len=%d check=%u blank=%u\n",
         mp, type, nval, len, check, blank);

  switch (type) {
    case TYPE_STRING:
    case TYPE_DECIM:
      if (len)
        blkp = new(g) CHRBLK(mp, nval, len, prec, blank);
      else
        blkp = new(g) STRBLK(g, mp, nval);

      break;
    case TYPE_SHORT:
      if (un)
        blkp = new(g) TYPBLK<ushort>(mp, nval, type, 0, true);
      else
        blkp = new(g) TYPBLK<short>(mp, nval, type);

      break;
    case TYPE_INT:
      if (un)
        blkp = new(g) TYPBLK<uint>(mp, nval, type, 0, true);
      else
        blkp = new(g) TYPBLK<int>(mp, nval, type);

      break;
    case TYPE_DATE:        // ?????
      blkp = new(g) DATBLK(mp, nval);
      break;
    case TYPE_BIGINT:
      if (un)
        blkp = new(g) TYPBLK<ulonglong>(mp, nval, type, 0, true);
      else
        blkp = new(g) TYPBLK<longlong>(mp, nval, type);

      break;
    case TYPE_DOUBLE:
      blkp = new(g) TYPBLK<double>(mp, nval, type, prec);
      break;
    case TYPE_TINY:
      if (un)
        blkp = new(g) TYPBLK<uchar>(mp, nval, type, 0, true);
      else
        blkp = new(g) TYPBLK<char>(mp, nval, type);

      break;
    case TYPE_PCHAR:
      blkp = new(g) PTRBLK(g, mp, nval);
      break;
    default:
      sprintf(g->Message, MSG(BAD_VALBLK_TYPE), type);
      return NULL;
    } // endswitch Type

  return (blkp->Init(g, check)) ? NULL : blkp;
  } // end of AllocValBlock
Пример #19
0
bool TDBCSV::PrepareWriting(PGLOBAL g)
  {
  char sep[2], qot[2];
  int  i, nlen, oldlen = strlen(To_Line);

  if (trace > 1)
    htrc("CSV WriteDB: R%d Mode=%d key=%p link=%p\n",
          Tdb_No, Mode, To_Key_Col, To_Link);

  // Before writing the line we must check its length
  if ((nlen = CheckWrite(g)) < 0)
    return true;

  // Before writing the line we must make it
  sep[0] = Sep;
  sep[1] = '\0';
  qot[0] = Qot;
  qot[1] = '\0';
  *To_Line = '\0';

  for (i = 0; i < Fields; i++) {
    if (i)
      strcat(To_Line, sep);

    if (Field[i])
      if (!strlen(Field[i])) {
        // Generally null fields are not quoted
        if (Quoted > 2)
          // Except if explicitely required
          strcat(strcat(To_Line, qot), qot);

      } else if (Qot && (strchr(Field[i], Sep) || *Field[i] == Qot
              || Quoted > 1 || (Quoted == 1 && !Fldtyp[i])))
        if (strchr(Field[i], Qot)) {
          // Field contains quotes that must be doubled
          int j, k = strlen(To_Line), n = strlen(Field[i]);

          To_Line[k++] = Qot;

          for (j = 0; j < n; j++) {
            if (Field[i][j] == Qot)
              To_Line[k++] = Qot;

            To_Line[k++] = Field[i][j];
            } // endfor j

          To_Line[k++] = Qot;
          To_Line[k] = '\0';
        } else
          strcat(strcat(strcat(To_Line, qot), Field[i]), qot);

      else
        strcat(To_Line, Field[i]);

    } // endfor i

#if defined(_DEBUG)
  assert ((unsigned)nlen == strlen(To_Line));
#endif

  if (Mode == MODE_UPDATE && nlen < oldlen
                          && !((PDOSFAM)Txfp)->GetUseTemp()) {
    // In Update mode with no temp file, line length must not change
    To_Line[nlen] = Sep;

    for (nlen++; nlen < oldlen; nlen++)
      To_Line[nlen] = ' ';

    To_Line[nlen] = '\0';
    } // endif

  if (trace > 1)
    htrc("Write: line is=%s", To_Line);

  return false;
  } // end of PrepareWriting
Пример #20
0
PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
                   int hdr, int mxr, bool info)
  {
  static int  buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
                          TYPE_INT,   TYPE_INT, TYPE_SHORT};
  static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE,   FLD_TYPENAME,
                          FLD_PREC, FLD_LENGTH, FLD_SCALE};
  static unsigned int length[] = {6, 6, 8, 10, 10, 6};
  char   *p, *colname[MAXCOL], dechar, filename[_MAX_PATH], buf[4096];
  int     i, imax, hmax, n, nerr, phase, blank, digit, dec, type;
  int     ncol = sizeof(buftyp) / sizeof(int);
  int     num_read = 0, num_max = 10000000;     // Statistics
  int     len[MAXCOL], typ[MAXCOL], prc[MAXCOL];
  FILE   *infile;
  PQRYRES qrp;
  PCOLRES crp;

  if (info) {
    imax = hmax = 0;
    length[0] = 128;
    goto skipit;
    } // endif info

//      num_max = atoi(p+1);             // Max num of record to test
#if defined(WIN32)
  if (sep == ',' || strnicmp(setlocale(LC_NUMERIC, NULL), "French", 6))
    dechar = '.';
  else
    dechar = ',';
#else   // !WIN32
  dechar = '.';
#endif  // !WIN32

  if (trace)
    htrc("File %s sep=%c q=%c hdr=%d mxr=%d\n",
          SVP(fn), sep, q, hdr, mxr);

  if (!fn) {
    strcpy(g->Message, MSG(MISSING_FNAME));
    return NULL;
    } // endif fn

  imax = hmax = nerr = 0;
  mxr = MY_MAX(0, mxr);

  for (i = 0; i < MAXCOL; i++) {
    colname[i] = NULL;
    len[i] = 0;
    typ[i] = TYPE_UNKNOWN;
    prc[i] = 0;
    } // endfor i

  /*********************************************************************/
  /*  Open the input file.                                             */
  /*********************************************************************/
  PlugSetPath(filename, fn, PlgGetDataPath(g));

  if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "r")))
    return NULL;

  if (hdr) {
    /*******************************************************************/
    /*  Make the column names from the first line.                     */
    /*******************************************************************/
    phase = 0;

    if (fgets(buf, sizeof(buf), infile)) {
      n = strlen(buf) + 1;
      buf[n - 2] = '\0';
#if defined(UNIX)
      // The file can be imported from Windows 
      if (buf[n - 3] == '\r')
        buf[n - 3] = 0;
#endif   // UNIX
      p = (char*)PlugSubAlloc(g, NULL, n);
      memcpy(p, buf, n);

      //skip leading blanks
      for (; *p == ' '; p++) ;

      if (q && *p == q) {
        // Header is quoted
        p++;
        phase = 1;
        } // endif q

      colname[0] = p;
    } else {
      sprintf(g->Message, MSG(FILE_IS_EMPTY), fn);
      goto err;
    } // endif's

    for (i = 1; *p; p++)
      if (phase == 1 && *p == q) {
        *p = '\0';
        phase = 0;
      } else if (*p == sep && !phase) {
        *p = '\0';

        //skip leading blanks
        for (; *(p+1) == ' '; p++) ;

        if (q && *(p+1) == q) {
          // Header is quoted
          p++;
          phase = 1;
          } // endif q

        colname[i++] = p + 1;
        } // endif sep

    num_read++;
    imax = hmax = i;

    for (i = 0; i < hmax; i++)
      length[0] = MY_MAX(length[0], strlen(colname[i]));

    } // endif hdr

  for (num_read++; num_read <= num_max; num_read++) {
    /*******************************************************************/
    /*  Now start the reading process. Read one line.                  */
    /*******************************************************************/
    if (fgets(buf, sizeof(buf), infile)) {
      n = strlen(buf);
      buf[n - 1] = '\0';
#if defined(UNIX)
      // The file can be imported from Windows 
      if (buf[n - 2] == '\r')
        buf[n - 2] = 0;
#endif   // UNIX
    } else if (feof(infile)) {
      sprintf(g->Message, MSG(EOF_AFTER_LINE), num_read -1);
      break;
    } else {
      sprintf(g->Message, MSG(ERR_READING_REC), num_read, fn);
      goto err;
    } // endif's

    /*******************************************************************/
    /*  Make the test for field lengths.                               */
    /*******************************************************************/
    i = n = phase = blank = digit = dec = 0;

    for (p = buf; *p; p++)
      if (*p == sep) {
        if (phase != 1) {
          if (i == MAXCOL - 1) {
            sprintf(g->Message, MSG(TOO_MANY_FIELDS), num_read, fn);
            goto err;
            } // endif i

          if (n) {
            len[i] = MY_MAX(len[i], n);
            type = (digit || (dec && n == 1)) ? TYPE_STRING
                 : (dec) ? TYPE_DOUBLE : TYPE_INT;
            typ[i] = MY_MIN(type, typ[i]);
            prc[i] = MY_MAX((typ[i] == TYPE_DOUBLE) ? (dec - 1) : 0, prc[i]);
            } // endif n

          i++;
          n = phase = blank = digit = dec = 0;
        } else          // phase == 1
          n++;

      } else if (*p == ' ') {
        if (phase < 2)
          n++;

        if (blank)
          digit = 1;

      } else if (*p == q) {
        if (phase == 0) {
          if (blank)
            if (++nerr > mxr) {
              sprintf(g->Message, MSG(MISPLACED_QUOTE), num_read);
              goto err;
            } else
              goto skip;

          n = 0;
          phase = digit = 1;
        } else if (phase == 1) {
          if (*(p+1) == q) {
            // This is currently not implemented for CSV tables
//          if (++nerr > mxr) {
//            sprintf(g->Message, MSG(QUOTE_IN_QUOTE), num_read);
//            goto err;
//          } else
//            goto skip;

            p++;
            n++;
          } else
            phase = 2;

        } else if (++nerr > mxr) {      // phase == 2
          sprintf(g->Message, MSG(MISPLACED_QUOTE), num_read);
          goto err;
        } else
          goto skip;

      } else {
        if (phase == 2)
          if (++nerr > mxr) {
            sprintf(g->Message, MSG(MISPLACED_QUOTE), num_read);
            goto err;
          } else
            goto skip;

        // isdigit cannot be used here because of debug assert
        if (!strchr("0123456789", *p)) {
          if (!digit && *p == dechar)
            dec = 1;                    // Decimal point found
          else if (blank || !(*p == '-' || *p == '+'))
            digit = 1;

        } else if (dec)
          dec++;                        // More decimals

        n++;
        blank = 1;
      } // endif's *p

    if (phase == 1)
      if (++nerr > mxr) {
        sprintf(g->Message, MSG(UNBALANCE_QUOTE), num_read);
        goto err;
      } else
        goto skip;

    if (n) {
      len[i] = MY_MAX(len[i], n);
      type = (digit || n == 0 || (dec && n == 1)) ? TYPE_STRING
           : (dec) ? TYPE_DOUBLE : TYPE_INT;
      typ[i] = MY_MIN(type, typ[i]);
      prc[i]  = MY_MAX((typ[i] == TYPE_DOUBLE) ? (dec - 1) : 0, prc[i]);
      } // endif n

    imax = MY_MAX(imax, i+1);
   skip: ;                  // Skip erroneous line
    } // endfor num_read

  if (trace) {
    htrc("imax=%d Lengths:", imax);

    for (i = 0; i < imax; i++)
      htrc(" %d", len[i]);

    htrc("\n");
  } // endif trace

  fclose(infile);

 skipit:
  if (trace)
    htrc("CSVColumns: imax=%d hmax=%d len=%d\n",
                      imax, hmax, length[0]);

  /*********************************************************************/
  /*  Allocate the structures used to refer to the result set.         */
  /*********************************************************************/
  qrp = PlgAllocResult(g, ncol, imax, IDS_COLUMNS + 3,
                          buftyp, fldtyp, length, false, false);
  if (info || !qrp)
    return qrp;

  qrp->Nblin = imax;

  /*********************************************************************/
  /*  Now get the results into blocks.                                 */
  /*********************************************************************/
  for (i = 0; i < imax; i++) {
    if (i >= hmax) {
      sprintf(buf, "COL%.3d", i+1);
      p = buf;
    } else
      p = colname[i];

    if (typ[i] == TYPE_UNKNOWN)            // Void column
      typ[i] = TYPE_STRING;

    crp = qrp->Colresp;                    // Column Name
    crp->Kdata->SetValue(p, i);
    crp = crp->Next;                       // Data Type
    crp->Kdata->SetValue(typ[i], i);
    crp = crp->Next;                       // Type Name
    crp->Kdata->SetValue(GetTypeName(typ[i]), i);
    crp = crp->Next;                       // Precision
    crp->Kdata->SetValue(len[i], i);
    crp = crp->Next;                       // Length
    crp->Kdata->SetValue(len[i], i);
    crp = crp->Next;                       // Scale (precision)
    crp->Kdata->SetValue(prc[i], i);
    } // endfor i

  /*********************************************************************/
  /*  Return the result pointer for use by GetData routines.           */
  /*********************************************************************/
  return qrp;

 err:
  fclose(infile);
  return NULL;
  } // end of CSVCColumns
Пример #21
0
int BLKFAM::ReadBuffer(PGLOBAL g)
  {
  int i, n, rc = RC_OK;

  /*********************************************************************/
  /*  Sequential reading when Placed is not true.                      */
  /*********************************************************************/
  if (Placed) {
    Placed = false;
  } else if (++CurNum < Rbuf) {
    CurLine = NxtLine;

    // Get the position of the next line in the buffer
    while (*NxtLine++ != '\n') ;

    // Set caller line buffer
    n = NxtLine - CurLine - Ending;
    memcpy(Tdbp->GetLine(), CurLine, n);
    Tdbp->GetLine()[n] = '\0';
    goto fin;
  } else if (Rbuf < Nrec && CurBlk != -1) {
    return RC_EF;
  } else {
    /*******************************************************************/
    /*  New block.                                                     */
    /*******************************************************************/
    CurNum = 0;

    if (++CurBlk >= Block)
      return RC_EF;

  } // endif's

  if (OldBlk == CurBlk)
    goto ok;         // Block is already there

  // fseek is required only in non sequential reading
  if (CurBlk != OldBlk + 1)
    if (fseek(Stream, BlkPos[CurBlk], SEEK_SET)) {
      sprintf(g->Message, MSG(FSETPOS_ERROR), BlkPos[CurBlk]);
      return RC_FX;
      } // endif fseek

  // Calculate the length of block to read
  BlkLen = BlkPos[CurBlk + 1] - BlkPos[CurBlk];

  if (trace)
    htrc("File position is now %d\n", ftell(Stream));

  // Read the entire next block
  n = fread(To_Buf, 1, (size_t)BlkLen, Stream);

  if (n == BlkLen) {
//  ReadBlks++;
    num_read++;
    Rbuf = (CurBlk == Block - 1) ? Last : Nrec;

   ok:
    rc = RC_OK;

    // Get the position of the current line
    for (i = 0, CurLine = To_Buf; i < CurNum; i++)
      while (*CurLine++ != '\n') ;      // What about Unix ???

    // Now get the position of the next line
    for (NxtLine = CurLine; *NxtLine++ != '\n';) ;

    // Set caller line buffer
    n = NxtLine - CurLine - Ending;
    memcpy(Tdbp->GetLine(), CurLine, n);
    Tdbp->GetLine()[n] = '\0';
  } else if (feof(Stream)) {
    rc = RC_EF;
  } else {
#if defined(UNIX)
    sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno));
#else
    sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL));
#endif

    if (trace)
      htrc("%s\n", g->Message);

    return RC_FX;
  } // endelse

  OldBlk = CurBlk;         // Last block actually read
  IsRead = true;           // Is read indeed

 fin:
  // Store the current record file position for Delete and Update
  Fpos = BlkPos[CurBlk] + CurLine - To_Buf;
  return rc;
  } // end of ReadBuffer