1. 一般情况下Sqliteman差不多属于最方便的sqlite桌面管理工具,因为,他可以直接打开一个sqlite数据库文件进行管理,比较方便。sqlite developer每次都要关联一下文件,才能操作,不过对DDL的操作sqlite developer是最方便完善的,sqliteman alter某一个字段的类型时,会丢失主键(primary key)的声明,这应该是它的一个bug.

2. integer字段,字段类型最好写INTEGER,全部大写的。我用delphi的sqlite simple wrapper的FieldAsInteger读取类型为integer的字段时,总告诉我类型不对,改为INTEGER正常。(后记,还是检查了一下SQLITETable3.pas文件的代码,果然里面判断类型时,直接和大写的匹配,sqlite对字段的类型时大小写都可以的。里面很多地方判断的时候,都只和大写判断,暂时不去修改这个wrapper的代码了,地方太多,先自己按大写的习惯来吧)

Posted in 开发手记 at 08月 22nd, 2009. No Comments.

php自带了URLDecode和urldecode函数,可以用来对&=等一些出现在url或者get/post内容中的控制字符进行转义。

delphi没有自带此类函数,必须自己写。

function URLDecode(const S: string): string;
var
  Idx: Integer;   // loops thru chars in string
  Hex: string;    // string of hex characters
  Code: Integer;  // hex character code (-1 on error)
begin
  // Intialise result and string index
  Result := ”;
  Idx := 1;
  // Loop thru string decoding each character
  while Idx <= Length(S) do
  begin
    case S[Idx] of
      ‘%’:
      begin
        // % should be followed by two hex digits - exception otherwise
        if Idx <= Length(S) - 2 then
        begin
          // there are sufficient digits - try to decode hex digits
          Hex := S[Idx+1] + S[Idx+2];
          Code := SysUtils.StrToIntDef(’$’ + Hex, -1);
          Inc(Idx, 2);
        end
        else
          // insufficient digits - error
          Code := -1;
        // check for error and raise exception if found
        if Code = -1 then
          raise SysUtils.EConvertError.Create(
            ‘Invalid hex digit in URL’
          );
        // decoded OK - add character to result
        Result := Result + Chr(Code);
      end;
      ‘+’:
        // + is decoded as a space
        Result := Result + ‘ ‘
      else
        // All other characters pass thru unchanged
        Result := Result + S[Idx];
    end;
    Inc(Idx);
  end;
end;
function URLEncode(const S: string; const InQueryString: Boolean): string;
var
  Idx: Integer; // loops thru characters in string
begin
  Result := ”;
  for Idx := 1 to Length(S) do
  begin
    case S[Idx] of
      ‘A’..’Z', ‘a’..’z', ‘0′..’9′, ‘-’, ‘_’, ‘.’:
        Result := Result + S[Idx];
      ‘ ‘:
        if InQueryString then
          Result := Result + ‘+’
        else
          Result := Result + ‘%20′;
      else
        Result := Result + ‘%’ + SysUtils.IntToHex(Ord(S[Idx]), 2);
    end;
  end;
end;

Posted in 开发手记 at 08月 12th, 2009. No Comments.

Delphi下时间和字符串互转用使用DateToStr或者StrToDate函数。
这两个函数没有php下的date函数方便和灵活。不过有时候也确实需要用到。

我写的下面这几句代码基本上体现了DateToStr比较完整的用法

  aFormat.ShortDateFormat := ‘yyyy/mm/dd hh:mm:ss’;
  aFormat.DateSeparator := ‘/’;
  ShowMessage( DateToStr( now, aFormat) );

Posted in 开发手记 at 08月 10th, 2009. 1 Comment.

sqlite:单机数据库,好处多多,特别适合单机桌面程序保存(复杂)数据用。以前一般都要自己写个数据保存模块,代码量比较巨大。

Sqlite一般是以.dll的形式发布的,然后到处一堆接口函数。aducom (http://www.aducom.com/cms/page.php?2) 有个免费的mysql vcl组件,调用方式模拟ado,习惯按ado方式操作数据库的可以使用。不过,现在下载最新版的需要注册用户(很恶心),还需要激活注册邮箱(非常恶心),下下来以后,虽然是2009年的新版本,但是最高还只支持到Delphi5,delphi7以上,要自己重新制作组件包,操作方法比较复杂,可以参考http://edn.embarcadero.com/article/27717 ,这是个非常详细的解决方案,真要解决的花点时间看绝对没有问题。

其实sqlite左右方便的小型数据库,也没有做太多的封装。另外一个解决方案是,给sqlite.dll写delphi声明。当然不用自己写,A simple Delphi wrapper (http://www.itwriting.com/blog/a-simple-delphi-wrapper-for-sqlite-3)就挺不错的,简单实用。价格便宜量又足。

顺便说一下,sqlite因为是文件型操作,所以,对于批量的操作,最好放到一个事务里面,这样所有操作只有一次文件读写,否则,每一次操作都会读写一次数据,连续插几十条数据,都能感觉到机器卡。

Posted in 开发手记 at 08月 3rd, 2009. No Comments.

因为TIdHttp是阻塞式的,所以,如果传输的文件比较大的时候,整个界面都动弹不得,和死了一样。

解决方法有两个:

1. 把对IdHttp的处理,放入线程内。搞个线程也很简单,就是一旦数据交互起来,麻烦一些。

2. 好久没用delphi了,不想写太复杂的代码了,这个简单的应用里,只要界面不僵死就可以了。所以不想用线程。第二个方法就是,往界面里放入一个TIdAntiFreeze控件,(真怀念delphi的方便)。不要高兴的太早,可能界面还是动不了的。因为默认情况下idAntiFreeze的OnlyWhenIdle属性是true,改为false,才会真正的antiFreeze。

BTW,键盘的F11键坏掉好久了,都没有什么感觉 (用delphi没有这个键,会死人的)

Posted in 未分类 at 02月 28th, 2009. 1 Comment.

用indy上传下载文件时,可以先在IdHTTP1WorkBegin中获得总大小,然后在IdHTTP1Work中实时得到当前的传输量,一遍算出整体的传输进度。

procedure TForm1.IdHTTP1WorkBegin(Sender:TObject; AWorkMode:TWorkMode;
  const AWorkCountMax:Integer);
begin
  ShowMessage(IntToStr(AWorkCountMax));
end;

procedure TForm1.IdHTTP1Work(Sender:TObject; AWorkMode:TWorkMode;
  const AWorkCount:Integer);
begin
  Caption := IntToStr(AWorkCount);
end;

Posted in 未分类 at 02月 28th, 2009. No Comments.