git-svn-id: svn://10.65.10.50/branches/R_10_00@22770 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			730 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			730 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <textset.h>
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TText_recordset
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
bool TText_recordset::destroy(TRecnotype r) 
 | 
						|
{ 
 | 
						|
  const bool ok = _rec.destroy(r, true);
 | 
						|
  if (ok && (_curr == r || _curr > _rec.items()))
 | 
						|
    _curr = -1;
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
const TRecordset_column_info& TText_recordset::column_info(const char* column) const
 | 
						|
{
 | 
						|
  return column_info(find_column(column));
 | 
						|
}
 | 
						|
 | 
						|
TRecnotype TText_recordset::new_rec(const char* rec)
 | 
						|
{
 | 
						|
  _curr = _rec.add(rec);
 | 
						|
  const int l = row(_curr).size(); // Forse sarebbe piu' sicuro len()
 | 
						|
  if (l > _info._width)
 | 
						|
    _info._width = l;
 | 
						|
  return _curr;
 | 
						|
}
 | 
						|
 | 
						|
TRecnotype TText_recordset::insert_rec(TRecnotype r, const char* buf)
 | 
						|
{
 | 
						|
  TRecnotype pos = new_rec(buf);
 | 
						|
  if ((r >= 0) && (r != pos))
 | 
						|
  {
 | 
						|
    TObject* last = _rec.remove(pos);
 | 
						|
    _rec.insert(last, r);
 | 
						|
    _curr = pos = r;
 | 
						|
  }
 | 
						|
  return pos;
 | 
						|
}
 | 
						|
 | 
						|
TToken_string& TText_recordset::row(TRecnotype n) const
 | 
						|
{
 | 
						|
  if (n < 0)
 | 
						|
    n = current_row();
 | 
						|
  if (n < 0 || n >= items())
 | 
						|
    n = ((TText_recordset*)this)->new_rec();  // Clausola di salvaguardia
 | 
						|
  return (TToken_string&)_rec.row(n);
 | 
						|
}
 | 
						|
 | 
						|
TRecnotype TText_recordset::items() const 
 | 
						|
{ 
 | 
						|
  TRecnotype n = _rec.items();
 | 
						|
  if (n == 0 && _query.full() && _query.find("CREATE ") < 0)
 | 
						|
  {
 | 
						|
    ((TText_recordset*)this)->exec(_query);
 | 
						|
    n = _rec.items();
 | 
						|
  }
 | 
						|
  return n; 
 | 
						|
}
 | 
						|
 | 
						|
bool TText_recordset::move_to(TRecnotype pos)
 | 
						|
{
 | 
						|
  const bool ok = pos >= 0 && pos < items();
 | 
						|
 | 
						|
  _curr = pos;
 | 
						|
	return ok;
 | 
						|
}
 | 
						|
 | 
						|
void TText_recordset::requery()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
bool TText_recordset::load_file(const TFilename& n)
 | 
						|
{
 | 
						|
  TString str(4096);
 | 
						|
  char* buf = str.get_buffer();
 | 
						|
  ifstream f(n);
 | 
						|
  while (f && !f.eof())
 | 
						|
  {
 | 
						|
    f.getline(buf, str.size());
 | 
						|
    new_rec(buf);
 | 
						|
  }
 | 
						|
  return _rec.items() > 0;
 | 
						|
}
 | 
						|
 | 
						|
int TText_recordset::find_column(const char* column) const
 | 
						|
{
 | 
						|
  int n = -1;
 | 
						|
  if (column && *column && *column != '#')
 | 
						|
  {
 | 
						|
    if (real::is_natural(column))
 | 
						|
      n = atoi(column);
 | 
						|
    if (strlen(column) > 2)
 | 
						|
      n = TRecordset::find_column(column);
 | 
						|
    else
 | 
						|
    {
 | 
						|
			n = 0;
 | 
						|
      for (const char* c = column; isalpha(*c); c++)
 | 
						|
      {
 | 
						|
        n *= 26;
 | 
						|
        n += toupper(*c)-'@';
 | 
						|
      }
 | 
						|
      n--;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return n;
 | 
						|
}
 | 
						|
 | 
						|
const TVariant& TText_recordset::get(unsigned int column) const
 | 
						|
{
 | 
						|
  const TRecnotype n = current_row();
 | 
						|
  if (column == 0 && n >= 0 && n < items())
 | 
						|
  {
 | 
						|
    TVariant& var = get_tmp_var();
 | 
						|
    var.set(((TText_recordset*)this)->row(n));
 | 
						|
    return var;
 | 
						|
  }
 | 
						|
  return NULL_VARIANT;
 | 
						|
}
 | 
						|
 | 
						|
bool TText_recordset::set(unsigned int column, const TVariant& var)
 | 
						|
{
 | 
						|
  const bool ok = column == 0;
 | 
						|
  if (ok)
 | 
						|
    row() = var.as_string();
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
bool TText_recordset::set(const char* column, const TVariant& var)
 | 
						|
{
 | 
						|
  return set(find_column(column), var);
 | 
						|
}
 | 
						|
 | 
						|
TQuery_type TText_recordset::parse_query(const char* query, TFilename& table)
 | 
						|
{
 | 
						|
  TQuery_type qt = _qt_none;
 | 
						|
  
 | 
						|
  TString q(query); q.trim(); 
 | 
						|
  const int ct = q.find("CREATE TABLE ");
 | 
						|
  if (ct >= 0)
 | 
						|
  {
 | 
						|
    const TToken_string t(q.mid(ct), ' ');
 | 
						|
    t.get(2, table); // Furbastro: prendo la terza parola della query
 | 
						|
    table.trim();
 | 
						|
    if (table.not_empty())
 | 
						|
      qt = _qt_create;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    const int se = q.find("SELECT ");
 | 
						|
    if (se >= 0)
 | 
						|
    {
 | 
						|
      int n = q.find("FROM ", se);
 | 
						|
      table = q.mid(n+5);
 | 
						|
      n = table.find("WHERE");
 | 
						|
      if (n > 0)
 | 
						|
        table.cut(n-1);
 | 
						|
      n = table.find(',');
 | 
						|
      if (n > 0)
 | 
						|
        table.cut(n);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      table = query;
 | 
						|
    }
 | 
						|
    table.trim();
 | 
						|
    if (table.not_empty())
 | 
						|
      qt = _qt_select;
 | 
						|
  }
 | 
						|
  return qt;
 | 
						|
}
 | 
						|
 | 
						|
bool TText_recordset::exec(const char* query)
 | 
						|
{
 | 
						|
  TFilename name;
 | 
						|
  const TQuery_type qt = parse_query(query, name);
 | 
						|
  if (qt != _qt_none)
 | 
						|
  {
 | 
						|
    _query = query; _query.trim();
 | 
						|
    if (qt == _qt_select)
 | 
						|
    {
 | 
						|
      destroy();
 | 
						|
      load_file(name);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return qt != _qt_none;
 | 
						|
}
 | 
						|
 | 
						|
bool TText_recordset::save_as_text(const char* path)
 | 
						|
{
 | 
						|
  bool valid = path && *path;
 | 
						|
  if (valid)
 | 
						|
  {
 | 
						|
    ofstream out(path);
 | 
						|
    if (out.good())
 | 
						|
    {
 | 
						|
      for (bool ok = move_first(); ok; ok = move_next())
 | 
						|
        out << row() << endl;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      valid = false;
 | 
						|
  }
 | 
						|
  return valid;
 | 
						|
}
 | 
						|
 | 
						|
bool TText_recordset::save_as(const char* path, TRecordsetExportFormat fmt)
 | 
						|
{
 | 
						|
  if (fmt == fmt_text)
 | 
						|
  {
 | 
						|
    TFilename n = path;
 | 
						|
    if (n.blank())
 | 
						|
      parse_query(_query, n);
 | 
						|
    if (n.full())
 | 
						|
      return save_as_text(n);
 | 
						|
  }
 | 
						|
  return TRecordset::save_as(path, fmt);
 | 
						|
}
 | 
						|
 | 
						|
void TText_recordset::sort(COMPARE_FUNCTION f)
 | 
						|
{
 | 
						|
  if (f == NULL)
 | 
						|
    _rec.sort(true);      // Ordina alfabeticamante
 | 
						|
  else
 | 
						|
    _rec.TArray::sort(f); // Usa la funzione definita dall'utente
 | 
						|
}
 | 
						|
 | 
						|
TText_recordset::TText_recordset(const char* query) : _query(query), _curr(-1)
 | 
						|
{ 
 | 
						|
  _info._name = "A";
 | 
						|
  _info._pos = _info._width = 0;
 | 
						|
  _info._type = _alfafld;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TCSV_recordset
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TQuery_type TCSV_recordset::parse_query(const char* query, TFilename& table)
 | 
						|
{
 | 
						|
  TString q(query);
 | 
						|
 | 
						|
  if (q.starts_with("CSV(", true))
 | 
						|
  {
 | 
						|
    switch (q[4])
 | 
						|
    { 
 | 
						|
    case '\'':
 | 
						|
    case '"' : 
 | 
						|
      if (q[5] == '\\' && q[6] == 't')
 | 
						|
        _separator = '\t'; 
 | 
						|
      else
 | 
						|
        _separator = q[5]; 
 | 
						|
      break;
 | 
						|
    default  :
 | 
						|
      if (q[4] != ')')
 | 
						|
        _separator = q[4];
 | 
						|
      else
 | 
						|
        _separator = ',';
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    q = q.after(')');
 | 
						|
    q.trim();
 | 
						|
  }
 | 
						|
  return TText_recordset::parse_query(q, table);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
unsigned int TCSV_recordset::columns() const
 | 
						|
{
 | 
						|
  unsigned int c = _trc.items();
 | 
						|
  if (c == 0)
 | 
						|
  {
 | 
						|
    const TRecnotype i = items();  //rilegge fai di testo e tenta di crearne il tracciato _trc
 | 
						|
    c = _trc.items();
 | 
						|
    if (c == 0 && i > 0)
 | 
						|
      c = ((TCSV_recordset*)this)->build_trc();
 | 
						|
  }
 | 
						|
  return c;
 | 
						|
}
 | 
						|
 | 
						|
const TRecordset_column_info& TCSV_recordset::column_info(unsigned int column) const
 | 
						|
{
 | 
						|
  if (column >= 0 && column < columns())
 | 
						|
  {
 | 
						|
    TRecordset_column_info* ci = (TRecordset_column_info*)_trc.objptr(column);
 | 
						|
    if (ci != NULL)
 | 
						|
      return *ci;
 | 
						|
  }
 | 
						|
  return TText_recordset::column_info(column);
 | 
						|
}
 | 
						|
 | 
						|
TRecnotype TCSV_recordset::new_rec(const char* rec)
 | 
						|
{
 | 
						|
  const TRecnotype n = TText_recordset::new_rec(rec);
 | 
						|
  if (n >= 0)
 | 
						|
    row(n).separator(_separator);
 | 
						|
  return n;
 | 
						|
}
 | 
						|
 | 
						|
void TCSV_recordset::create_column(const char * name, TFieldtypes type)
 | 
						|
{
 | 
						|
  TRecordset_column_info * info = new TRecordset_column_info;
 | 
						|
 | 
						|
	info->_name = name;
 | 
						|
	info->_type = type;
 | 
						|
  _trc.add(info);
 | 
						|
}
 | 
						|
 | 
						|
unsigned int TCSV_recordset::build_trc()
 | 
						|
{
 | 
						|
  _trc.destroy();
 | 
						|
  int cols = 1;
 | 
						|
  int i;
 | 
						|
  for (i = items()-1; i >= 0; i--)
 | 
						|
  {
 | 
						|
    const TToken_string& r = row(i);
 | 
						|
    const int c = r.items();
 | 
						|
    if (c > cols)
 | 
						|
      cols = c;
 | 
						|
  }
 | 
						|
 | 
						|
  for (i = 0; i < cols; i++)
 | 
						|
    _trc.add(new TRecordset_column_info);
 | 
						|
 | 
						|
  TString val;
 | 
						|
  for (i = items()-1; i >= 0; i--)
 | 
						|
  {
 | 
						|
    const TToken_string& r = row(i);
 | 
						|
    for (int c = r.items()-1; c >= 0; c--)
 | 
						|
    {
 | 
						|
      r.get(c, val);
 | 
						|
      if (val.full())
 | 
						|
      {
 | 
						|
        TRecordset_column_info& ci = *(TRecordset_column_info*)_trc.objptr(c);
 | 
						|
        const int l = val.len();
 | 
						|
        if (l > ci._width)
 | 
						|
        {
 | 
						|
          ci._width = l;
 | 
						|
          if (l == 8 || l == 10 && TDate::isdate(val))
 | 
						|
            ci._type = _datefld;
 | 
						|
          else
 | 
						|
          {
 | 
						|
            if (!real::is_null(val))
 | 
						|
            {
 | 
						|
              if (real::is_natural(val))
 | 
						|
                ci._type = _intfld;
 | 
						|
              else
 | 
						|
                ci._type = _realfld;
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return _trc.items();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TCSV_recordset::load_file(const TFilename& n)
 | 
						|
{
 | 
						|
  if (!TText_recordset::load_file(n))
 | 
						|
    return false;
 | 
						|
 | 
						|
  return build_trc() > 0;
 | 
						|
}
 | 
						|
 | 
						|
bool TCSV_recordset::set(unsigned int column, const TVariant& var)
 | 
						|
{
 | 
						|
  TToken_string& r = row();
 | 
						|
  r.add(var.as_string(), column);
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
const TVariant& TCSV_recordset::get(unsigned int column) const
 | 
						|
{
 | 
						|
  const TRecnotype n = current_row();
 | 
						|
  if (n >= 0 && n < items())
 | 
						|
  {
 | 
						|
    const char* val = row(n).get(column);
 | 
						|
    if (val != NULL)
 | 
						|
    {
 | 
						|
      TVariant& var = get_tmp_var();
 | 
						|
      var.set(val);
 | 
						|
      return var;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return NULL_VARIANT;
 | 
						|
}
 | 
						|
 | 
						|
TCSV_recordset::TCSV_recordset(const char* query) 
 | 
						|
              : TText_recordset(query), _separator(',')
 | 
						|
{ 
 | 
						|
  TFilename n;
 | 
						|
  if (parse_query(query, n) == _qt_select && n.exist())
 | 
						|
    load_file(n);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TAS400_recordset
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
bool TAS400_recordset::load_file(const TFilename& n)
 | 
						|
{
 | 
						|
  TString row(record_length(), ' ');
 | 
						|
  ifstream f(n, ios::binary);
 | 
						|
  char* buf = row.get_buffer();
 | 
						|
  TRecnotype r = -1;
 | 
						|
  while (f)
 | 
						|
  {
 | 
						|
    *buf = '\0';
 | 
						|
    f.read(buf, record_length());
 | 
						|
    if (*buf)
 | 
						|
      r = new_rec(buf);
 | 
						|
    else
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  return r >= 0;
 | 
						|
}
 | 
						|
 | 
						|
TQuery_type TAS400_recordset::parse_query(const char* query, TFilename& table)
 | 
						|
{
 | 
						|
  TString q(query);
 | 
						|
  if (q.find("AS400(") >= 0)
 | 
						|
  {
 | 
						|
    const int da = q.find('(');
 | 
						|
    const int al = q.find(')', da);
 | 
						|
    TToken_string k(q.sub(da+1, al), ',');
 | 
						|
    _info._width = k.get_int(0);
 | 
						|
    _key._width = k.get_int();
 | 
						|
    _key._pos = k.get_int();
 | 
						|
    q = q.mid(al+1);
 | 
						|
    q.trim();
 | 
						|
  }
 | 
						|
  return TText_recordset::parse_query(q, table);
 | 
						|
}
 | 
						|
 | 
						|
bool TAS400_recordset::set_field(const TAS400_column_info& fi, const TVariant& var)
 | 
						|
{
 | 
						|
  TToken_string& r = row();
 | 
						|
  switch (fi._type)
 | 
						|
  {
 | 
						|
  case _intfld:
 | 
						|
  case _longfld:
 | 
						|
    {
 | 
						|
      TString80 str;
 | 
						|
      if (fi._width > 8)
 | 
						|
        str = var.as_real().string(fi._width, 0, ' ');
 | 
						|
      else
 | 
						|
        str.format("%*ld", fi._width, var.as_int());
 | 
						|
      r.overwrite(str, fi._pos);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case _intzerofld:
 | 
						|
  case _longzerofld:
 | 
						|
    {
 | 
						|
      TString80 str; 
 | 
						|
      if (fi._width > 8)
 | 
						|
        str = var.as_real().string(fi._width, 0, '0');
 | 
						|
      else
 | 
						|
        str.format("%0*ld", fi._width, var.as_int());
 | 
						|
      r.overwrite(str, fi._pos);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case _realfld:
 | 
						|
    {
 | 
						|
      const char* str = var.as_real().string(fi._width);
 | 
						|
      r.overwrite(str, fi._pos);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case _datefld:
 | 
						|
    if (fi._width == 8)
 | 
						|
    {
 | 
						|
      TString8 str; str << var.as_date().date2ansi();
 | 
						|
      r.overwrite(str, fi._pos, fi._width);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    // fall down to default
 | 
						|
  default:
 | 
						|
    r.overwrite(var.as_string(), fi._pos, fi._width);
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  bool ok = true;
 | 
						|
  if (fi._required && var.is_empty())
 | 
						|
    ok = false;
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
TAS400_column_info* TAS400_recordset::parse_field(const char* column, int& c, bool create)
 | 
						|
{
 | 
						|
  CHECK(column && *column > ' ', "NULL field name");
 | 
						|
  TAS400_column_info* ci = NULL;
 | 
						|
  
 | 
						|
  TString16 trc;
 | 
						|
  TString80 fld(column);
 | 
						|
  const int dot = fld.find('.');
 | 
						|
  if (dot > 0)
 | 
						|
  {
 | 
						|
    trc = fld.left(dot);
 | 
						|
    fld.ltrim(dot+1);
 | 
						|
  }
 | 
						|
  else
 | 
						|
    trc = rec_type();
 | 
						|
 | 
						|
  TArray* info = (TArray*)_trc.objptr(trc);
 | 
						|
  if (info == NULL && create)
 | 
						|
  {
 | 
						|
    info = new TArray;
 | 
						|
    _trc.add(trc, info);
 | 
						|
  }
 | 
						|
  
 | 
						|
  if (info != NULL)
 | 
						|
  {
 | 
						|
    if (create)
 | 
						|
    {
 | 
						|
      ci = new TAS400_column_info;
 | 
						|
      ci->_name = fld;
 | 
						|
      if (info->items() > 0)
 | 
						|
      {
 | 
						|
        const TAS400_column_info& last = *(const TAS400_column_info*)info->objptr(info->last());
 | 
						|
        ci->_pos = last._pos+last._width;
 | 
						|
      }
 | 
						|
      c = info->add(ci);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      for (c = info->last(); c >= 0; c--)
 | 
						|
      {
 | 
						|
        TAS400_column_info* aci = (TAS400_column_info*)info->objptr(c);
 | 
						|
        if (aci->_name == fld)
 | 
						|
        {
 | 
						|
          ci = aci;
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }  
 | 
						|
  return ci;
 | 
						|
}
 | 
						|
 | 
						|
unsigned int TAS400_recordset::columns() const
 | 
						|
{
 | 
						|
  const TArray* info = (const TArray*)_trc.objptr(rec_type());
 | 
						|
  if (info)
 | 
						|
    return info->items();
 | 
						|
  return TText_recordset::columns();
 | 
						|
}
 | 
						|
 | 
						|
const TRecordset_column_info& TAS400_recordset::column_info(unsigned int c) const
 | 
						|
{
 | 
						|
  const TArray* info = (const TArray*)_trc.objptr(rec_type());
 | 
						|
  if (info)
 | 
						|
  {
 | 
						|
    TRecordset_column_info* i = (TRecordset_column_info*)info->objptr(c);
 | 
						|
    if (i != NULL)
 | 
						|
      return *i;
 | 
						|
  }
 | 
						|
  return TText_recordset::column_info(c);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TAS400_recordset::find_column(const char* column) const
 | 
						|
{
 | 
						|
  int c = -1;
 | 
						|
  ((TAS400_recordset*)this)->parse_field(column, c,  false);
 | 
						|
  return c;
 | 
						|
}
 | 
						|
 | 
						|
const TRecordset_column_info& TAS400_recordset::column_info(const char* column) const
 | 
						|
{
 | 
						|
  int c = -1;
 | 
						|
  TRecordset_column_info* ci = ((TAS400_recordset*)this)->parse_field(column, c,  false);
 | 
						|
  if (ci != NULL)
 | 
						|
  {
 | 
						|
    return *ci;
 | 
						|
  }
 | 
						|
  return TText_recordset::column_info(column);
 | 
						|
}
 | 
						|
 | 
						|
const TVariant& TAS400_recordset::get_field(const TAS400_column_info& ci) const
 | 
						|
{
 | 
						|
  const TRecnotype n = current_row();
 | 
						|
  if (n >= 0 && n < items())
 | 
						|
  {
 | 
						|
    const TString& str = row(n).mid(ci._pos, ci._width);
 | 
						|
    TVariant& var = get_tmp_var();
 | 
						|
    var.set(str); var.convert_to(ci._type);
 | 
						|
    return var;
 | 
						|
  }
 | 
						|
  return ci._default;
 | 
						|
}
 | 
						|
 | 
						|
const TVariant& TAS400_recordset::get(unsigned int column) const
 | 
						|
{
 | 
						|
  const TArray* info = (const TArray*)_trc.objptr(rec_type());
 | 
						|
  if (info)
 | 
						|
  {
 | 
						|
    const TAS400_column_info* ci = (const TAS400_column_info*)info->objptr(column);
 | 
						|
    if (ci != NULL)
 | 
						|
      return get_field(*ci);
 | 
						|
  }
 | 
						|
  return TText_recordset::get(column);
 | 
						|
}
 | 
						|
 | 
						|
const TVariant& TAS400_recordset::get(const char* column) const
 | 
						|
{
 | 
						|
	if (column && *column != '#')
 | 
						|
  {
 | 
						|
		int c = -1;
 | 
						|
		if (column[1] != '\0')
 | 
						|
		{
 | 
						|
			const TAS400_column_info* ci = ((TAS400_recordset*)this)->parse_field(column, c,  false);
 | 
						|
			if (ci != NULL)
 | 
						|
				return get_field(*ci);
 | 
						|
		}
 | 
						|
		c = TText_recordset::find_column(column);
 | 
						|
		if (c >= 0)
 | 
						|
			return TText_recordset::get(c);
 | 
						|
	}
 | 
						|
	return TRecordset::get(column);
 | 
						|
}
 | 
						|
 | 
						|
TRecnotype TAS400_recordset::new_rec(const char* trc)
 | 
						|
{
 | 
						|
	CHECK(record_length() > 0, "Lunghezza record nulla");
 | 
						|
 | 
						|
	if (trc && (int)strlen(trc) == record_length())
 | 
						|
		return TText_recordset::new_rec(trc);
 | 
						|
	else
 | 
						|
	{
 | 
						|
	  const TString str(record_length(), ' ');
 | 
						|
		const TRecnotype n = TText_recordset::new_rec(str);
 | 
						|
 | 
						|
		if (trc && (int)strlen(trc) == key_length())
 | 
						|
		{
 | 
						|
			TArray* info = (TArray*)_trc.objptr(trc);
 | 
						|
			if (info != NULL) // Se il tracciato e' noto, riempio di zeri i campi opportuni
 | 
						|
			{
 | 
						|
				FOR_EACH_ARRAY_ITEM_BACK((*info), i, obj)
 | 
						|
				{
 | 
						|
					const TAS400_column_info& ci = *(const TAS400_column_info*)obj;
 | 
						|
					if (ci._default.is_null())
 | 
						|
					{
 | 
						|
						if (ci._type == _intzerofld || ci._type == _longzerofld)
 | 
						|
							set_field(ci, NULL_VARIANT);
 | 
						|
					}
 | 
						|
					else
 | 
						|
						set_field(ci, ci._default);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			row(n).overwrite(trc, key_position(), key_length());
 | 
						|
		}
 | 
						|
	  return n;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
const TString& TAS400_recordset::rec_type(TRecnotype r) const
 | 
						|
{
 | 
						|
  if (key_length() > 0)
 | 
						|
  {
 | 
						|
    const TToken_string& riga = row(r);
 | 
						|
    return riga.mid(key_position(), key_length());
 | 
						|
  }
 | 
						|
  return EMPTY_STRING;
 | 
						|
}
 | 
						|
 | 
						|
bool TAS400_recordset::create_field(const char* nam, int pos, int len, 
 | 
						|
                                    TFieldtypes typ, bool req, const TVariant& def)
 | 
						|
{
 | 
						|
  CHECK(nam && *nam > ' ', "Null field name");
 | 
						|
  
 | 
						|
  int c = -1;
 | 
						|
  TAS400_column_info* ci = parse_field(nam, c, true);
 | 
						|
  const bool ok = ci != NULL;
 | 
						|
  if (ok)
 | 
						|
  {
 | 
						|
    if (pos >= 0) // Se l'utente fissa una posizione impostala, altrimenti tieni quella automatica
 | 
						|
      ci->_pos    = pos;
 | 
						|
    ci->_width    = len;
 | 
						|
    ci->_type     = typ;
 | 
						|
    ci->_required = req;
 | 
						|
    ci->_default  = def;
 | 
						|
    
 | 
						|
    CHECKS(ci->_pos >= 0 && ci->_pos < record_length(), "Invalid position for field ", nam);
 | 
						|
    CHECKS(ci->_width > 0 && ci->_pos+ci->_width <= record_length(), "Invalid lenght for field ", nam);
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
bool TAS400_recordset::set(const char* column, const TVariant& var)
 | 
						|
{
 | 
						|
  int c = -1;
 | 
						|
  TAS400_column_info* ci = parse_field(column, c,  false);
 | 
						|
  bool ok = ci != NULL;
 | 
						|
  if (ok)
 | 
						|
    ok = set_field(*ci, var);
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
bool TAS400_recordset::set(unsigned int column, const TVariant& var)
 | 
						|
{
 | 
						|
  const TAS400_column_info& ci = (const TAS400_column_info&)column_info(column);
 | 
						|
  return set_field(ci, var);
 | 
						|
}
 | 
						|
 | 
						|
bool TAS400_recordset::save_as_text(const char* path)
 | 
						|
{
 | 
						|
  bool valid = path && *path;
 | 
						|
  if (valid)
 | 
						|
  {
 | 
						|
    ofstream out(path, ios::binary);
 | 
						|
    if (out.good())
 | 
						|
    {
 | 
						|
      for (bool ok = move_first(); ok; ok = move_next())
 | 
						|
        out << row();  // NON mettere << endl
 | 
						|
    }
 | 
						|
    else
 | 
						|
      valid = false;
 | 
						|
  }
 | 
						|
  return valid;
 | 
						|
}
 | 
						|
 | 
						|
TAS400_recordset::TAS400_recordset(const char* query)
 | 
						|
                : TText_recordset(query)
 | 
						|
{ 
 | 
						|
  TFilename n;
 | 
						|
  if (parse_query(query, n) == _qt_select && n.exist())
 | 
						|
    load_file(n);
 | 
						|
}
 |