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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? uwebdataaccess.pas

?? 抽象三層訪問數(shù)據(jù)庫示例
?? PAS
?? 第 1 頁 / 共 2 頁
字號:
{*******************************************************}
{       軟件名稱: --通用--                              }
{       單元名稱: uWebDataAccess.pas                    }
{       中文名稱: Web數(shù)據(jù)訪問類                         }
{       單元描述: Web方式訪問數(shù)據(jù),本地不進行任何數(shù)據(jù)訪 }
{                 問操作                                }
{       創(chuàng)    建: SamonHua                              }
{       創(chuàng)建日期: 2007-12-18                            }
{       修    改: 參見VSS記錄                           }
{       版權(quán)所有 (C)2002-2007 深圳壹平臺信息技術(shù)有限公司}
{*******************************************************}
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;
    //填充關(guān)鍵字段值列表,空的補<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
    //此方法主要是通過用戶調(diào)用的關(guān)鍵字段名找到原始的字段名,避免字段名大小寫不一致
    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);
    //加載數(shù)據(jù)
//    ShowMessage('assign cds data');
    tmpCDS.Data := Data;
    if tmpCDS.ChangeCount > 0 then
    begin
      tmpCDSDelta.Data := tmpCDS.Delta;
      tmpCDS.MergeChangeLog;
      //刪除未修改的數(shù)據(jù)
      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;
    //復(fù)制XML節(jié)點
    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');
    //修改字段數(shù)據(jù)類型
    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;
    //添加關(guān)鍵字段列表節(jié)點"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"節(jié)點
    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('空數(shù)據(jù)集引用,不能正常轉(zhuǎn)換為XML數(shù)據(jù)文件');
//      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('不能查詢數(shù)據(jù)數(shù)據(jù)。'
        + #13#10'SQL:'#13#10'%s'
        + #13#10'錯誤:'#13#10'%s', [TableNameOrSQL, e.Message]);
  end;
end;

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

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品动漫网站| 久久国产夜色精品鲁鲁99| 高清日韩电视剧大全免费| 欧美精品一区二区三区一线天视频| 五月天中文字幕一区二区| 欧美久久久久久久久久| 日本伊人午夜精品| 精品国产污污免费网站入口| 精品一区二区在线播放| 国产人久久人人人人爽| 91啪九色porn原创视频在线观看| 亚洲伦理在线精品| 欧美一激情一区二区三区| 久久国产精品色| 国产精品久久午夜夜伦鲁鲁| 91福利精品视频| 日本美女一区二区三区| 国产午夜亚洲精品午夜鲁丝片 | 91网站最新网址| 亚洲a一区二区| 久久女同性恋中文字幕| 色乱码一区二区三区88| 美女视频网站黄色亚洲| 欧美激情综合五月色丁香小说| 在线视频综合导航| 久久成人综合网| 亚洲欧美精品午睡沙发| 91精品国产91热久久久做人人| 国产成人一区在线| 偷拍自拍另类欧美| 国产精品久久免费看| 91精品国产乱| 99久久99久久精品免费观看 | 亚洲乱码精品一二三四区日韩在线| 精品视频在线看| 成人综合在线网站| 日韩国产在线观看| 亚洲日本在线天堂| 亚洲精品在线电影| 欧美日韩一区二区在线观看视频 | 免费观看30秒视频久久| 亚洲欧美日韩在线播放| 精品国产乱码久久| 欧美在线一二三| 不卡视频一二三| 国内精品嫩模私拍在线| 亚洲午夜精品网| 中文字幕在线观看不卡| 26uuu欧美日本| 在线播放中文字幕一区| 欧洲精品视频在线观看| 国产91精品一区二区麻豆亚洲| 天堂资源在线中文精品| 亚洲欧美日韩综合aⅴ视频| 久久久久亚洲蜜桃| 欧美一二三四在线| 欧美肥大bbwbbw高潮| 在线看日韩精品电影| av电影在线观看一区| 国产电影一区二区三区| 麻豆久久一区二区| 日韩av一级电影| 亚洲国产va精品久久久不卡综合| 亚洲欧美另类久久久精品| 国产精品久久久久影视| 国产日产欧美一区二区三区| 久久久久久久一区| 26uuu精品一区二区在线观看| 69堂国产成人免费视频| 欧美久久一二三四区| 欧美日韩三级一区二区| 欧美色图一区二区三区| 色综合久久久久| 一本一道波多野结衣一区二区| jlzzjlzz亚洲女人18| 成人免费av资源| 成人免费看片app下载| 国产精品 欧美精品| 国产一区二区精品久久91| 国产一区在线不卡| 国产成人在线免费观看| 国产一区二区三区香蕉 | 99久久精品国产导航| 99国产一区二区三精品乱码| 99久久综合国产精品| 99久久久免费精品国产一区二区| av亚洲精华国产精华精华| 99久久99久久精品免费看蜜桃 | 成人激情免费视频| 99久久精品一区二区| 欧洲精品视频在线观看| 欧美精品久久天天躁| 日韩精品影音先锋| 久久精品日产第一区二区三区高清版 | 国产亚洲自拍一区| 国产精品欧美久久久久一区二区 | 久久精品欧美日韩精品| 国产精品三级av| 亚洲久草在线视频| 日韩专区欧美专区| 国产老女人精品毛片久久| 91丨porny丨国产入口| 精品视频在线免费看| 日韩限制级电影在线观看| 国产日本一区二区| 亚洲一区二区中文在线| 毛片av一区二区| 99精品久久99久久久久| 欧美日韩精品免费| 久久婷婷一区二区三区| 亚洲视频1区2区| 日韩成人免费在线| 成人高清视频免费观看| 欧美日韩国产三级| 国产色产综合产在线视频| 亚洲国产精品嫩草影院| 精品在线观看视频| 一本大道久久精品懂色aⅴ| 91精品国产91综合久久蜜臀| 国产精品入口麻豆原神| 日韩不卡一区二区| 91在线视频播放| 精品福利视频一区二区三区| 亚洲欧美日韩一区二区三区在线观看| 日本视频中文字幕一区二区三区| 成人h精品动漫一区二区三区| 欧美日韩视频一区二区| 国产精品丝袜91| 麻豆中文一区二区| 欧美丝袜丝交足nylons| 国产精品天美传媒沈樵| 免费成人结看片| 色偷偷成人一区二区三区91| 精品国产凹凸成av人网站| 亚洲国产精品久久久男人的天堂| 国产99久久久国产精品潘金网站| 欧美日韩综合在线免费观看| 国产精品热久久久久夜色精品三区| 视频一区二区欧美| 一本色道a无线码一区v| 久久久不卡网国产精品二区| 国产精品一区二区91| 7777精品伊人久久久大香线蕉超级流畅 | 欧美一区二区三区人| 一区二区三区影院| 国产成人日日夜夜| 精品国产凹凸成av人导航| 日韩国产欧美视频| 欧美手机在线视频| 亚洲综合丁香婷婷六月香| 91原创在线视频| 国产精品久久久久精k8| 大美女一区二区三区| 久久亚洲免费视频| 蜜桃av一区二区| 欧美一区二区三区四区五区| 亚洲v中文字幕| 欧美日韩中文字幕精品| 亚洲一区二区视频在线| 色偷偷成人一区二区三区91| 亚洲欧美福利一区二区| 91网址在线看| 亚洲欧美另类在线| 色又黄又爽网站www久久| 国产精品久线在线观看| 国产aⅴ综合色| 国产精品乱人伦中文| 成人激情免费视频| 亚洲视频香蕉人妖| 色婷婷久久综合| 亚洲精品成人在线| 欧美午夜宅男影院| 性感美女极品91精品| 3d动漫精品啪啪1区2区免费 | 国产乱子轮精品视频| 久久久国产精品不卡| 东方欧美亚洲色图在线| 久久精品在这里| 99免费精品视频| 亚洲一区二区三区美女| 制服视频三区第一页精品| 奇米色一区二区| 精品福利视频一区二区三区| 国产高清精品在线| 中文字幕在线观看一区二区| 日本丰满少妇一区二区三区| 亚洲高清免费观看 | 亚洲v精品v日韩v欧美v专区| 欧美一卡在线观看| 国产精品99精品久久免费| 国产精品久久久久久久久搜平片 | 最近日韩中文字幕| 欧美午夜免费电影| 奇米综合一区二区三区精品视频| 久久这里只有精品首页| 99久久精品免费看国产| 日韩专区欧美专区| 国产精品污www在线观看| 欧美性受xxxx黑人xyx性爽| 麻豆国产91在线播放|