Friday, April 27, 2012

Unicode Usernames and Passwords

Advantage added support for Unicode in version 10. I did a few posts and a demo of this feature in 2009, just put Unicode in the search box to find relevant posts. However, Data Dictionary metadata is still stored in Character fields.
This means that usernames and passwords cannot be stored as Unicode by default. In order to use Unicode usernames and passwords you will need to convert the characters to UTF8 before storing them in the dictionary.
For Delphi 2009 and newer these Unicode strings are stored using UTF16, the default for Windows systems. These UTF16 values need to be converted to UTF8 before storing them in the data dictionary. An example of creating a user with Unicode is shown below.

procedure TForm1.btnCreateUser(Sender: TObject);
var
  FhConnection   : AdsNativeInt;
  RetVal         : Cardinal;
begin
  //First make an admin connection
  RetVal := ace.AdsConnect60('C:\Data\TestDb\TestDb.add', ADS_REMOTE_SERVER,
                   'adssys', 'password', ADS_DEFAULT, @FhConnection );

  if ( RetVal = AE_SUCCESS ) then
  begin
    // Create the user using the values from edit boxes
    RetVal := ace.AdsDDCreateUser(lHandle, nil, 
                      PAnsiChar( UTF8String( edtUsername.Text ) ),
                      PAnsiChar( UTF8String( edtPassword.Text ) ), 
                      'Unicode username and password' ) ;
    // add error checking here
  end
  else
    showmessage( 'Connection Failed: ' + IntToStr(RetVal));
end;
Once the user has been created you can then connect using the same type of casting.
procedure TForm1.btnLoginClick(Sender: TObject);
var
  FhConnection   : AdsNativeInt;
  RetVal         : Cardinal;
begin
  // Connect using the supplied username and password
  RetVal := ace.AdsConnect60('C:\Data\TestDb\TestDb.add', ADS_REMOTE_SERVER,
                   PAnsiChar( UTF8String( edtUsername.Text ) ),
                   PAnsiChar( UTF8String( edtPassword.Text ) ),
                   ADS_DEFAULT, @FhConnection );

  if ( RetVal = AE_SUCCESS ) then
    showmessage( 'Connection Successful!' );
  else
    showmessage( 'Connection Failed: ' + IntToStr(RetVal));
end;

You can do similar conversions in other languages as well. If you need code for a specific language let me know and I'll get some additional examples posted.

No comments: