Project JEDI - Issue Tracker
Mantis Bugtracker

Viewing Issue Simple Details Jump to Notes ] View Advanced ] Issue History ] Print ]
ID Category Severity Reproducibility Date Submitted Last Update
0004935 [JEDI VCL] 00 JVCL Components minor always 2009-09-14 12:15 2009-09-14 20:48
Reporter JeremyKnowles View Status public  
Assigned To AHUser
Priority normal Resolution fixed  
Status resolved   Product Version 3.37
Summary 0004935: CSVDataset error (actually v 3.38)
Description Using TJvCustomCsvDataSet (TJvCsvDataSet component) and opening a bad file doesn't then allow a good file to be opened afterwards. This is because it keeps the header row from the bad file. This in turn is because FCsvFileLoaded is still set to true even though the bad file couldn't load so next time, when you try to load a good file, ReadCsvFileStream doesn't happen so the header row is still set to the previous (bad) file. I found this by trying to import a file with no header.

The fix is quite straightforward. Add a try/except around TJvCustomCsvDataSet.InternalOpen and set FCsvFileLoaded := false; if there is an exception. The entire routine becomes:

procedure TJvCustomCsvDataSet.InternalOpen;
var
  AppendStr: string;
  CsvLine: RawByteString;
  Counter: Integer;
  csvFileExists: Boolean;
begin
  if FCursorOpen then
    InternalClose; // close first!
  try
    Counter := 0;

    FFileDirty := False;
    if FLoadsFromFile then
    begin
      if FTableName = '' then
        JvCsvDatabaseError(RsENoTableName, RsETableNameRequired);

      FOpenFileName := GetFileName; // Always use the same file name to save as you did to load!!! MARCH 2004.WP
    end
    else
    begin
      FOpenFileName := '';
    end;

    InternalInitFieldDefs; // initialize FieldDef objects.

      // Create TField components when no persistent fields have been created
    if DefaultFields then
      CreateFields;
    BindFields(True); // bind FieldDefs to actual Data

    if FCsvColumns.Count > 1 then
    begin
      // Create a null terminated string which is just a bunch of commas:
      SetLength(FEmptyRowStr, FCsvColumns.Count - 1);
      // When adding an empty row, we add this string as the ascii equivalent:
      FillNativeChar(FEmptyRowStr[1], FCsvColumns.Count - 1, Separator);
    end
    else
      FEmptyRowStr := ''; // nothing.

    FRecordPos := JvCsv_ON_BOF_CRACK; // initial record pos before BOF
    BookmarkSize := SizeOf(Integer);
    // initialize bookmark size for VCL (Integer uses 4 bytes on 32 bit operating systems)

    csvFileExists:= False;
    if FLoadsFromFile then // ReadCsvFileStream:Creates file stream and start reading it. Sets FCsvFileTopLine.
      csvFileExists := ReadCsvFileStream;

    if FHasHeaderRow then
    begin
      if csvFileExists and not ExtendedHeaderInfo and (FCsvFileTopLine <> '') then
        FHeaderRow := FCsvFileTopLine
      else
      begin
        FHeaderRow := GetColumnsAsString; // creating a new file! set up HeaderRow
        FCsvFileTopLine := FHeaderRow;
      end;

      if FHeaderRow <> '' then
        try
          ProcessCsvHeaderRow;
        except
          FHeaderRow := '';
          FreeAndNil(FCsvStream);
          raise;
        end;

      if FAppendedFieldCount > 0 then
      begin
        SetLength(AppendStr, FAppendedFieldCount);
        FillNativeChar(AppendStr[1], FAppendedFieldCount, Separator);
      end;
    end;

    // Load rows from disk to memory, using Stream object to read line by line.
    if FLoadsFromFile and Assigned(FCsvStream) then
    begin
      while not FCsvStream.Eof do
      begin
        CsvLine := JvTrimAnsiStringCrLf(FCsvStream.ReadLine);// leading space, trailing space and crlf are removed by Trim!
        if CsvLine <> '' then
        begin
          if (FSpecialDataMarker <> '')
            and (Pos(FSpecialDataMarker, CsvLine) = 1)
            and Assigned(FOnSpecialData) then
          begin
            // This very rarely used feature should
            // probably be removed from the JVCL? -WPostma.
            FOnSpecialData(Self, Counter, CsvLine);
          end
          else
          begin
            // Process the row:
            {$IFDEF UNICODE}
            if FUtf8Detected then
              ProcessCsvDataRow(Utf8ToAnsi(CsvLine), Counter)
            else
            {$ENDIF UNICODE}
              ProcessCsvDataRow(string(AnsiString(CsvLine)), Counter);
            Inc(Counter);
          end;
        end;
      end; {while}
    end;{if}
    if Active then
      First;
    FCursorOpen := True;
  except
    FCsvFileLoaded := false;
    Raise;
  end;
  { clean up stream object }
  FreeAndNil(FCsvStream);
end;
Additional Information
Tags No tags attached.
Attached Files

- Relationships
related to 0004901resolvedAHUser [TJvCsvDataSet] loading successively different csv files in a same TJvCsvDataSet fires un unexpected exception 

-  Notes
(0016097)
JeremyKnowles (reporter)
2009-09-14 12:23

I just noticed 0004901, but that fix didn't solve it in my instance (where there is no header or you try to import something obscure like a jpeg).
(0016099)
AHUser (developer)
2009-09-14 20:48

Patch applied to SVN. Thanks.

- Issue History
Date Modified Username Field Change
2009-09-14 12:15 JeremyKnowles New Issue
2009-09-14 12:23 JeremyKnowles Note Added: 0016095
2009-09-14 12:23 JeremyKnowles Note Added: 0016096
2009-09-14 12:23 JeremyKnowles Note Added: 0016097
2009-09-14 14:01 obones Note Deleted: 0016095
2009-09-14 14:01 obones Note Deleted: 0016096
2009-09-14 14:01 obones Relationship added related to 0004901
2009-09-14 14:02 obones Status new => acknowledged
2009-09-14 20:48 AHUser Note Added: 0016099
2009-09-14 20:48 AHUser Status acknowledged => resolved
2009-09-14 20:48 AHUser Fixed in Version => Daily / SVN
2009-09-14 20:48 AHUser Resolution open => fixed
2009-09-14 20:48 AHUser Assigned To => AHUser


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker