亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? uwebdataaccess.pas

?? 抽象三層訪問數據庫示例
?? PAS
?? 第 1 頁 / 共 2 頁
字號:
{*******************************************************}
{       軟件名稱: --通用--                              }
{       單元名稱: uWebDataAccess.pas                    }
{       中文名稱: Web數據訪問類                         }
{       單元描述: Web方式訪問數據,本地不進行任何數據訪 }
{                 問操作                                }
{       創    建: SamonHua                              }
{       創建日期: 2007-12-18                            }
{       修    改: 參見VSS記錄                           }
{       版權所有 (C)2002-2007 深圳壹平臺信息技術有限公司}
{*******************************************************}
unit uWebDataAccess;

interface

uses
  SysUtils, Classes, Variants, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdHTTP, DB, DBClient, XMLIntf, XMLDoc, uCommon, uIDataAccess,
  uDataAccess, uDataAccessCommon, uXMLCommon, IdURI;

type
  TWebDataAccess = class(TDataAccess)
  private
    FIdHTTP: TIdHTTP;
    function GetIdHTTP: TIdHTTP;
    property IdHTTP: TIdHTTP read GetIdHTTP;
    function URLEncode(URL: string): string;
    function ParamsEncode(Params: string): string;

    function RequestRemoteGet(URL: string): string; overload;
    procedure RequestRemoteGet(URL: string; ResponseContent: TStream); overload;
    function RequestRemotePost(URL: string; Source: TStream): string; overload;
    function RequestRemotePost(URL: string; Source: TStrings): string; overload;
    function RequestRemotePost(URL, Params: string): string; overload;
    procedure RequestRemotePost(URL: string; Source: TStrings; ResponseContent: TStream); overload;
    procedure RequestRemotePost(URL: string; Source, ResponseContent: TStream); overload;
    procedure RequestRemotePost(URL, Params: string; ResponseContent: TStream); overload;

    function XMLAsData(AXMLNode: IXMLNode): OleVariant; overload;
    function XMLAsData(XML: string; TableNameOrIndex: Variant): OleVariant; overload;
    function XMLAsData(XML: string): OleVariant; overload;
    function DataAsXML(Data: OleVariant; const TableNameOrSQL, KeyFields: string): string; overload;
    function DataAsXML(Data: TBatchDataSet): string; overload;
    function DataAsXML(DataList: TList): string; overload;
    //填充關鍵字段值列表,空的補<null>
    function FillKeyValues(KeyFields, KeyValues: string): string;
  protected
  public
    function GetData(const TableNameOrSQL: string): OleVariant; override;
    function GetID(const TableName: string): string; override;
    function UpdateData(Data: OleVariant; const TableNameOrSQL, KeyFields: string): Boolean; override;
    function UpdateBatchData(BatchDataList: TList): Boolean; override;
    function ExcuteSQL(const ASQL: string): Boolean; override;
    function GetBlobContent(const TableName, KeyFieldName, KeyFieldValue, BlobFieldName: string;
      BlobFieldContent: TStream): boolean; override;
    function GetFileContent(const AFileName: string; FileContent: TStream): boolean; override;
    function UpdateBlobContent(const TableName, KeyFieldName, KeyFieldValue, BlobFieldName: string;
      BlobFieldContent: TStream): boolean; override;
  end;

implementation

const
  {QueryDataURL = 'operateDataAction.do?method=queryData&strSql=%s';
  GeneratorIDURL = 'operateDataAction.do?method=generatorID&tableName=%s';
  UpdateDataURL = 'operateDataAction.do?method=updateData&strXMLData=%s';
  ExcuteSQLURL = 'operateDataAction.do?method=excuteSQL&strSql=%s';
  QueryBlobContentURL = 'operateDataAction.do?method=queryBlobContent&tableName=%s&keyFieldName=%s&keyFieldValue=%s&blobFieldName=%s';
  UpdateBlobContentURL = 'operateDataAction.do?method=updateBlobContent&tableName=%s&keyFieldName=%s&keyFieldValue=%s&blobFieldName=%s';}
  OperateBaseURL = 'operateDataAction.do';
  QueryDataURL = 'method=queryData&strSql=%s';
  GeneratorIDURL = 'method=generatorID&tableName=%s';
  UpdateDataURL = 'method=updateData&strXMLData=%s';
  ExcuteSQLURL = 'method=excuteSQL&strSql=%s';
  QueryBlobContentURL = 'method=queryBlobContent&tableName=%s&keyFieldName=%s&keyFieldValue=%s&blobFieldName=%s';
  UpdateBlobContentURL = 'method=updateBlobContent&tableName=%s&keyFieldName=%s&keyFieldValue=%s&blobFieldName=%s';

{ TWebDataAccess }

function TWebDataAccess.DataAsXML(Data: TBatchDataSet): string;
begin
  //ShowMessage('xxx: ' + booltostr(Assigned(Data), True));
  Result := DataAsXML(Data.Data, Data.TableName, Data.KeyFields);
end;

function TWebDataAccess.DataAsXML(Data: OleVariant; const TableNameOrSQL,
  KeyFields: string): string;
var
  tmpCDS, tmpCDSDelta: TClientDataSet;
  XMLDocument, XMLNewDocument: IXMLDocument;
  XMLChildNode: IXMLNode;
  XMLTableNode, XMLMetaDataNode, XMLKeyFieldsNode, XMLFieldsNode,
    XMLParamsNode, XMLRowDataNode, XMLDeleteRowDataNode: IXMLNode;
  tmpStream: TMemoryStream;
  strFieldName, strFieldType: string;
  i: integer;

  function LocateUpdateStatus: boolean;
  var
    varKeyValues: Variant;
    i: Integer;
  begin
    Result := False;
    varKeyValues := VarArrayCreate([0, SubStrCount(KeyFields)], varVariant);
    for i := 0 to SubStrCount(KeyFields) do
      varKeyValues[i] := tmpCDS.FieldByName(CopySubStr(KeyFields, i)).Value;
    Result := tmpCDSDelta.Locate(KeyFields, varKeyValues, [loCaseInsensitive]);
  end;

  function KeyFieldName(FieldName: string): string;
  var
    tmpXMLNode: IXMLNode;
  begin
    //此方法主要是通過用戶調用的關鍵字段名找到原始的字段名,避免字段名大小寫不一致
    Result := FieldName;
    if XMLFieldsNode = nil then
      exit;
    tmpXMLNode := TXMLHelper.GetChildNode(XMLFieldsNode, 'FIELD', '', 'attrname=' + FieldName);
    if tmpXMLNode <> nil then
      Result := TXMLHelper.GetNodeAttributeValue(tmpXMLNode, 'attrname');
  end;

  function GetAttribute: string;
  var
    i: Integer;
  begin
    Result := '';
    for i := 0 to SubStrCount(KeyFields) do
    begin
      strFieldName := CopySubStr(KeyFields, i);
      Result := Result + Format('%s=%s;', [KeyFieldName(strFieldName), tmpCDSDelta.FieldByName(strFieldName).AsString]);
    end;
    if Result <> '' then
      Delete(Result, Length(Result), 1);
  end;

  procedure FormatDateFieldValue;
  var
    i, j: integer;
    tmpFieldList: TStringList;
    strFieldValues, strFieldValue: string;
    tmpDate: TDateTime;
    recFormat: TFormatSettings;
  begin
    if XMLRowDataNode = nil then
      exit;
    tmpFieldList := TStringList.Create;
    try
      for i := 0 to tmpCDS.FieldCount - 1 do
        if tmpCDS.Fields[i].DataType in [ftDate, ftTime, ftDateTime] then
        tmpFieldList.Add(tmpCDS.Fields[i].FieldName);
      if tmpFieldList.Count = 0 then
        exit;
      for i := 0 to XMLRowDataNode.ChildNodes.Count - 1 do
        if TXMLHelper.NodeNameEqual(XMLRowDataNode.ChildNodes[i], 'ROW') then
        begin
          strFieldValues := '';
          for j := 0 to tmpFieldList.Count - 1 do
          begin
            strFieldValue := TXMLHelper.GetNodeAttributeValue(XMLRowDataNode.ChildNodes[i], tmpFieldList[j]);
            if strFieldValue = ''then
              Continue;
            recFormat.DateSeparator := #0;
            recFormat.ShortDateFormat := 'yyyymmdd';
            if TryStrToDateTime(strFieldValue, tmpDate, recFormat) then
              strFieldValues := strFieldValues + Format('%s=%s;', [tmpFieldList[j],
                FormatDateTime('yyyy-mm-dd hh:nn:ss', tmpDate)])
            else
              if Length(strFieldValue) = 8 then
              begin
                strFieldValue := Format('%s-%s-%s', [Copy(strFieldValue, 1, 4),
                  Copy(strFieldValue, 5, 2), Copy(strFieldValue, 7, 2)]);
                strFieldValues := strFieldValues + Format('%s=%s;', [tmpFieldList[j], strFieldValue]);
              end
              else
                strFieldValues := strFieldValues + Format('%s=%s;', [tmpFieldList[j], '']);
          end;
          if strFieldValues = '' then
            Continue
          else
            Delete(strFieldValues, Length(strFieldValues), 1);
          TXMLHelper.AddAttributes(XMLRowDataNode.ChildNodes[i], strFieldValues);
        end;
    finally
      tmpFieldList.Free;
    end;
  end;
begin
//Data必須傳的是TClientDataSet.Data,而不能是TClientDataSet.Delta。否則此處生成XML文件有異常
  tmpCDS := TClientDataSet.Create(self);
  tmpCDSDelta := TClientDataSet.Create(self);
  tmpStream := TMemoryStream.Create;
//  ShowMessage('begin to xml');
  XMLDocument := NewXMLDocument;
  XMLNewDocument := TXMLHelper.NewXMLDocument('1.0', 'GBK', 'DATAPACKET');
  try
    //初始化XML
    XMLNewDocument.Options := XMLNewDocument.Options + [doNodeAutoIndent];
    TXMLHelper.AddAttributes(XMLNewDocument.DocumentElement, 'Version=2.0');
    XMLTableNode := TXMLHelper.CreateNode(XMLNewDocument.DocumentElement, 'TABLE', '', 'NAME=' + TableNameOrSQL);
    //加載數據
//    ShowMessage('assign cds data');
    tmpCDS.Data := Data;
    if tmpCDS.ChangeCount > 0 then
    begin
      tmpCDSDelta.Data := tmpCDS.Delta;
      tmpCDS.MergeChangeLog;
      //刪除未修改的數據
      tmpCDS.First;
      while not tmpCDS.Eof do
        if LocateUpdateStatus then
          tmpCDS.Next
        else
          tmpCDS.Delete;
      i := tmpCDS.RecordCount;
      if tmpCDS.ChangeCount > 0 then
        tmpCDS.MergeChangeLog;
    end;
    tmpCDS.SaveToStream(tmpStream, dfXMLUTF8);
//    ShowMessage('save cds data to xml file');
//    tmpCDS.SaveToFile('c:\cds_data.xml', dfXMLUTF8);
    tmpStream.Position := 0;
    //復制XML節點
    XMLDocument.LoadFromStream(tmpStream);
    for i := 0 to XMLDocument.DocumentElement.ChildNodes.Count - 1 do
    begin
      XMLChildNode := XMLDocument.DocumentElement.ChildNodes[i].CloneNode(true);
      XMLTableNode.ChildNodes.Add(XMLChildNode);
    end;
    XMLMetaDataNode := TXMLHelper.GetChildNode(XMLTableNode, 'METADATA');
    XMLFieldsNode := TXMLHelper.GetChildNode(XMLMetaDataNode, 'FIELDS');
    XMLParamsNode := TXMLHelper.GetChildNode(XMLMetaDataNode, 'PARAMS');
    XMLRowDataNode := TXMLHelper.GetChildNode(XMLTableNode, 'ROWDATA');
    //修改字段數據類型
    if XMLFieldsNode <> nil then
      for i := 0 to XMLFieldsNode.ChildNodes.Count - 1 do
        begin
          XMLChildNode := XMLFieldsNode.ChildNodes[i];
          if TXMLHelper.NodeNameEqual(XMLChildNode, 'FIELD') then
          begin
            strFieldType := TXMLHelper.GetNodeAttributeValue(XMLChildNode, 'fieldtype');
            if CompareText(strFieldType, 'r8') = 0 then
              strFieldType := 'NUMERIC'
            else if CompareText(strFieldType, 'dateTime') = 0 then
              strFieldType := 'DATE'
            else
              strFieldType := 'VARCHAR';
            TXMLHelper.AddAttributes(XMLChildNode, 'fieldtype=' + strFieldType);
          end;
        end;
    //添加關鍵字段列表節點"KEYFIELDS"
    if (KeyFields <> '') and (XMLMetaDataNode <> nil) then
    begin
      XMLKeyFieldsNode := XMLNewDocument.CreateNode('KEYFIELDS');
      XMLMetaDataNode.ChildNodes.Insert(0, XMLKeyFieldsNode);
      for i := 0 to SubStrCount(KeyFields) do
      begin
        strFieldName := CopySubStr(KeyFields, i);
        if strFieldName = '' then
          Continue;
        TXMLHelper.CreateNode(XMLKeyFieldsNode, 'KEYFIELD', KeyFieldName(strFieldName));
      end;
    end;
    //刪除多余的"PARAMS"節點
    if (XMLMetaDataNode <> nil) and (XMLParamsNode <> nil) then
      XMLMetaDataNode.ChildNodes.Delete(XMLMetaDataNode.ChildNodes.IndexOf(XMLParamsNode));
    //添加刪除的記錄
    if (KeyFields <> '') and tmpCDSDelta.Active and (not tmpCDSDelta.IsEmpty) then
    begin
      XMLDeleteRowDataNode := TXMLHelper.CreateNode(XMLTableNode, 'DELETEROWDATA', '');
      tmpCDSDelta.First;
      while not tmpCDSDelta.Eof do
      begin
        case tmpCDSDelta.UpdateStatus of
          usDeleted:
            TXMLHelper.CreateNode(XMLDeleteRowDataNode, 'ROW', '', GetAttribute);
        end;
        tmpCDSDelta.Next;
      end;           
    end;
    //FormatDateFieldValue;
    Result := XMLNewDocument.XML.Text;
    //XMLNewDocument.SaveToFile('c:\data.xml');
  finally
    XMLNewDocument := nil;
    XMLDocument := nil;
    tmpStream.Free;
    tmpCDSDelta.Free;
    tmpCDS.Free;
  end;
end;

function TWebDataAccess.DataAsXML(DataList: TList): string;
var
  tmpBatchDataSet: TBatchDataSet;
  i: integer;
  XMLDocument, XMLSubDocument: IXMLDocument;
  XMLNewNode, XMLChildNode: IXMLNode;
begin
  Result := '';
  if DataList.Count = 0 then
    exit;
  XMLDocument := TXMLHelper.NewXMLDocument('1.0', 'GBK', 'DATAPACKET');
  try
    XMLDocument.Options := XMLDocument.Options + [doNodeAutoIndent];
    TXMLHelper.AddAttributes(XMLDocument.DocumentElement, 'Version=2.0');
    for i := 0 to DataList.Count - 1 do
    begin
      tmpBatchDataSet := TBatchDataSet(DataList.Items[i]);
      if tmpBatchDataSet = nil then
        raise Exception.Create('空數據集引用,不能正常轉換為XML數據文件');
//      ShowMessage('begin data to xml');
      XMLSubDocument := LoadXMLData(DataAsXML(tmpBatchDataSet));
//      ShowMessage('end data to xml');
      try
        XMLNewNode := TXMLHelper.GetChildNode(XMLSubDocument.DocumentElement, 'TABLE');
        XMLNewNode := XMLNewNode.CloneNode(true);
        XMLDocument.DocumentElement.ChildNodes.Add(XMLNewNode);
      finally
        XMLSubDocument := nil;
      end;
    end;
    Result := XMLDocument.XML.Text;
//    XMLDocument.SaveToFile('c:\batch_data.xml');
  finally
    XMLDocument := nil;
  end;
end;

function TWebDataAccess.ExcuteSQL(const ASQL: string): Boolean;
var
  strURL, strResponse: string;
begin
  strURL := Format('%s%s?' + ExcuteSQLURL, [WebURL, OperateBaseURL, ParamsEncode(ASQL)]);
  strResponse := RequestRemoteGet(strURL);
  Result := StrToBoolDef(strResponse, False);
end;

function TWebDataAccess.GetBlobContent(const TableName, KeyFieldName,
  KeyFieldValue, BlobFieldName: string;
  BlobFieldContent: TStream): boolean;
var
  strURL: string;
begin
  strURL := Format('%s%s?' + QueryBlobContentURL, [WebURL, OperateBaseURL,
    TableName, ParamsEncode(KeyFieldName), ParamsEncode(FillKeyValues(KeyFieldName,
      KeyFieldValue)), BlobFieldName]);
  RequestRemoteGet(strURL, BlobFieldContent);
  Result := True;
end;

function TWebDataAccess.GetData(const TableNameOrSQL: string): OleVariant;
var
  strURL, strURLParams: string;

  function GetSQL(ASQL: string): string;
  begin
    Result := trim(ASQL);
    if Pos(' ', Result) = 0 then//僅表名
      Result := Format('select * from %s', [Result]);
  end;
  
  function ConvertTableNameToSQL(ASQL: string): string;
  var
    i: Integer;
  begin
    Result := '';
    for i := 0 to SubStrCount(ASQL) do
      Result := Result + GetSQL(CopySubStr(ASQL, i)) + ';';
    if Result <> '' then
      Delete(Result, Length(Result), 1);
  end;
begin
  try
    strURL := Format('%s%s', [WebURL, OperateBaseURL]);
    strURLParams := Format(QueryDataURL, [ParamsEncode(ConvertTableNameToSQL(TableNameOrSQL))]);
    if Pos(';', TableNameOrSQL) > 0 then//檢查是否多條語句
      Result := XMLAsData(RequestRemotePost(strURL, strURLParams))
    else
      Result := XMLAsData(RequestRemotePost(strURL, strURLParams), 0);
  except
    on e: Exception do
      raise Exception.CreateFmt('不能查詢數據數據。'
        + #13#10'SQL:'#13#10'%s'
        + #13#10'錯誤:'#13#10'%s', [TableNameOrSQL, e.Message]);
  end;
end;

function TWebDataAccess.GetID(const TableName: string): string;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美日韩一级黄| 色综合天天天天做夜夜夜夜做| 欧美日韩视频在线第一区| 亚洲一二三四区| 在线播放中文字幕一区| 免费人成黄页网站在线一区二区| 日韩欧美高清dvd碟片| 国产又黄又大久久| 国产精品蜜臀在线观看| 在线观看成人小视频| 五月婷婷综合在线| 久久先锋影音av鲁色资源网| 成人免费毛片高清视频| 伊人婷婷欧美激情| 精品免费日韩av| 99久久精品99国产精品 | 欧美又粗又大又爽| 日产精品久久久久久久性色| 亚洲精品一区二区三区四区高清 | 亚洲国产视频网站| 日韩欧美一区在线| 99久久精品免费观看| 日韩中文字幕不卡| 国产欧美日韩在线看| 欧美午夜精品一区二区蜜桃| 精品亚洲国产成人av制服丝袜| 中文字幕欧美一区| 91精品国产综合久久精品| 国产精品一级二级三级| 亚洲午夜av在线| 日本一区二区三区久久久久久久久不| 91浏览器在线视频| 国内精品嫩模私拍在线| 一区二区三区在线观看动漫| 日韩亚洲国产中文字幕欧美| 99国产精品一区| 看片的网站亚洲| 亚洲乱码中文字幕综合| 精品久久久久久久人人人人传媒 | 久久成人av少妇免费| 综合分类小说区另类春色亚洲小说欧美| 欧美性生交片4| 成人午夜激情影院| 爽爽淫人综合网网站| 国产精品乱码人人做人人爱| 欧美一卡二卡在线| 欧美四级电影在线观看| 成人午夜av影视| 久久99精品国产91久久来源| 亚洲一区二区3| 自拍偷拍国产亚洲| 国产午夜久久久久| 欧美本精品男人aⅴ天堂| 欧美性生活影院| 色哟哟一区二区| 成人免费毛片aaaaa**| 国产自产视频一区二区三区| 五月婷婷欧美视频| 亚洲综合精品自拍| 专区另类欧美日韩| 国产精品久久久久精k8| 国产日韩欧美高清| 中文字幕av在线一区二区三区| 精品精品欲导航| 精品日韩99亚洲| 日韩免费观看2025年上映的电影| 欧美精品高清视频| 欧美日韩日本视频| 欧美日韩国产一区二区三区地区| 日本黄色一区二区| 91黄视频在线| 欧美性猛片aaaaaaa做受| 在线一区二区观看| 欧美视频中文字幕| 欧美日韩视频在线第一区| 欧美日韩精品一区二区三区蜜桃 | 日韩黄色免费网站| 免费人成精品欧美精品| 免费一区二区视频| 伦理电影国产精品| 久久99热狠狠色一区二区| 美洲天堂一区二卡三卡四卡视频 | 国产最新精品免费| 韩国女主播一区二区三区| 另类中文字幕网| 国产乱码精品一区二区三区忘忧草| 精品一区二区综合| 国产精品性做久久久久久| 福利一区二区在线| 日本黄色一区二区| 91精品中文字幕一区二区三区| 欧美mv和日韩mv的网站| 国产日韩一级二级三级| 中文字幕一区二区三区色视频| 中文字幕日韩欧美一区二区三区| 亚洲天堂av一区| 亚洲综合激情网| 青青草91视频| 国产mv日韩mv欧美| 日本大香伊一区二区三区| 欧美最猛黑人xxxxx猛交| 欧美日韩国产另类不卡| 2021中文字幕一区亚洲| 国产精品剧情在线亚洲| 一区二区三区四区不卡在线 | 欧美日韩一区中文字幕| 欧美一二三在线| 国产视频一区二区在线观看| 亚洲丝袜精品丝袜在线| 视频在线观看91| 国产一区福利在线| 91丨九色丨蝌蚪丨老版| 日韩一级成人av| 国产精品乱码久久久久久| 亚洲va欧美va人人爽午夜| 久久99日本精品| 色老头久久综合| 欧美成人一区二区三区| 最好看的中文字幕久久| 精品在线免费观看| 欧美主播一区二区三区美女| 日韩一区二区三区视频在线观看| 亚洲欧洲在线观看av| 久久国产免费看| 欧美综合亚洲图片综合区| 亚洲精品一区二区精华| 亚洲午夜免费视频| 国产不卡在线视频| 91精品视频网| 亚洲男同1069视频| 国内一区二区在线| 在线观看国产一区二区| 亚洲国产精品99久久久久久久久| 亚洲电影一区二区三区| 成人午夜在线视频| 欧美r级电影在线观看| 亚洲成a人片在线观看中文| 成人18视频日本| 精品国产精品网麻豆系列| 一区二区成人在线| 91老师国产黑色丝袜在线| 亚洲国产精品v| 国产精品夜夜嗨| 久久这里只有精品视频网| 三级精品在线观看| 色先锋资源久久综合| 国产精品视频免费看| 国产一区二三区| 日韩精品一区在线观看| 日韩精品五月天| 欧美日韩国产另类一区| 亚洲一区二区三区在线看| 91小宝寻花一区二区三区| 欧美高清一级片在线观看| 国产精品一区二区在线观看网站| 欧美一级片在线观看| 亚洲电影欧美电影有声小说| 欧美性受xxxx| 天堂精品中文字幕在线| 欧美无乱码久久久免费午夜一区| 中文字幕一区av| www.色综合.com| 国产精品久久久久永久免费观看 | 精品国偷自产国产一区| 蜜臀久久99精品久久久久久9| 欧美日韩一卡二卡| 婷婷激情综合网| 91精品国产免费久久综合| 美女脱光内衣内裤视频久久影院| 欧美夫妻性生活| 蓝色福利精品导航| 国产日本一区二区| 成人av午夜影院| 一区二区三区四区国产精品| 欧美视频一区二| 欧美区视频在线观看| 国产激情视频一区二区在线观看| 免费在线观看成人| 精品中文字幕一区二区| 国产精品美女久久久久aⅴ国产馆 国产精品美女久久久久av爽李琼 国产精品美女久久久久高潮 | 亚洲精品在线一区二区| 国产一区二区三区黄视频| 国产日韩欧美高清| 99re热这里只有精品免费视频 | 亚洲一二三四区| 欧美一级久久久| 国产高清不卡二三区| ●精品国产综合乱码久久久久| 色婷婷国产精品久久包臀 | 亚洲欧美另类小说视频| 在线观看亚洲精品视频| 免费看日韩a级影片| 国产亚洲视频系列| 色婷婷激情一区二区三区| 日韩黄色在线观看| 国产午夜精品福利| 色天使久久综合网天天| 日本不卡不码高清免费观看| 国产免费成人在线视频| 欧美揉bbbbb揉bbbbb|