⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umysqlclient.pas

📁 RO模拟器!!适合玩仙境传说的玩家们呦~
💻 PAS
📖 第 1 页 / 共 5 页
字号:
                    {$IFDEF _WIN_}
                       fhost:=LOCAL_HOST_NAMEDPIPE;
                    {$ELSE}
                       fhost:='localhost';
                    {$ENDIF}
                    if (funix_socket='') or
                    {$IFDEF _WIN_}
                    (funix_socket<>MYSQL_NAMEDPIPE)
                    {$ELSE}
                    (funix_socket<>MYSQL_UNIX_ADDR)
                    {$ENDIF}
                    then
                    {$IFDEF _WIN_}
                       funix_socket:=MYSQL_NAMEDPIPE;
                    {$ELSE}
                       funix_socket:=MYSQL_UNIX_ADDR;
                    {$ENDIF}
               end; //if not mark we don't use named pipe
               if (fnet.vio_type<>VIO_TYPE_NAMEDPIPE)and(fnet.vio_type<>VIO_TYPE_SOCKET) then
               begin
                    fnamed_pipe:=false;
                    funix_socket:='';
               end;
          end;
     end
     else
         begin
              fnet.net_open(VIO_TYPE_TCPIP,fhost,funix_socket,fport,fconnect_timeout,true);
              funix_socket:='';
         end;
     //are we connected?
     if fnet.net_connected then
     begin
          pkt_length:=fnet.net_safe_read;
          if (pkt_length = packet_error) then
          begin //if we got an error
               fnet.net_close;
               result:=false;
               exit;
          end;
          //we have the start packet 
          fnet.protocol_version:= byte(pchar(fnet.read_pos)[0]);
          if (fnet.protocol_version <> PROTOCOL_VERSION) and
             (fnet.protocol_version <> PROTOCOL_VERSION-1) then
          begin //do we speak same protocol?
               fnet.last_errno:= CR_VERSION_ERROR;
               fnet.last_error:=format(client_errors[(fnet.last_errno)-CR_MIN_ERROR], [protocol_version,PROTOCOL_VERSION]);
               fnet.net_close;
               result:=false;
               exit;
          end;
          curpos:=1;
          //read server version
          fserver_version:=copy(pchar(fnet.read_pos+curpos),1,length(pchar(fnet.read_pos+curpos)));
          curpos:=curpos+length(fserver_version);
          //read thread id
          fthread_id:= byte(pchar(longint(fnet.read_pos+curpos)+1)^)+
                       byte(pchar(longint(fnet.read_pos+curpos+2))^)shl 8+
                       byte(pchar(longint(fnet.read_pos+curpos+3))^)shl 16+
                       byte(pchar(longint(fnet.read_pos+curpos+4))^)shl 24;
          curpos:=curpos+5;
          //get scramble buffer
          fscramble_buff:=copy(pchar(fnet.read_pos+curpos),1,8);
          curpos:=curpos+9;
          //read server capabilities
          if (pkt_length >= (longint(fnet.read_pos+curpos)+1 - (fnet.read_pos))) then
             fserver_capabilities:=byte(pchar(longint(fnet.read_pos+curpos))^)+
                                   byte(pchar(longint(fnet.read_pos+curpos+1))^)shl 8;
          //if we have server language and server status
          if (pkt_length >= (longint(fnet.read_pos+curpos)+18 - fnet.read_pos)) then
          begin
               fserver_language:=byte(pchar(fnet.read_pos+curpos)[2]);
               fserver_status:=byte(pchar(fnet.read_pos+curpos+3)[0])+byte(pchar(fnet.read_pos+curpos+3)[1])shl 8;
          end;

          //time to do some writing
          fclient_flag:=fclient_flag or CLIENT_CAPABILITIES;
          {$IFDEF HAVE_SSL}
          if (fuse_ssl) then
             fclient_flag:=fclient_flag or CLIENT_SSL;
          {$ENDIF}
          //if initial db is specified
          if (fdb<>'') then
             fclient_flag:=fclient_flag or CLIENT_CONNECT_WITH_DB;
          //if we have compression can we enable it?
          {$IFDEF HAVE_COMPRESS}
          if ((fserver_capabilities and CLIENT_COMPRESS=CLIENT_COMPRESS) and
             (fcompress or (fclient_flag and CLIENT_COMPRESS=CLIENT_COMPRESS))) then
             fclient_flag:=fclient_flag or CLIENT_COMPRESS
          else
          {$ENDIF} // seems we don't use/need compression
              fclient_flag:=fclient_flag and not(CLIENT_COMPRESS);
          {$IFDEF HAVE_SSL}
          if ((fserver_capabilities AND CLIENT_SSL=CLIENT_SSL) and
             (fuse_ssl or (fclient_flag and CLIENT_SSL=CLIENT_SSL))) then
             fclient_flag := fclient_flag or CLIENT_SSL //this does nothing
          else
          if (fclient_flag and CLIENT_SSL=CLIENT_SSL) then
          begin
               fclient_flag :=fclient_flag and (not (CLIENT_SSL));
               fuse_ssl:=false;
          end;
          {$ENDIF}
          //set client flags in buffer
          buff[0]:=chr(fclient_flag);
          buff[1]:=chr(fclient_flag shr 8);
          {$IFDEF HAVE_SSL}
          if (fclient_flag AND CLIENT_SSL=CLIENT_SSL) then
          begin
          if ((fnet.my_net_write(@buff,2)<>0) or (fnet.net_flush<>0)) then
          begin
               fnet.net_close;
               result:=false;
               exit;
          end;
          apc:=pchar(fssl_cipher);
          fnet.SwitchToSSL(pchar(fssl_key),pchar(fssl_cert),pchar(fssl_ca),pchar(fssl_capath),apc, fconnect_timeout);
          fssl_cipher:=apc;
          if (fnet.vio_type<>VIO_TYPE_SSL)and(fclient_flag and CLIENT_SSL=CLIENT_SSL) then
          begin
               fclient_flag :=fclient_flag and (not (CLIENT_SSL));//clear ssl flag
               result:=false; //mark error on ssl
               fuse_ssl:=false;
               SSL_ReadError;
               exit;
          end;
          end;
          {$ENDIF}
          //set max allowed packet
          pchar(longint(@buff)+2)[0]:=chr(max_allowed_packet);
          pchar(longint(@buff)+2)[1]:= chr(max_allowed_packet shr 8);
          pchar(longint(@buff)+2)[2]:= chr(max_allowed_packet shr 16);
          //do we have an user name?
          if (fuser <>'') then
          begin
               i:=length(fuser);
               if i>32 then //is it longer than 32
                  i:=32;
               move(pchar(fuser)[0],pchar(@buff[5])^,i); //copy it to the buffer
               curpos:=i+5+1;
          end
          else
              curpos:=6;
          //if we have password
          if (fpasswd<>'') then
          begin
               somp:=mysql_scramble(fpasswd,fscramble_buff);
               i:=length(somp);
               move(somp[0],pchar(@buff[curpos])^,i);
               strdispose(somp);
               curpos:=curpos+i+1;
          end
          else
              inc(curpos);
          //do we have a db?
          if (fdb<>'') and ((fserver_capabilities and CLIENT_CONNECT_WITH_DB)=CLIENT_CONNECT_WITH_DB) then
          begin
               i:=length(fdb);
               if i>NAME_LEN then
                  i:=NAME_LEN;
               move(pchar(fdb)[0],pchar(@buff[curpos])^,i);
               curpos:=curpos+i;
          end
          else
              inc(curpos);
          //we have the buffer filled, let's send it
          if (fnet.my_net_write(@buff,curpos)<>0) then
          begin //errors?
               fnet.net_close;
               result:=false;
               exit;
          end;
          //let's flush it
          if (fnet.net_flush<>0) then
          begin //errors?
               fnet.net_close;
               result:=false;
               exit;
          end;
          //did it got to the server? are we logged in?
          if (fnet.net_safe_read = packet_error) then
          begin //errors?
               fnet.net_close;
               result:=false;
               exit;
          end;
          //we use compression? let's tell to net to activate it
          if (fclient_flag and CLIENT_COMPRESS = CLIENT_COMPRESS)then
             fnet.compress:=true
          else
              fnet.compress:=false;
          //we are ready to work
          fstatus:=MYSQL_STATUS_READY;
          //if server does not support connect with db
          //we need to select the db
          if (fdb<>'') and (not ((fserver_capabilities and CLIENT_CONNECT_WITH_DB)=CLIENT_CONNECT_WITH_DB))and (not select_db(fdb)) then
          begin //errors on select db?
               fnet.net_close;
               result:=false;
               exit;
          end;
     end
     else //we are not connected
          result:=false;
     end;
end;

////////////////////////////////////////////////////////////////////////////////
//sends a query to the server and attempts to read the result
// if StoreResult is true then it will create a result in store mode, else it will be used
// rather than creating an empty result to mark an ok executed query ExecutedOk variable
// will be set to true
// !! Pay attention to it since it is the only way to know if a query with no
// result set was executed ok
function TMysqlClient.query(const aquery: string; StoreResult:boolean; var ExecutedOk:boolean): TMysqlResult;
begin
     result:=nil;
     executedOk:=false;
     if freconnect then
        if not ping then//this will reconnect if we lost the connection in the mean time
           exit;
     if (simple_command(COM_QUERY,aquery,length(aquery),true,freconnect)=0) then
        if read_query_result=0 then
        begin
             if StoreResult then
             begin
                  result:=store_result;
                  fnet.net_pack;//we can pack the net now
             end
             else
                 result:=use_result;
             executedOk:=true;
        end
end;

////////////////////////////////////////////////////////////////////////////////
// tells to server to performs a refresh
function TMysqlClient.refresh(options: longint): boolean;
var buff:string[3];
begin
     buff[0]:=chr(options);
     buff[1]:=chr(options shr 8);
     buff[2]:=chr(options shr 16);
     buff[3]:=chr(options shr 24);
     result:=simple_command(COM_REFRESH,buff,4,false,freconnect)=0;
end;

////////////////////////////////////////////////////////////////////////////////
// attempt to change the current selected db
function TMysqlClient.select_db(const newdb: string): boolean;
begin
     result:=simple_command(COM_INIT_DB,newdb,length(newdb),false,freconnect)=0;
     if result then
        fdb:=newdb;
end;

////////////////////////////////////////////////////////////////////////////////
// tells to server to shutdown
// current logged in user will need permission to do that
function TMysqlClient.shutdown: boolean;
begin
     result:=simple_command(COM_SHUTDOWN,'',0,false,freconnect)=0;
     close;
end;

////////////////////////////////////////////////////////////////////////////////
// get the statistics from server
function TMysqlClient.stat: string;
begin
     if (simple_command(COM_STATISTICS,'',0,false,freconnect)<>0) then //try to send the command
        result:=''//fnet.last_error //there was an error
     else //no error
         begin
              if pchar(fnet.read_pos)[0]=#0 then //did we got an empty string?
              begin
                   fnet.last_errno:=CR_WRONG_HOST_INFO;
                   fnet.last_error:= client_errors[(fnet.last_errno)-CR_MIN_ERROR];
                   result:='';//fnet.last_error;
              end
              else
                  result:=pchar(fnet.read_pos); //return stats
         end;
end;

////////////////////////////////////////////////////////////////////////////////
// reconnects to the server
// returns true if success
function TMysqlClient.reconnect: boolean;
begin
     if (not freconnect) or
        (fserver_status and SERVER_STATUS_IN_TRANS =SERVER_STATUS_IN_TRANS) then
     begin
          fserver_status:=fserver_status and not SERVER_STATUS_IN_TRANS;
          result:=false;
          exit;
     end;
     //fnet.net_close;
     if not connect then
        result:=false
     else
         result:=true;
end;

////////////////////////////////////////////////////////////////////////////////
// internal send file to server for use with load data infile on client machine
function TMysqlClient.send_file_to_server(const filename: string): longint;
var readcount:longint;
    buf:array[0..IO_SIZE*15-1] of char;
    f:file;
    tmp:byte;
begin
     //todo     fn_format(buf,filename,"","",4);
     assignfile(f,filename);
     tmp:=filemode; //old filemode
     filemode:=0; //read only
     {$I-}
     reset(f,1); //try to open the file
     {$I+}
     if (IOResult<> 0) then
     begin
          fnet.last_errno:=0;// EE_FILENOTFOUND
          fnet.last_error:=copy(format('File ''%s'' not found (Errcode: %d)',[filename,IOResult]),1,length(fnet.last_error));
          fnet.my_net_write('',0); //send empty packet to server
          fnet.net_flush;
          result:=-1;
          filemode:=tmp;
          exit;
     end;
     blockread(f,buf,sizeof(buf),readcount); //let's send the file
     while (readcount > 0) do //while we still have things in file
     begin
          if (fnet.my_net_write(buf,readcount)<>0) then //maybe we have errors?
          begin
               fnet.last_errno:=CR_SERVER_LOST;
               fnet.last_error:=client_errors[(fnet.last_errno)-CR_MIN_ERROR];
               closefile(f);
               result:=-1;
               filemode:=tmp;
               exit;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -