LAPTOP-SNT8I5JK\Boounion
2025-09-09 c119b8ef36718a8ca24b719cdbff86913cbca129
1.Glass数据库保存,查询,分页,关键字,时间段等功能;
已添加5个文件
已修改15个文件
271215 ■■■■■ 文件已修改
SourceCode/Bond/Servo/CGlass.cpp 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CGlass.h 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CJobDataS.cpp 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CJobDataS.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGlassList.cpp 280 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGlassList.h 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CServoUtilsTool.cpp 83 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CServoUtilsTool.h 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/GlassJson.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/GlassLogDb.cpp 526 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/GlassLogDb.h 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Model.cpp 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.rc 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj.filters 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ToolUnits.cpp 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ToolUnits.h 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/sqlite3.c 255811 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/sqlite3.h 13357 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/sqlite3ext.h 719 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CGlass.cpp
@@ -50,7 +50,7 @@
        return strText;
    }
    MaterialsType CGlass::getType()
    MaterialsType CGlass::getType() const
    {
        return m_type;
    }
@@ -65,7 +65,7 @@
        m_strID = pszID;
    }
    std::string& CGlass::getID()
    const std::string& CGlass::getID() const
    {
        return m_strID;
    }
@@ -107,7 +107,7 @@
        return m_pPath;
    }
    std::string CGlass::getPathDescription()
    std::string CGlass::getPathDescription() const
    {
        std::string strOut, strPath;
        char szBuffer[256];
@@ -126,7 +126,7 @@
        return strOut;
    }
    CPath* CGlass::getPathWithEq(unsigned int nEqId, unsigned int nUnit)
    CPath* CGlass::getPathWithEq(unsigned int nEqId, unsigned int nUnit) const
    {
        CPath* pTemp = m_pPath;
        while (pTemp != nullptr) {
@@ -238,9 +238,14 @@
        return m_pBuddy;
    }
    std::string& CGlass::getBuddyId()
    const std::string& CGlass::getBuddyId() const
    {
        return m_strBuddyId;
    }
    void CGlass::setBuddyId(std::string& strId)
    {
        m_strBuddyId = strId;
    }
    int CGlass::processEnd(unsigned int nEqId, unsigned int nUnit)
@@ -269,12 +274,17 @@
        return 0;
    }
    InspResult CGlass::getInspResult(unsigned int nEqId, unsigned int nUnit)
    InspResult CGlass::getInspResult(unsigned int nEqId, unsigned int nUnit) const
    {
        CPath* pPath = getPathWithEq(nEqId, nUnit);
        if (pPath == nullptr) return InspResult::NotInspected;
        return pPath->getInspResult();
    }
    InspResult CGlass::getAOIInspResult() const
    {
        return getInspResult(EQ_ID_MEASUREMENT, 0);
    }
    std::string CGlass::getStateText()
@@ -381,11 +391,13 @@
    void CGlass::markStart()
    {
        m_state = GlsState::InProcess;
        m_tStart = std::chrono::system_clock::now();
    }
    void CGlass::markEnd()
    {
        m_state = GlsState::Completed;
        m_tEnd = std::chrono::system_clock::now();
    }
@@ -399,7 +411,7 @@
        return m_params;
    }
    std::string CGlass::getParamsDescription()
    std::string CGlass::getParamsDescription() const
    {
        std::string strOut;
SourceCode/Bond/Servo/CGlass.h
@@ -33,23 +33,23 @@
    public:
        virtual std::string& getClassName();
        virtual std::string toString();
        short getCassetteSequenceNo() { return m_jobDataS.getCassetteSequenceNo(); }
        short getJobSequenceNo() { return m_jobDataS.getJobSequenceNo(); }
        MaterialsType getType();
        short getCassetteSequenceNo() const { return m_jobDataS.getCassetteSequenceNo(); }
        short getJobSequenceNo() const { return m_jobDataS.getJobSequenceNo(); }
        MaterialsType getType() const;
        void setType(MaterialsType type);
        void setID(const char* pszID);
        std::string& getID();
        const std::string& getID() const;
        void setOriginPort(int port, int slot);
        void getOrginPort(int& port, int& slot);
        BOOL isScheduledForProcessing();
        void setScheduledForProcessing(BOOL bProcessing);
        CProcessJob* getProcessJob();
        void setProcessJob(CProcessJob* pProcessJob);
        CPath* getPathWithEq(unsigned int nEqId, unsigned int nUnit);
        CPath* getPathWithEq(unsigned int nEqId, unsigned int nUnit) const;
        CPath* getPath();
        void addPath(unsigned int nEqId, unsigned int nUnit);
        std::string getPathDescription();
        std::string getParamsDescription();
        std::string getPathDescription() const;
        std::string getParamsDescription() const;
        void serialize(CArchive& ar);
        void setJobDataS(CJobDataS* pJobDataS);
        void updateJobDataS(CJobDataS* pJobDataS);
@@ -57,11 +57,13 @@
        BOOL setBuddy(CGlass* pGlass);
        BOOL forceSetBuddy(CGlass* pGlass);
        CGlass* getBuddy();
        std::string& getBuddyId();
        const std::string& getBuddyId() const;
        void setBuddyId(std::string& strId);
        int processEnd(unsigned int nEqId, unsigned int nUnit);
        BOOL isProcessed(unsigned int nEqId, unsigned int nUnit);
        int setInspResult(unsigned int nEqId, unsigned int nUnit, InspResult result);
        InspResult getInspResult(unsigned int nEqId, unsigned int nUnit);
        InspResult getInspResult(unsigned int nEqId, unsigned int nUnit) const;
        InspResult getAOIInspResult() const;
    public:
        // æ–°å¢žçŠ¶æ€
SourceCode/Bond/Servo/CJobDataS.cpp
@@ -143,7 +143,7 @@
        m_pOwner = pOwner;
    }
    int CJobDataS::getCassetteSequenceNo()
    int CJobDataS::getCassetteSequenceNo() const
    {
        return m_nCassetteSequenceNo;
    }
@@ -153,7 +153,7 @@
        m_nCassetteSequenceNo = no;
    }
    int CJobDataS::getJobSequenceNo()
    int CJobDataS::getJobSequenceNo() const
    {
        return m_nJobSequenceNo;
    }
SourceCode/Bond/Servo/CJobDataS.h
@@ -18,9 +18,9 @@
        void copy(CJobDataS* pScr);
        void update(CJobDataS* pScr);
        CJobDataB& getJobDataB(CJobDataB& jobDataB);
        int getCassetteSequenceNo();
        int getCassetteSequenceNo() const;
        void setCassetteSequenceNo(int no);
        int getJobSequenceNo();
        int getJobSequenceNo() const;
        void setJobSequenceNo(int no);
        std::string& getLotId();
        void setLotId(const char* pszId);
SourceCode/Bond/Servo/CPageGlassList.cpp
@@ -6,9 +6,11 @@
#include "CPageGlassList.h"
#include "afxdialogex.h"
#include "GlassJson.h"
#include "CServoUtilsTool.h"
#include "ToolUnits.h"
#define PAGE_SIZE                        100
#define PAGE_SIZE                        10
#define PAGE_BACKGROUND_COLOR            RGB(252, 252, 255)
// CPageGlassList å¯¹è¯æ¡†
@@ -23,9 +25,8 @@
    m_pObserver = nullptr;
    m_strStatus = "";
    m_strKeyword = "";
    m_nCurPage = 0;
    m_nTotalPages = 0;
    m_nTotalPages = 1;
    memset(m_szTimeStart, 0, sizeof(m_szTimeStart));
    memset(m_szTimeEnd, 0, sizeof(m_szTimeEnd));
@@ -198,7 +199,7 @@
    //m_dateTimeEnd.ModifyStyle(0, DTS_TIMEFORMAT);
}
void CPageGlassList::LoadTransfers()
void CPageGlassList::LoadData()
{
    m_nCurPage = 1;
    UpdatePageData();
@@ -206,19 +207,36 @@
void CPageGlassList::UpdatePageData()
{
    /*
    TransferData filter;
    filter.strStatus = m_strStatus;
    filter.strDescription = m_strKeyword;
    filter.strCreateTime = m_szTimeStart;
    filter.strEndTime = m_szTimeEnd;
    auto vecData = TransferManager::getInstance().getTransfers(filter, m_nCurPage, PAGE_SIZE);
    FillDataToListCtrl(vecData);
    // æŸ¥è¯¢
    auto& db = GlassLogDb::Instance();
    auto page = db.queryPaged(m_filters, PAGE_SIZE, PAGE_SIZE * (m_nCurPage - 1));
    m_listCtrl.DeleteAllItems();
    for (const auto& r : page.items) {
        int index = m_listCtrl.InsertItem(m_listCtrl.GetItemCount(), std::to_string(r.id).c_str());
        m_listCtrl.SetItemText(index, 1, std::to_string(r.cassetteSeqNo).c_str());
        m_listCtrl.SetItemText(index, 2, std::to_string(r.jobSeqNo).c_str());
        m_listCtrl.SetItemText(index, 3, r.classId.c_str());
        m_listCtrl.SetItemText(index, 4, SERVO::CServoUtilsTool::getMaterialsTypeText((SERVO::MaterialsType)r.materialType).c_str());
        m_listCtrl.SetItemText(index, 5, SERVO::CServoUtilsTool::getGlassStateText((SERVO::GlsState)r.state).c_str());
        m_listCtrl.SetItemText(index, 6, r.tStart.c_str());
        m_listCtrl.SetItemText(index, 7, r.tEnd.c_str());
        m_listCtrl.SetItemText(index, 8, r.buddyId.c_str());
        m_listCtrl.SetItemText(index, 9, SERVO::CServoUtilsTool::getInspResultText((SERVO::InspResult)r.aoiResult).c_str());
        m_listCtrl.SetItemText(index, 10, r.path.c_str());
        m_listCtrl.SetItemText(index, 11, r.params.c_str());
    int nTotalRecords = TransferManager::getInstance().getFilteredTransferCount(filter);
    m_nTotalPages = (nTotalRecords + PAGE_SIZE - 1) / PAGE_SIZE;
        // æµ‹è¯•反序列化
        /*
        SERVO::CGlass g2;
        std::string err;
        if (GlassJson::FromString(r.pretty, g2, &err)) {
            AfxMessageBox(r.pretty.c_str());
        }
        */
    }
    // ä¸Šä¸€é¡µ / ä¸‹ä¸€é¡µ
    UpdatePageControls();
    */
}
void CPageGlassList::UpdatePageControls()
@@ -228,91 +246,8 @@
    SetDlgItemText(IDC_LABEL_PAGE_NUMBER, strPage);
    GetDlgItem(IDC_BUTTON_PREV_PAGE)->EnableWindow(m_nCurPage > 1);
    GetDlgItem(IDC_BUTTON_NEXT_PAGE)->EnableWindow(m_nCurPage < m_nTotalPages);
    Resize();
}
void CPageGlassList::UpdateDateFilter()
{
    CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DATETIME);
    if (nullptr != pComboBox) {
        int nIndex = pComboBox->GetCurSel();
        if (nIndex == 0) {
            memset(m_szTimeStart, 0, sizeof(m_szTimeStart));
            memset(m_szTimeEnd, 0, sizeof(m_szTimeEnd));
            m_szTimeStart[0] = '\0';
            m_szTimeEnd[0] = '\0';
        }
        else {
            CTime time = CTime::GetCurrentTime();
            if (nIndex == 1) {
                sprintf_s(m_szTimeStart, 64, "%d-%02d-%02d 00:00:00", time.GetYear(), time.GetMonth(), time.GetDay());
                sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d 23:59:59", time.GetYear(), time.GetMonth(), time.GetDay());
            }
            else if (nIndex == 2) {
                CTime time2 = time - CTimeSpan(7, 0, 0, 0);
                sprintf_s(m_szTimeStart, 64, "%d-%02d-%02d 00:00:00", time2.GetYear(), time2.GetMonth(), time2.GetDay());
                sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d 23:59:59", time.GetYear(), time.GetMonth(), time.GetDay());
            }
            else if (nIndex == 3) {
                sprintf_s(m_szTimeStart, 64, "%d-%02d-01 00:00:00", time.GetYear(), time.GetMonth());
                sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d 23:59:59", time.GetYear(), time.GetMonth(), time.GetDay());
            }
            else if (nIndex == 4) {
                sprintf_s(m_szTimeStart, 64, "%d-01-01 00:00:00", time.GetYear());
                sprintf_s(m_szTimeEnd, 64, "%d-12-31 23:59:59", time.GetYear());
            }
            else if (nIndex == 5) {
                SYSTEMTIME t1, t2;
                m_dateTimeStart.GetTime(&t1);
                m_dateTimeEnd.GetTime(&t2);
                //sprintf_s(m_szTimeStart, 64, "%d-%02d-%02d %02d:%02d:%02d", t1.wYear, t1.wMonth, t1.wDay, t1.wHour, t1.wMinute, t1.wSecond);
                //sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d %02d:%02d:%02d", t2.wYear, t2.wMonth, t2.wDay, t2.wHour, t2.wMinute, t2.wSecond);
                sprintf_s(m_szTimeStart, 64, "%d-%02d-%02d 00:00:00", t1.wYear, t1.wMonth, t1.wDay);
                sprintf_s(m_szTimeEnd, 64, "%d-%02d-%02d 23:59:59", t2.wYear, t2.wMonth, t2.wDay);
            }
        }
    }
}
/*
void CPageGlassList::FillDataToListCtrl(const std::vector<TransferData>& vecData)
{
    if (m_listCtrl.m_hWnd == nullptr) {
        return;
    }
    m_listCtrl.DeleteAllItems();
    for (const auto& item : vecData) {
        InsertTransferData(item);
    }
}
void CPageGlassList::InsertTransferData(const TransferData& data)
{
    if (m_listCtrl.m_hWnd == nullptr) {
        return;
    }
    int nIndex = m_listCtrl.GetItemCount();
    if (nIndex < 0) {
        return;
    }
    int nItem = m_listCtrl.InsertItem(nIndex, _T(""));
    CString str;
    str.Format(_T("%d"), data.nRecordId);
    m_listCtrl.SetItemText(nItem, 1, str);
    m_listCtrl.SetItemText(nItem, 2, CString(data.strStatus.c_str()));
    m_listCtrl.SetItemText(nItem, 3, CString(data.strClassID.c_str()));
    m_listCtrl.SetItemText(nItem, 4, CString(data.strCreateTime.c_str()));
    m_listCtrl.SetItemText(nItem, 5, CString(data.strPickTime.c_str()));
    m_listCtrl.SetItemText(nItem, 6, CString(data.strPlaceTime.c_str()));
    m_listCtrl.SetItemText(nItem, 7, CString(data.strEndTime.c_str()));
    m_listCtrl.SetItemText(nItem, 8, CString(data.strDescription.c_str()));
}
*/
// CPageTransferLog æ¶ˆæ¯å¤„理程序
BOOL CPageGlassList::OnInitDialog()
@@ -342,7 +277,7 @@
    ListView_SetImageList(m_listCtrl.GetSafeHwnd(), imageList, LVSIL_SMALL);
    CString headers[] = { 
        _T(""),
        _T("id"),
        _T("Cassette Sequence No"),
        _T("Job Sequence No"),
        _T("Class ID"),
@@ -355,24 +290,15 @@
        _T("路径"),
        _T("工艺参数") 
    };
    int widths[] = { 0, 80, 80, 100, 120, 120, 120, 120, 200, 200, 200, 200 };
    int widths[] = { 80, 80, 80, 100, 120, 120, 120, 120, 200, 200, 200, 200 };
    for (int i = 0; i < _countof(headers); ++i) {
        strItem.Format(_T("Col_%d_Width"), i);
        widths[i] = GetPrivateProfileInt("GlassListCtrl", strItem, widths[i], strIniFile);
        m_listCtrl.InsertColumn(i, headers[i], LVCFMT_LEFT, widths[i]);
    }
    m_listCtrl.SetColumnWidth(10, LVSCW_AUTOSIZE_USEHEADER);
    // è®¡ç®—总页数
    /*
    int nTotalRecords = TransferManager::getInstance().getTotalTransferCountAll();
    m_nTotalPages = (nTotalRecords + PAGE_SIZE - 1) / PAGE_SIZE;
    m_nCurPage = 1;
    */
    Resize();
    LoadTransfers();
    OnBnClickedButtonSearch();
    return TRUE;  // return TRUE unless you set the focus to a control
    // å¼‚常: OCX å±žæ€§é¡µåº”返回 FALSE
@@ -440,8 +366,8 @@
    m_dateTimeEnd.EnableWindow(nIndex == nCount - 1);
    // æ›´æ–°æ—¥æœŸè¿‡æ»¤å™¨å’Œé¡µé¢æ•°æ®
    UpdateDateFilter();
    LoadTransfers();
    // UpdateDateFilter();
    // LoadTransfers();
}
void CPageGlassList::OnCbnSelchangeComboStatusFilter()
@@ -456,7 +382,7 @@
        pComboBox->GetLBText(nIndex, cstrText);
        m_strStatus = CT2A(cstrText);
    }
    LoadTransfers();
    // LoadTransfers();
}
void CPageGlassList::OnBnClickedButtonSearch()
@@ -464,11 +390,47 @@
    // èŽ·å–å…³é”®å­—è¾“å…¥æ¡†å†…å®¹
    CString strKeyword;
    GetDlgItemText(IDC_EDIT_KEYWORD, strKeyword);
    m_strKeyword = CT2A(strKeyword);
    m_filters.keyword = CT2A(strKeyword);
    // æ›´æ–°æ—¥æœŸè¿‡æ»¤å™¨å’Œé¡µé¢æ•°æ®
    UpdateDateFilter();
    LoadTransfers();
    CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_DATETIME);
    int index = pComboBox->GetCurSel();
    if (index == 0) {
        // ä¸é™
        m_filters.tStartFrom = std::nullopt;
        m_filters.tStartTo = std::nullopt;
    }
    else if (index == 1) {
        auto [fromUtc, toUtc] = CToolUnits::CalcQuickRangeUtc(QuickRange::Today);
        m_filters.tStartFrom = fromUtc;
        m_filters.tStartTo = toUtc;
    }
    else if (index == 2) {
        auto [fromUtc, toUtc] = CToolUnits::CalcQuickRangeUtc(QuickRange::Last7Days);
        m_filters.tStartFrom = fromUtc;
        m_filters.tStartTo = toUtc;
    }
    else if (index == 3) {
        auto [fromUtc, toUtc] = CToolUnits::CalcQuickRangeUtc(QuickRange::ThisMonth);
        m_filters.tStartFrom = fromUtc;
        m_filters.tStartTo = toUtc;
    }
    else if (index == 4) {
        auto [fromUtc, toUtc] = CToolUnits::CalcQuickRangeUtc(QuickRange::ThisYear);
        m_filters.tStartFrom = fromUtc;
        m_filters.tStartTo = toUtc;
    }
    else if(index == 5){
        // è‡ªå®šä¹‰
        std::chrono::system_clock::time_point tp;
        if (CToolUnits::GetCtrlDateRangeUtc_StartOfDay(m_dateTimeStart, tp)) m_filters.tStartFrom = tp;
        if (CToolUnits::GetCtrlDateRangeUtc_EndOfDay(m_dateTimeEnd, tp))   m_filters.tStartTo = tp;
    }
    auto& db = GlassLogDb::Instance();
    long long total = db.count(m_filters);
    m_nTotalPages = (PAGE_SIZE > 0) ? int((total + PAGE_SIZE - 1) / PAGE_SIZE) : 1;
    LoadData();
}
void CPageGlassList::OnBnClickedButtonExport()
@@ -478,90 +440,22 @@
        return;
    }
    CStdioFile file;
    if (!file.Open(fileDialog.GetPathName(), CFile::modeCreate | CFile::modeWrite | CFile::typeText)) {
        AfxMessageBox(_T("创建文件失败!"));
        return;
    // å¯¼å‡º CSV:导出符合 filters çš„“全部记录”(不受分页限制)
        // è¿”回导出的行数(不含表头)
        // csvPath:目标文件路径(UTF-8)
    auto& db = GlassLogDb::Instance();
    std::string csvPath((LPTSTR)(LPCTSTR)fileDialog.GetPathName());
    if (db.exportCsv(csvPath, m_filters) > 0) {
        AfxMessageBox("导出CSV成功!");
    }
    CString strHeader = _T("任务ID,状态,ClassID,创建时间,取片时间,放片时间,结束时间,描述\n");
    file.WriteString(strHeader);
    for (int i = 0; i < m_listCtrl.GetItemCount(); ++i) {
        CString row;
        for (int j = 1; j <= 8; ++j) {
            row += m_listCtrl.GetItemText(i, j);
            if (j != 8) {
                row += ",";
            }
        }
        row += "\n";
        file.WriteString(row);
    }
    file.Close();
}
void CPageGlassList::OnBnClickedButtonPrevPage()
{
    SERVO::CGlass g;
    g.setID("GLS-001");
    g.setType(SERVO::MaterialsType::G1);
    g.setOriginPort(1, 5);
    g.setScheduledForProcessing(TRUE);
    g.m_failReason = "none";
    g.markQueued();
    g.markStart();
    // æ·»åŠ å‚æ•°
    CParam p1("校正对位延时", "P001", "ms", 123);
    CParam p2("温度", "P002", "degC", 25.5);
    g.getParams().push_back(p1);
    g.getParams().push_back(p2);
    // è®¾ç½® JobDataS
    SERVO::CJobDataS* js = g.getJobDataS();
    js->setCassetteSequenceNo(10);
    js->setJobSequenceNo(20);
    js->setLotId("LOT-ABC");
    js->setGlass1Id("GLS-001");
    // æ·»åŠ  Path
    g.addPath(100, 1);
    SERVO::CPath* tail = g.getPath()->getTailPath();
    tail->setInTime(111111);
    tail->setOutTime(222222);
    tail->setInspResult(SERVO::InspResult::Pass);
    tail->processEnd();
    return;
    // 2. è½¬ä¸º JSON
    std::string jsonText = GlassJson::ToPrettyString(g);
    TRACE("序列化结果:\n%s\n\n", jsonText.c_str());
    // 3. ååºåˆ—化
    SERVO::CGlass g2;
    std::string err;
    if (!GlassJson::FromString(jsonText, g2, &err)) {
        TRACE("解析失败: %s\n", err.c_str());
        return;
    }
    // 4. æ‰“印验证
    TRACE("反序列化后的ID: %s\n", g2.getID().c_str());
    TRACE("反序列化后的参数数量: %d\n", (int)g2.getParams().size());
    if (!g2.getParams().empty()) {
        TRACE("第一个参数名: %s å€¼=%d\n",
            g2.getParams()[0].getName().c_str(),
            g2.getParams()[0].getIntValue());
    }
    if (m_nCurPage > 1) {
        m_nCurPage--;
        UpdatePageData();
    }
    }
}
void CPageGlassList::OnBnClickedButtonNextPage()
SourceCode/Bond/Servo/CPageGlassList.h
@@ -1,5 +1,6 @@
#pragma once
#include "ListCtrlEx.h"
#include "GlassLogDb.h"
// CPageGlassList å¯¹è¯æ¡†
@@ -18,8 +19,8 @@
    IObserver* m_pObserver;
    // æœç´¢å…³é”®å­—
    GlassLogDb::Filters m_filters;
    std::string m_strStatus;
    std::string m_strKeyword;
    // é¡µç 
    int m_nCurPage;
@@ -40,14 +41,10 @@
    void InitStatusCombo();
    void InitTimeRangeCombo();
    void InitDateTimeControls();
    void LoadTransfers();
    void LoadData();
    void UpdatePageData();
    void UpdatePageControls();
    void UpdateDateFilter();
    /*
    void FillDataToListCtrl(const std::vector<TransferData>& vecData);
    void InsertTransferData(const TransferData& data);
    */
// å¯¹è¯æ¡†æ•°æ®
#ifdef AFX_DESIGN_TIME
SourceCode/Bond/Servo/CServoUtilsTool.cpp
@@ -16,31 +16,13 @@
    std::string CServoUtilsTool::getEqUnitName(int eqid, int unit)
    {
        /*
#define EQ_ID_LOADPORT1            1
#define EQ_ID_LOADPORT2            2
#define EQ_ID_LOADPORT3            3
#define EQ_ID_LOADPORT4            4
#define EQ_ID_ARM_TRAY1            5
#define EQ_ID_ARM_TRAY2            6
#define EQ_ID_ALIGNER            7
#define EQ_ID_FLIPER            8
#define EQ_ID_VACUUMBAKE        9
#define EQ_ID_Bonder1            10
#define EQ_ID_Bonder2            11
#define EQ_ID_BAKE_COOLING        12
#define EQ_ID_MEASUREMENT        13
#define EQ_ID_EFEM                100
#define EQ_ID_ARM                101
#define EQ_ID_OPERATOR_REMOVE    102
*/
        char szBuffer[256];
        if (eqid == EQ_ID_LOADPORT1
            || eqid == EQ_ID_LOADPORT2
            || eqid == EQ_ID_LOADPORT3
            || eqid == EQ_ID_LOADPORT4
            ) {
            sprintf_s(szBuffer, 256, "Port%d(Slot%d)", unit, eqid - EQ_ID_LOADPORT1 + 1);
            sprintf_s(szBuffer, 256, "Port%d(Slot%d)", eqid - EQ_ID_LOADPORT1 + 1, unit + 1);
            return std::string(szBuffer);
        }
@@ -84,4 +66,67 @@
        return "";
    }
    std::string CServoUtilsTool::getMaterialsTypeText(MaterialsType type)
    {
        if (type == MaterialsType::G1) {
            return "G1";
        }
        if (type == MaterialsType::G2) {
            return "G2";
        }
        return "";
    }
    std::string CServoUtilsTool::getGlassStateText(SERVO::GlsState state)
    {
        switch (state)
        {
        case SERVO::GlsState::NoState:
            return "NoState";
            break;
        case SERVO::GlsState::Queued:
            return "Queued";
            break;
        case SERVO::GlsState::InProcess:
            return "InProcess";
            break;
        case SERVO::GlsState::Paused:
            return "Paused";
            break;
        case SERVO::GlsState::Completed:
            return "Completed";
            break;
        case SERVO::GlsState::Aborted:
            return "Aborted";
            break;
        case SERVO::GlsState::Failed:
            return "Failed";
            break;
        default:
            return "";
            break;
        }
    }
    std::string CServoUtilsTool::getInspResultText(SERVO::InspResult result)
    {
        switch (result)
        {
        case SERVO::InspResult::NotInspected:
            return "";
            break;
        case SERVO::InspResult::Pass:
            return "Pass";
            break;
        case SERVO::InspResult::Fail:
            return "Fail";
            break;
        default:
            return "";
            break;
        }
    }
}
SourceCode/Bond/Servo/CServoUtilsTool.h
@@ -1,4 +1,6 @@
#pragma once
#include "ServoCommo.h"
#include "CGlass.h"
namespace SERVO {
@@ -10,6 +12,9 @@
    public:
        static std::string getEqUnitName(int eqid, int unit);
        static std::string getMaterialsTypeText(MaterialsType type);
        static std::string getGlassStateText(SERVO::GlsState state);
        static std::string getInspResultText(SERVO::InspResult result);
    };
}
SourceCode/Bond/Servo/GlassJson.cpp
@@ -199,7 +199,7 @@
    // åŸºæœ¬
    g.setID(JStr(root, "id").c_str());
    g.setType(static_cast<MaterialsType>(JInt(root, "materials", 0)));
    g.getBuddyId() = JStr(root, "buddy_id");
    g.setBuddyId(JStr(root, "buddy_id"));
    g.setScheduledForProcessing(JBool(root, "scheduled") ? TRUE : FALSE);
    g.m_failReason = JStr(root, "fail_reason");
    g.setOriginPort(JInt(root, "origin_port", 0), JInt(root, "origin_slot", 0));
SourceCode/Bond/Servo/GlassLogDb.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,526 @@
// GlassLogDb.cpp - å•例封装:SQLite å†™å…¥/查询/分页/统计/CSV å¯¼å‡ºï¼ˆå·²å¯¹æŽ¥ SERVO::CGlass)
#include "stdafx.h"
#include "GlassLogDb.h"
#include "sqlite3.h"
#include <stdexcept>
#include <sstream>
#include <iomanip>
#include <ctime>
#include <fstream>
#include "GlassJson.h"
using namespace SERVO;
#ifndef GLASS_LOG_TABLE
#define GLASS_LOG_TABLE "glass_log"
#endif
// ================== å·¥å…·å‡½æ•° ==================
static void throwIf(int rc, sqlite3* db, const char* msg) {
    if (rc != SQLITE_OK && rc != SQLITE_DONE && rc != SQLITE_ROW) {
        std::ostringstream oss;
        oss << msg << " (rc=" << rc << "): " << (db ? sqlite3_errmsg(db) : "null db");
        throw std::runtime_error(oss.str());
    }
}
static inline const char* safe_text(sqlite3_stmt* s, int col) {
    const unsigned char* p = sqlite3_column_text(s, col);
    return p ? reinterpret_cast<const char*>(p) : "";
}
static std::string csvEscape(const std::string& s) {
    bool needQuote = s.find_first_of(",\"\n\r") != std::string::npos;
    if (!needQuote) return s;
    std::string out; out.reserve(s.size() + 2);
    out.push_back('"');
    for (char c : s) out += (c == '"') ? "\"\"" : std::string(1, c);
    out.push_back('"');
    return out;
}
static std::string toIso8601String(const std::optional<std::chrono::system_clock::time_point>& tp) {
    if (!tp.has_value()) return "";
    using namespace std::chrono;
    auto t = system_clock::to_time_t(*tp);
    std::tm tm{};
#if defined(_WIN32)
    gmtime_s(&tm, &t);
#else
    gmtime_r(&t, &tm);
#endif
    std::ostringstream oss;
    oss << std::put_time(&tm, "%Y-%m-%dT%H:%M:%SZ");
    return oss.str();
}
// ================== å•例静态成员 ==================
std::unique_ptr<GlassLogDb> GlassLogDb::s_inst;
std::mutex GlassLogDb::s_instMtx;
// ================== å•例接口实现 ==================
void GlassLogDb::Init(const std::string& dbPath) {
    std::lock_guard<std::mutex> g(s_instMtx);
    if (!s_inst) {
        s_inst.reset(new GlassLogDb(dbPath));
    }
    else if (s_inst->dbPath_ != dbPath) {
        s_inst->reopenInternal(dbPath);
    }
}
GlassLogDb& GlassLogDb::Instance() {
    std::lock_guard<std::mutex> g(s_instMtx);
    if (!s_inst) throw std::runtime_error("GlassLogDb::Instance() called before Init()");
    return *s_inst;
}
bool GlassLogDb::IsInitialized() noexcept {
    std::lock_guard<std::mutex> g(s_instMtx);
    return static_cast<bool>(s_inst);
}
void GlassLogDb::Reopen(const std::string& dbPath) {
    std::lock_guard<std::mutex> g(s_instMtx);
    if (!s_inst) {
        s_inst.reset(new GlassLogDb(dbPath));
    }
    else {
        s_inst->reopenInternal(dbPath);
    }
}
std::string GlassLogDb::CurrentPath() {
    std::lock_guard<std::mutex> g(s_instMtx);
    return s_inst ? s_inst->dbPath_ : std::string();
}
// ================== æž„造/打开/关闭/重开 ==================
GlassLogDb::GlassLogDb(const std::string& dbPath) {
    openDb(dbPath);
}
void GlassLogDb::openDb(const std::string& dbPath) {
    int rc = sqlite3_open_v2(dbPath.c_str(), &db_,
        SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX,
        nullptr);
    if (rc != SQLITE_OK) {
        std::string err = db_ ? sqlite3_errmsg(db_) : "open failed";
        if (db_) sqlite3_close(db_);
        db_ = nullptr;
        throw std::runtime_error("Failed to open sqlite DB: " + err + " | path=" + dbPath);
    }
    dbPath_ = dbPath;
    ensureSchema();
    prepareStatements();
}
void GlassLogDb::closeDb() noexcept {
    finalizeStatements();
    if (db_) {
        sqlite3_close(db_);
        db_ = nullptr;
    }
}
void GlassLogDb::reopenInternal(const std::string& dbPath) {
    std::lock_guard<std::mutex> lk(mtx_);
    if (dbPath == dbPath_) return;
    closeDb();
    openDb(dbPath);
}
// ================== æžæž„ ==================
GlassLogDb::~GlassLogDb() {
    closeDb();
}
// ================== DDL & é¢„编译 ==================
void GlassLogDb::ensureSchema() {
    const char* ddl =
        "CREATE TABLE IF NOT EXISTS " GLASS_LOG_TABLE " ("
        "  id INTEGER PRIMARY KEY AUTOINCREMENT,"
        "  cassette_seq_no INTEGER,"
        "  job_seq_no INTEGER,"
        "  class_id TEXT,"
        "  material_type INTEGER,"
        "  state INTEGER,"
        "  t_start TEXT,"      // ISO8601 UTC(可为 NULL)
        "  t_end TEXT,"        // ISO8601 UTC(可为 NULL)
        "  buddy_id TEXT,"
        "  aoi_result INTEGER,"
        "  path TEXT,"
        "  params TEXT,"
        "  pretty TEXT"
        ");"
        "CREATE INDEX IF NOT EXISTS idx_glass_key "
        "  ON " GLASS_LOG_TABLE " (cassette_seq_no, job_seq_no);"
        "CREATE INDEX IF NOT EXISTS idx_class_id "
        "  ON " GLASS_LOG_TABLE " (class_id);"
        "CREATE INDEX IF NOT EXISTS idx_t_start "
        "  ON " GLASS_LOG_TABLE " (t_start);";
    char* errMsg = nullptr;
    int rc = sqlite3_exec(db_, ddl, nullptr, nullptr, &errMsg);
    if (rc != SQLITE_OK) {
        std::string err = errMsg ? errMsg : "unknown";
        sqlite3_free(errMsg);
        throw std::runtime_error("Failed to create schema: " + err);
    }
}
void GlassLogDb::prepareStatements() {
    const char* sql =
        "INSERT INTO " GLASS_LOG_TABLE " ("
        " cassette_seq_no, job_seq_no, class_id, material_type, state,"
        " t_start, t_end, buddy_id, aoi_result, path, params, pretty)"
        " VALUES (?,?,?,?,?,?,?,?,?,?,?,?);";
    int rc = sqlite3_prepare_v2(db_, sql, -1, &stmtInsert_, nullptr);
    throwIf(rc, db_, "prepare insert");
}
void GlassLogDb::finalizeStatements() noexcept {
    if (stmtInsert_) {
        sqlite3_finalize(stmtInsert_);
        stmtInsert_ = nullptr;
    }
}
// ================== äº‹åŠ¡ ==================
void GlassLogDb::beginTransaction() {
    std::lock_guard<std::mutex> lk(mtx_);
    char* err = nullptr;
    int rc = sqlite3_exec(db_, "BEGIN IMMEDIATE;", nullptr, nullptr, &err);
    if (rc != SQLITE_OK) {
        std::string e = err ? err : "unknown";
        sqlite3_free(err);
        throw std::runtime_error("BEGIN failed: " + e);
    }
}
void GlassLogDb::commit() {
    std::lock_guard<std::mutex> lk(mtx_);
    char* err = nullptr;
    int rc = sqlite3_exec(db_, "COMMIT;", nullptr, nullptr, &err);
    if (rc != SQLITE_OK) {
        std::string e = err ? err : "unknown";
        sqlite3_free(err);
        throw std::runtime_error("COMMIT failed: " + e);
    }
}
void GlassLogDb::rollback() {
    std::lock_guard<std::mutex> lk(mtx_);
    char* err = nullptr;
    sqlite3_exec(db_, "ROLLBACK;", nullptr, nullptr, &err);
    if (err) sqlite3_free(err);
}
// ================== æ—¶é—´æ ¼å¼ ==================
std::string GlassLogDb::toIso8601Utc(std::chrono::system_clock::time_point tp) {
    using namespace std::chrono;
    auto t = system_clock::to_time_t(tp);
    std::tm tm{};
#if defined(_WIN32)
    gmtime_s(&tm, &t);
#else
    gmtime_r(&t, &tm);
#endif
    std::ostringstream oss;
    oss << std::put_time(&tm, "%Y-%m-%dT%H:%M:%SZ");
    return oss.str();
}
// ================== æ’入实现 ==================
long long GlassLogDb::doInsert(
    int cassetteSeqNo,
    int jobSeqNo,
    const std::string& classId,
    int materialType,
    int state,
    std::optional<std::chrono::system_clock::time_point> tStart,
    std::optional<std::chrono::system_clock::time_point> tEnd,
    const std::string& buddyId,
    int aoiResult,
    const std::string& pathDesc,
    const std::string& paramsDesc,
    const std::string& prettyString)
{
    std::lock_guard<std::mutex> lk(mtx_);
    int idx = 1;
    throwIf(sqlite3_reset(stmtInsert_), db_, "reset insert");
    throwIf(sqlite3_clear_bindings(stmtInsert_), db_, "clear bindings");
    throwIf(sqlite3_bind_int(stmtInsert_, idx++, cassetteSeqNo), db_, "bind cassette");
    throwIf(sqlite3_bind_int(stmtInsert_, idx++, jobSeqNo), db_, "bind job");
    throwIf(sqlite3_bind_text(stmtInsert_, idx++, classId.c_str(), -1, SQLITE_TRANSIENT), db_, "bind class_id");
    throwIf(sqlite3_bind_int(stmtInsert_, idx++, materialType), db_, "bind material_type");
    throwIf(sqlite3_bind_int(stmtInsert_, idx++, state), db_, "bind state");
    if (tStart.has_value()) {
        auto s = toIso8601Utc(*tStart);
        throwIf(sqlite3_bind_text(stmtInsert_, idx++, s.c_str(), -1, SQLITE_TRANSIENT), db_, "bind t_start");
    }
    else {
        throwIf(sqlite3_bind_null(stmtInsert_, idx++), db_, "bind t_start null");
    }
    if (tEnd.has_value()) {
        auto e = toIso8601Utc(*tEnd);
        throwIf(sqlite3_bind_text(stmtInsert_, idx++, e.c_str(), -1, SQLITE_TRANSIENT), db_, "bind t_end");
    }
    else {
        throwIf(sqlite3_bind_null(stmtInsert_, idx++), db_, "bind t_end null");
    }
    throwIf(sqlite3_bind_text(stmtInsert_, idx++, buddyId.c_str(), -1, SQLITE_TRANSIENT), db_, "bind buddy_id");
    throwIf(sqlite3_bind_int(stmtInsert_, idx++, aoiResult), db_, "bind aoi_result");
    throwIf(sqlite3_bind_text(stmtInsert_, idx++, pathDesc.c_str(), -1, SQLITE_TRANSIENT), db_, "bind path");
    throwIf(sqlite3_bind_text(stmtInsert_, idx++, paramsDesc.c_str(), -1, SQLITE_TRANSIENT), db_, "bind params");
    throwIf(sqlite3_bind_text(stmtInsert_, idx++, prettyString.c_str(), -1, SQLITE_TRANSIENT), db_, "bind pretty");
    int rc = sqlite3_step(stmtInsert_);
    throwIf(rc, db_, "insert step");
    return sqlite3_last_insert_rowid(db_);
}
long long GlassLogDb::insertFromCGlass(CGlass& g)
{
    const int cassette = static_cast<int>(g.getCassetteSequenceNo());
    const int job = static_cast<int>(g.getJobSequenceNo());
    const std::string& classId = g.getID();
    const int material = static_cast<int>(g.getType());
    const int state = static_cast<int>(g.state());
    const std::string& buddy = g.getBuddyId();
    const int aoiResult = static_cast<int>(g.getAOIInspResult());
    const std::string pathDesc = g.getPathDescription();
    const std::string paramsDesc = g.getParamsDescription();
    const std::string pretty = GlassJson::ToPrettyString(g);
    auto tStart = g.tStart();
    auto tEnd = g.tEnd();
    return doInsert(cassette, job, classId, material, state,
        tStart, tEnd, buddy, aoiResult, pathDesc, paramsDesc, pretty);
}
long long GlassLogDb::insertExplicit(
    int cassetteSeqNo,
    int jobSeqNo,
    const std::string& classId,
    int materialType,
    int state,
    std::optional<std::chrono::system_clock::time_point> tStart,
    std::optional<std::chrono::system_clock::time_point> tEnd,
    const std::string& buddyId,
    int aoiResult,
    const std::string& pathDesc,
    const std::string& paramsDesc,
    const std::string& prettyString)
{
    return doInsert(cassetteSeqNo, jobSeqNo, classId, materialType, state,
        tStart, tEnd, buddyId, aoiResult, pathDesc, paramsDesc, prettyString);
}
// ================== è¿‡æ»¤æž„造(where + bind) ==================
static std::string buildWhereSql(const GlassLogDb::Filters& f) {
    std::ostringstream where;
    bool first = true;
    auto add = [&](const std::string& cond) {
        if (first) { where << " WHERE " << cond; first = false; }
        else { where << " AND " << cond; }
    };
    if (f.classId)       add("class_id = ?");
    if (f.cassetteSeqNo) add("cassette_seq_no = ?");
    if (f.jobSeqNo)      add("job_seq_no = ?");
    if (f.keyword)       add("(class_id LIKE ? OR buddy_id LIKE ? OR path LIKE ? OR params LIKE ? OR pretty LIKE ?)");
    if (f.tStartFrom && f.tStartTo) add("(t_start >= ? AND t_start <= ?)");
    else if (f.tStartFrom)          add("t_start >= ?");
    else if (f.tStartTo)            add("t_start <= ?");
    return where.str();
}
static void bindFilters(sqlite3_stmt* stmt, sqlite3* db, int& idx, const GlassLogDb::Filters& f) {
    if (f.classId)       throwIf(sqlite3_bind_text(stmt, idx++, f.classId->c_str(), -1, SQLITE_TRANSIENT), db, "bind classId");
    if (f.cassetteSeqNo) throwIf(sqlite3_bind_int(stmt, idx++, *f.cassetteSeqNo), db, "bind cassette");
    if (f.jobSeqNo)      throwIf(sqlite3_bind_int(stmt, idx++, *f.jobSeqNo), db, "bind job");
    if (f.keyword) {
        std::string kw = "%" + *f.keyword + "%";
        for (int i = 0; i < 5; ++i)
            throwIf(sqlite3_bind_text(stmt, idx++, kw.c_str(), -1, SQLITE_TRANSIENT), db, "bind keyword");
    }
    if (f.tStartFrom && f.tStartTo) {
        std::string s = toIso8601String(f.tStartFrom);
        std::string e = toIso8601String(f.tStartTo);
        throwIf(sqlite3_bind_text(stmt, idx++, s.c_str(), -1, SQLITE_TRANSIENT), db, "bind tStartFrom");
        throwIf(sqlite3_bind_text(stmt, idx++, e.c_str(), -1, SQLITE_TRANSIENT), db, "bind tStartTo");
    }
    else if (f.tStartFrom) {
        std::string s = toIso8601String(f.tStartFrom);
        throwIf(sqlite3_bind_text(stmt, idx++, s.c_str(), -1, SQLITE_TRANSIENT), db, "bind tStartFrom");
    }
    else if (f.tStartTo) {
        std::string e = toIso8601String(f.tStartTo);
        throwIf(sqlite3_bind_text(stmt, idx++, e.c_str(), -1, SQLITE_TRANSIENT), db, "bind tStartTo");
    }
}
// ================== æŸ¥è¯¢ / ç»Ÿè®¡ / åˆ†é¡µ ==================
std::vector<GlassLogDb::Row> GlassLogDb::query(
    const Filters& filters,
    int limit,
    int offset)
{
    std::lock_guard<std::mutex> lk(mtx_);
    std::ostringstream sql;
    sql << "SELECT id, cassette_seq_no, job_seq_no, class_id, material_type, state,"
        " IFNULL(strftime('%Y-%m-%d %H:%M:%S', t_start, 'localtime'), ''),"
        " IFNULL(strftime('%Y-%m-%d %H:%M:%S', t_end,   'localtime'), ''),"
        " buddy_id, aoi_result, path, params, pretty"
        " FROM " GLASS_LOG_TABLE;
    std::string where = buildWhereSql(filters);
    sql << where
        << " ORDER BY id DESC"
        << " LIMIT " << (limit < 0 ? 0 : limit)
        << " OFFSET " << (offset < 0 ? 0 : offset);
    sqlite3_stmt* stmt = nullptr;
    throwIf(sqlite3_prepare_v2(db_, sql.str().c_str(), -1, &stmt, nullptr), db_, "prepare query");
    int idx = 1;
    bindFilters(stmt, db_, idx, filters);
    std::vector<Row> rows;
    for (;;) {
        int rc = sqlite3_step(stmt);
        if (rc == SQLITE_ROW) {
            Row r;
            r.id = sqlite3_column_int64(stmt, 0);
            r.cassetteSeqNo = sqlite3_column_int(stmt, 1);
            r.jobSeqNo = sqlite3_column_int(stmt, 2);
            r.classId = safe_text(stmt, 3);
            r.materialType = sqlite3_column_int(stmt, 4);
            r.state = sqlite3_column_int(stmt, 5);
            r.tStart = safe_text(stmt, 6);
            r.tEnd = safe_text(stmt, 7);
            r.buddyId = safe_text(stmt, 8);
            r.aoiResult = sqlite3_column_int(stmt, 9);
            r.path = safe_text(stmt, 10);
            r.params = safe_text(stmt, 11);
            r.pretty = safe_text(stmt, 12);
            rows.push_back(std::move(r));
        }
        else if (rc == SQLITE_DONE) {
            break;
        }
        else {
            sqlite3_finalize(stmt);
            throwIf(rc, db_, "query step");
        }
    }
    sqlite3_finalize(stmt);
    return rows;
}
long long GlassLogDb::count(const Filters& filters) {
    std::lock_guard<std::mutex> lk(mtx_);
    std::ostringstream sql;
    sql << "SELECT COUNT(1) FROM " GLASS_LOG_TABLE;
    std::string where = buildWhereSql(filters);
    sql << where;
    sqlite3_stmt* stmt = nullptr;
    throwIf(sqlite3_prepare_v2(db_, sql.str().c_str(), -1, &stmt, nullptr), db_, "prepare count");
    int idx = 1;
    bindFilters(stmt, db_, idx, filters);
    long long total = 0;
    int rc = sqlite3_step(stmt);
    if (rc == SQLITE_ROW) {
        total = sqlite3_column_int64(stmt, 0);
    }
    else if (rc != SQLITE_DONE) {
        sqlite3_finalize(stmt);
        throwIf(rc, db_, "count step");
    }
    sqlite3_finalize(stmt);
    return total;
}
GlassLogDb::Page GlassLogDb::queryPaged(
    const Filters& filters,
    int limit,
    int offset)
{
    Page p;
    p.limit = (limit < 0 ? 0 : limit);
    p.offset = (offset < 0 ? 0 : offset);
    p.total = count(filters);
    p.items = query(filters, p.limit, p.offset);
    return p;
}
// ================== å¯¼å‡º CSV(全部符合条件) ==================
long long GlassLogDb::exportCsv(const std::string& csvPath, const Filters& filters) {
    std::lock_guard<std::mutex> lk(mtx_);
    std::ofstream ofs(csvPath, std::ios::binary);
    if (!ofs) {
        throw std::runtime_error("Failed to open csv for write: " + csvPath);
    }
    // è¡¨å¤´
    ofs << "id,cassette_seq_no,job_seq_no,class_id,material_type,state,t_start,t_end,"
        "buddy_id,aoi_result,path,params,pretty\n";
    std::ostringstream sql;
    sql << "SELECT id, cassette_seq_no, job_seq_no, class_id, material_type, state,"
        " IFNULL(strftime('%Y-%m-%d %H:%M:%S', t_start, 'localtime'), ''),"
        " IFNULL(strftime('%Y-%m-%d %H:%M:%S', t_end,   'localtime'), ''),"
        " buddy_id, aoi_result, path, params, pretty"
        " FROM " GLASS_LOG_TABLE;
    std::string where = buildWhereSql(filters);
    sql << where << " ORDER BY id DESC";
    sqlite3_stmt* stmt = nullptr;
    throwIf(sqlite3_prepare_v2(db_, sql.str().c_str(), -1, &stmt, nullptr), db_, "prepare export");
    int idx = 1;
    bindFilters(stmt, db_, idx, filters);
    long long rows = 0;
    for (;;) {
        int rc = sqlite3_step(stmt);
        if (rc == SQLITE_ROW) {
            std::string id = std::to_string(sqlite3_column_int64(stmt, 0));
            std::string cassette = std::to_string(sqlite3_column_int(stmt, 1));
            std::string job = std::to_string(sqlite3_column_int(stmt, 2));
            std::string class_id = safe_text(stmt, 3);
            std::string material = std::to_string(sqlite3_column_int(stmt, 4));
            std::string state = std::to_string(sqlite3_column_int(stmt, 5));
            std::string t_start = safe_text(stmt, 6);
            std::string t_end = safe_text(stmt, 7);
            std::string buddy = safe_text(stmt, 8);
            std::string aoi = std::to_string(sqlite3_column_int(stmt, 9));
            std::string path = safe_text(stmt, 10);
            std::string params = safe_text(stmt, 11);
            std::string pretty = safe_text(stmt, 12);
            ofs << id << ','
                << cassette << ','
                << job << ','
                << csvEscape(class_id) << ','
                << material << ','
                << state << ','
                << t_start << ','
                << t_end << ','
                << csvEscape(buddy) << ','
                << aoi << ','
                << csvEscape(path) << ','
                << csvEscape(params) << ','
                << csvEscape(pretty) << '\n';
            ++rows;
        }
        else if (rc == SQLITE_DONE) {
            break;
        }
        else {
            sqlite3_finalize(stmt);
            throwIf(rc, db_, "export step");
        }
    }
    sqlite3_finalize(stmt);
    ofs.flush();
    return rows;
}
SourceCode/Bond/Servo/GlassLogDb.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,170 @@
#pragma once
// GlassLogDb.h - å•例封装:SQLite å†™å…¥/查询/分页/统计/CSV å¯¼å‡ºï¼ˆå·²å¯¹æŽ¥ SERVO::CGlass)
#include <string>
#include <vector>
#include <mutex>
#include <optional>
#include <chrono>
#include <cstdint>
#include <memory>   // std::unique_ptr
#include "CGlass.h"   // éœ€è¦ SERVO::CGlass
// å¯åœ¨ç¼–译命令或本头文件前自定义表名:#define GLASS_LOG_TABLE "your_table_name"
#ifndef GLASS_LOG_TABLE
#define GLASS_LOG_TABLE "glass_log"
#endif
// å‰ç½®å£°æ˜Žï¼Œé¿å…å¤´æ–‡ä»¶ä¾èµ– sqlite3.h
struct sqlite3;
struct sqlite3_stmt;
class GlassLogDb {
public:
    // ====== å•例接口 ======
    // åˆå§‹åŒ–(或切换)数据库文件路径;第一次调用会创建实例
    static void Init(const std::string& dbPath);
    // èŽ·å–å…¨å±€å®žä¾‹ï¼›è‹¥æœªåˆå§‹åŒ–ä¼šæŠ›å¼‚å¸¸
    static GlassLogDb& Instance();
    // æ˜¯å¦å·²åˆå§‹åŒ–
    static bool IsInitialized() noexcept;
    // è¿è¡Œä¸­åˆ‡æ¢åˆ°å¦ä¸€ä»½æ•°æ®åº“文件(等同 Init,不存在则创建)
    static void Reopen(const std::string& dbPath);
    // å½“前数据库文件路径(未初始化返回空串)
    static std::string CurrentPath();
    // ====== äº‹åŠ¡æŽ§åˆ¶ ======
    void beginTransaction();
    void commit();
    void rollback();
    // ====== å†™å…¥ ======
    // ç›´æŽ¥ä»Ž SERVO::CGlass å†™å…¥ï¼ˆæ³¨æ„ï¼šå‚数为 éž const å¼•用,因为你的若干 getter éž const)
    long long insertFromCGlass(SERVO::CGlass& g);
    // æ˜¾å¼å‚数插入(tStart/tEnd å¯ç©ºï¼›å‡å†™å…¥ UTC ISO8601 æ–‡æœ¬æˆ– NULL)
    long long insertExplicit(
        int cassetteSeqNo,
        int jobSeqNo,
        const std::string& classId,
        int materialType,
        int state,
        std::optional<std::chrono::system_clock::time_point> tStart,
        std::optional<std::chrono::system_clock::time_point> tEnd,
        const std::string& buddyId,
        int aoiResult,
        const std::string& pathDesc,
        const std::string& paramsDesc,
        const std::string& prettyString);
    // ====== æŸ¥è¯¢è¿”回结构 ======
    struct Row {
        long long id = 0;
        int cassetteSeqNo = 0;
        int jobSeqNo = 0;
        std::string classId;
        int materialType = 0;
        int state = 0;
        std::string tStart;   // ISO8601(库中为 NULL åˆ™ä¸ºç©ºä¸²ï¼‰
        std::string tEnd;     // ISO8601(库中为 NULL åˆ™ä¸ºç©ºä¸²ï¼‰
        std::string buddyId;
        int aoiResult = 0;
        std::string path;
        std::string params;
        std::string pretty;
    };
    // ====== è¿‡æ»¤æ¡ä»¶ ======
    struct Filters {
        std::optional<std::string> classId;       // ç²¾ç¡®åŒ¹é… class_id
        std::optional<int> cassetteSeqNo;
        std::optional<int> jobSeqNo;
        // å…³é”®å­—模糊:对 class_id / buddy_id / path / params / pretty åš OR LIKE
        std::optional<std::string> keyword;
        // æ—¶é—´èŒƒå›´ï¼šå¯¹ t_start è¿‡æ»¤ï¼Œå«è¾¹ç•Œï¼ˆISO8601 æ–‡æœ¬æ¯”较)
        std::optional<std::chrono::system_clock::time_point> tStartFrom;
        std::optional<std::chrono::system_clock::time_point> tStartTo;
    };
    // ====== æŸ¥è¯¢ / ç»Ÿè®¡ / åˆ†é¡µ ======
    // åˆ†é¡µæŸ¥è¯¢ï¼ˆlimit/offset),按 id DESC
    std::vector<Row> query(
        const Filters& filters = {},
        int limit = 50,
        int offset = 0);
    // ç»Ÿè®¡ä¸Ž filters ç›¸åŒæ¡ä»¶çš„æ€»æ•°
    long long count(const Filters& filters = {});
    struct Page {
        std::vector<Row> items;  // å½“前页数据
        long long total = 0;     // ç¬¦åˆæ¡ä»¶çš„æ€»è®°å½•æ•°
        int limit = 0;           // æœ¬æ¬¡æŸ¥è¯¢çš„页容量
        int offset = 0;          // æœ¬æ¬¡æŸ¥è¯¢çš„起始偏移
    };
    // ä¸€æ¬¡å–回列表 + æ€»æ•°
    Page queryPaged(
        const Filters& filters = {},
        int limit = 50,
        int offset = 0);
    // ====== å¯¼å‡º ======
    // å¯¼å‡ºæ»¡è¶³ filters çš„“全部记录”(不受分页限制)为 CSV(UTF-8)
    // è¿”回写出的数据行数(不含表头)
    long long exportCsv(const std::string& csvPath, const Filters& filters = {});
    // ====== æžæž„ / æ‹·è´æŽ§åˆ¶ ======
    ~GlassLogDb();
    GlassLogDb(const GlassLogDb&) = delete;
    GlassLogDb& operator=(const GlassLogDb&) = delete;
private:
    // ä»…允许通过单例接口构造
    explicit GlassLogDb(const std::string& dbPath);
    // å†…部打开/关闭/重开
    void openDb(const std::string& dbPath);
    void closeDb() noexcept;
    void reopenInternal(const std::string& dbPath);
    // å»ºè¡¨ / é¢„编译 / é‡Šæ”¾
    void ensureSchema();
    void prepareStatements();
    void finalizeStatements() noexcept;
    // å·¥å…·ï¼štime_point -> "YYYY-MM-DDTHH:MM:SSZ"(UTC)
    static std::string toIso8601Utc(std::chrono::system_clock::time_point tp);
    // å®žé™…插入执行(支持可空时间)
    long long doInsert(
        int cassetteSeqNo,
        int jobSeqNo,
        const std::string& classId,
        int materialType,
        int state,
        std::optional<std::chrono::system_clock::time_point> tStart,
        std::optional<std::chrono::system_clock::time_point> tEnd,
        const std::string& buddyId,
        int aoiResult,
        const std::string& pathDesc,
        const std::string& paramsDesc,
        const std::string& prettyString);
private:
    // SQLite å¥æŸ„
    sqlite3* db_ = nullptr;
    sqlite3_stmt* stmtInsert_ = nullptr;
    // å®žä¾‹å†…并发保护(同一连接上的写/读串行化)
    std::mutex mtx_;
    // å½“前数据库文件路径
    std::string dbPath_;
    // å•例静态对象与其互斥
    static std::unique_ptr<GlassLogDb> s_inst;
    static std::mutex s_instMtx;
};
SourceCode/Bond/Servo/Model.cpp
@@ -8,6 +8,7 @@
#include "CGlassPool.h"
#include "TransferManager.h"
#include "RecipeManager.h"
#include "GlassLogDb.h"
CModel::CModel()
@@ -461,6 +462,11 @@
    alarmManager.readAlarmFile(szBuffer);
    // Glass数据库
    strLogDir.Format(_T("%s\\db\\process.db"), (LPTSTR)(LPCTSTR)m_strWorkDir);
    std::string path((LPTSTR)(LPCTSTR)strLogDir);
    GlassLogDb::Init(path);
    return 0;
}
SourceCode/Bond/Servo/Servo.rc
Binary files differ
SourceCode/Bond/Servo/Servo.vcxproj
@@ -236,6 +236,7 @@
    <ClInclude Include="CVariable.h" />
    <ClInclude Include="DeviceRecipeParamDlg.h" />
    <ClInclude Include="GlassJson.h" />
    <ClInclude Include="GlassLogDb.h" />
    <ClInclude Include="GridControl\CellRange.h" />
    <ClInclude Include="GridControl\GridCell.h" />
    <ClInclude Include="GridControl\GridCellBase.h" />
@@ -356,6 +357,8 @@
    <ClInclude Include="ServoDlg.h" />
    <ClInclude Include="ServoGraph.h" />
    <ClInclude Include="ServoMemDC.h" />
    <ClInclude Include="sqlite3.h" />
    <ClInclude Include="sqlite3ext.h" />
    <ClInclude Include="stdafx.h" />
    <ClInclude Include="SystemLogManager.h" />
    <ClInclude Include="SystemLogManagerDlg.h" />
@@ -408,6 +411,7 @@
    <ClCompile Include="CVariable.cpp" />
    <ClCompile Include="DeviceRecipeParamDlg.cpp" />
    <ClCompile Include="GlassJson.cpp" />
    <ClCompile Include="GlassLogDb.cpp" />
    <ClCompile Include="GridControl\GridCell.cpp" />
    <ClCompile Include="GridControl\GridCellBase.cpp" />
    <ClCompile Include="GridControl\GridCellButton.cpp" />
@@ -522,6 +526,10 @@
    <ClCompile Include="ServoDlg.cpp" />
    <ClCompile Include="ServoGraph.cpp" />
    <ClCompile Include="ServoMemDC.cpp" />
    <ClCompile Include="sqlite3.c">
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
    </ClCompile>
    <ClCompile Include="stdafx.cpp">
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -195,6 +195,8 @@
    <ClCompile Include="DeviceRecipeParamDlg.cpp" />
    <ClCompile Include="CSVData.cpp" />
    <ClCompile Include="CServoUtilsTool.cpp" />
    <ClCompile Include="GlassLogDb.cpp" />
    <ClCompile Include="sqlite3.c" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="AlarmManager.h" />
@@ -414,6 +416,9 @@
    <ClInclude Include="DeviceRecipeParamDlg.h" />
    <ClInclude Include="CSVData.h" />
    <ClInclude Include="CServoUtilsTool.h" />
    <ClInclude Include="GlassLogDb.h" />
    <ClInclude Include="sqlite3.h" />
    <ClInclude Include="sqlite3ext.h" />
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="Servo.rc" />
SourceCode/Bond/Servo/ToolUnits.cpp
@@ -336,4 +336,158 @@
    if (nLength > 0) {
        strOut = std::string(pszBuffer, nLength);
    }
}
}
// FILETIME(UTC) -> time_point
std::chrono::system_clock::time_point CToolUnits::FileTimeToTimePointUTC(const FILETIME& ftUtc) {
    ULARGE_INTEGER ull;
    ull.LowPart = ftUtc.dwLowDateTime;
    ull.HighPart = ftUtc.dwHighDateTime;
    // 1601-01-01 åˆ° 1970-01-01 çš„ 100ns tick
    constexpr unsigned long long EPOCH_DIFF_100NS = 116444736000000000ULL;
    unsigned long long t100 = ull.QuadPart - EPOCH_DIFF_100NS; // 1970以来 100ns
    // é¿å…æº¢å‡ºï¼š100ns -> us
    unsigned long long us = t100 / 10ULL;
    return std::chrono::system_clock::time_point(std::chrono::microseconds(us));
}
// ä»Ž CDateTimeCtrl å–本地时间并转为 UTC time_point
// è¿”回 false è¡¨ç¤ºæŽ§ä»¶æ˜¯â€œæ— å€¼â€(DTS_SHOWNONE / GDT_NONE) æˆ–转换失败
bool CToolUnits::GetCtrlTimeUtc(const CDateTimeCtrl& ctrl,
    std::chrono::system_clock::time_point& outUtc)
{
    SYSTEMTIME stLocal{};
    DWORD rc = const_cast<CDateTimeCtrl&>(ctrl).GetTime(&stLocal); // MFC åŽŸåž‹éœ€è¦éžconst
    if (rc != GDT_VALID) return false; // GDT_NONE
    SYSTEMTIME stUtc{};
    if (!TzSpecificLocalTimeToSystemTime(nullptr, &stLocal, &stUtc)) return false;
    FILETIME ftUtc{};
    if (!SystemTimeToFileTime(&stUtc, &ftUtc)) return false;
    outUtc = FileTimeToTimePointUTC(ftUtc);
    return true;
}
// è‹¥ä½ çš„æ—¥æœŸæŽ§ä»¶åªæ˜¾ç¤ºâ€œæ—¥æœŸä¸æ˜¾ç¤ºæ—¶é—´â€ï¼Œæƒ³æŠŠ From è°ƒæ•´åˆ° 00:00:00 / To è°ƒæ•´åˆ° 23:59:59.999:
bool CToolUnits::GetCtrlDateRangeUtc_StartOfDay(const CDateTimeCtrl& ctrl,
    std::chrono::system_clock::time_point& outUtc)
{
    SYSTEMTIME st{};
    DWORD rc = const_cast<CDateTimeCtrl&>(ctrl).GetTime(&st);
    if (rc != GDT_VALID) return false;
    st.wHour = 0; st.wMinute = 0; st.wSecond = 0; st.wMilliseconds = 0;
    SYSTEMTIME stUtc{};
    if (!TzSpecificLocalTimeToSystemTime(nullptr, &st, &stUtc)) return false;
    FILETIME ftUtc{}; if (!SystemTimeToFileTime(&stUtc, &ftUtc)) return false;
    outUtc = FileTimeToTimePointUTC(ftUtc);
    return true;
}
bool CToolUnits::GetCtrlDateRangeUtc_EndOfDay(const CDateTimeCtrl& ctrl,
    std::chrono::system_clock::time_point& outUtc)
{
    SYSTEMTIME st{};
    DWORD rc = const_cast<CDateTimeCtrl&>(ctrl).GetTime(&st);
    if (rc != GDT_VALID) return false;
    st.wHour = 23; st.wMinute = 59; st.wSecond = 59; st.wMilliseconds = 999;
    SYSTEMTIME stUtc{};
    if (!TzSpecificLocalTimeToSystemTime(nullptr, &st, &stUtc)) return false;
    FILETIME ftUtc{}; if (!SystemTimeToFileTime(&stUtc, &ftUtc)) return false;
    outUtc = FileTimeToTimePointUTC(ftUtc);
    return true;
}
// ---------- æœ¬åœ° SYSTEMTIME -> UTC time_point ----------
std::chrono::system_clock::time_point CToolUnits::LocalSTtoUtcTP(const SYSTEMTIME& stLocal) {
    SYSTEMTIME stUtc{};
    if (!TzSpecificLocalTimeToSystemTime(nullptr, &stLocal, &stUtc))
        throw std::runtime_error("TzSpecificLocalTimeToSystemTime failed");
    FILETIME ftUtc{};
    if (!SystemTimeToFileTime(&stUtc, &ftUtc))
        throw std::runtime_error("SystemTimeToFileTime failed");
    return FileTimeToTimePointUTC(ftUtc);
}
// ç”Ÿæˆæœ¬åœ° SYSTEMTIME
SYSTEMTIME CToolUnits::MakeLocalST(int y, int m, int d, int hh, int mi, int ss, int ms) {
    SYSTEMTIME st{};
    st.wYear = (WORD)y; st.wMonth = (WORD)m; st.wDay = (WORD)d;
    st.wHour = (WORD)hh; st.wMinute = (WORD)mi; st.wSecond = (WORD)ss; st.wMilliseconds = (WORD)ms;
    return st;
}
// é—°å¹´ / æœˆå¤©æ•°
bool CToolUnits::IsLeap(int y) {
    return ((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0);
}
int CToolUnits::DaysInMonth(int y, int m) {
    static const int d[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
    return (m == 2) ? d[m] + (IsLeap(y) ? 1 : 0) : d[m];
}
// æœ¬åœ°â€œä»Šå¤©â€çš„年月日
void CToolUnits::GetTodayYMD_Local(int& y, int& m, int& d) {
    SYSTEMTIME now{}; GetLocalTime(&now);
    y = now.wYear; m = now.wMonth; d = now.wDay;
}
// æœ¬åœ°æ—¥åŽ†ä¸Šå‡ n å¤©ï¼ˆä»æ˜¯æœ¬åœ° Y/M/D)
void CToolUnits::LocalCalendarMinusDays(int& y, int& m, int& d, int nDays) {
    std::tm t{};
    t.tm_year = y - 1900; t.tm_mon = m - 1; t.tm_mday = d;
    t.tm_hour = 0; t.tm_min = 0; t.tm_sec = 0;
    t.tm_mday -= nDays;
    (void)std::mktime(&t); // æŒ‰æœ¬åœ°æ—¶åŒºå½’一化
    y = t.tm_year + 1900; m = t.tm_mon + 1; d = t.tm_mday;
}
// ====== æ ¸å¿ƒï¼šè®¡ç®—预设区间的 UTC [from, to] ======
// è¯­ä¹‰ï¼š
//  - Today     : æœ¬åœ°â€œä»Šå¤©â€00:00:00.000 ï½ž ä»Šå¤© 23:59:59.999
//  - Last7Days : æœ¬åœ°â€œ6 å¤©å‰â€00:00:00.000 ï½ž ä»Šå¤© 23:59:59.999(共 7 ä¸ªè‡ªç„¶æ—¥ï¼Œå«ä»Šå¤©ï¼‰
//  - ThisMonth : æœ¬åœ°â€œå½“月 1 å·â€00:00:00.000 ï½ž æœ¬æœˆæœ« 23:59:59.999
//  - ThisYear  : æœ¬åœ°â€œå½“å¹´ 1/1”00:00:00.000 ï½ž å½“年末 23:59:59.999
std::pair<std::chrono::system_clock::time_point,
    std::chrono::system_clock::time_point>
    CToolUnits::CalcQuickRangeUtc(QuickRange r)
{
    int y, m, d;
    GetTodayYMD_Local(y, m, d);
    SYSTEMTIME stFromLocal{}, stToLocal{};
    switch (r) {
    case QuickRange::Today:
        stFromLocal = MakeLocalST(y, m, d, 0, 0, 0, 0);
        stToLocal = MakeLocalST(y, m, d, 23, 59, 59, 999);
        break;
    case QuickRange::Last7Days: {
        int y2 = y, m2 = m, d2 = d;
        LocalCalendarMinusDays(y2, m2, d2, 6);
        stFromLocal = MakeLocalST(y2, m2, d2, 0, 0, 0, 0);
        stToLocal = MakeLocalST(y, m, d, 23, 59, 59, 999);
        break;
    }
    case QuickRange::ThisMonth: {
        int lastDay = DaysInMonth(y, m);
        stFromLocal = MakeLocalST(y, m, 1, 0, 0, 0, 0);
        stToLocal = MakeLocalST(y, m, lastDay, 23, 59, 59, 999);
        break;
    }
    case QuickRange::ThisYear:
        stFromLocal = MakeLocalST(y, 1, 1, 0, 0, 0, 0);
        stToLocal = MakeLocalST(y, 12, DaysInMonth(y, 12), 23, 59, 59, 999);
        break;
    default:
        throw std::invalid_argument("CalcQuickRangeUtc: unsupported range");
    }
    auto fromUtc = LocalSTtoUtcTP(stFromLocal);
    auto toUtc = LocalSTtoUtcTP(stToLocal);
    return { fromUtc, toUtc };
}
SourceCode/Bond/Servo/ToolUnits.h
@@ -1,5 +1,10 @@
#pragma once
#include <string>
#include <chrono>
#include <optional>
#include <utility>
enum class QuickRange { Today, Last7Days, ThisMonth, ThisYear };
class CToolUnits
{
@@ -32,5 +37,22 @@
    static bool startsWith(const std::string& str, const std::string& prefix);
    static std::string& toHexString(int value, std::string& strOut);
    static void convertString(const char* pszBuffer, int size, std::string& strOut);
    static inline std::chrono::system_clock::time_point FileTimeToTimePointUTC(const FILETIME& ftUtc);
    static bool GetCtrlTimeUtc(const CDateTimeCtrl& ctrl,
        std::chrono::system_clock::time_point& outUtc);
    static bool GetCtrlDateRangeUtc_StartOfDay(const CDateTimeCtrl& ctrl,
        std::chrono::system_clock::time_point& outUtc);
    static bool GetCtrlDateRangeUtc_EndOfDay(const CDateTimeCtrl& ctrl,
        std::chrono::system_clock::time_point& outUtc);
    static std::chrono::system_clock::time_point CToolUnits::LocalSTtoUtcTP(const SYSTEMTIME& stLocal);
    static SYSTEMTIME CToolUnits::MakeLocalST(int y, int m, int d, int hh, int mi, int ss, int ms);
    static bool IsLeap(int y);
    static int DaysInMonth(int y, int m);
    static void GetTodayYMD_Local(int& y, int& m, int& d);
    static void CToolUnits::LocalCalendarMinusDays(int& y, int& m, int& d, int nDays);
    static std::pair<std::chrono::system_clock::time_point,
        std::chrono::system_clock::time_point>
        CToolUnits::CalcQuickRangeUtc(QuickRange r);
};
SourceCode/Bond/Servo/sqlite3.c
¶Ô±ÈÐÂÎļþ
ÎļþÌ«´ó
SourceCode/Bond/Servo/sqlite3.h
¶Ô±ÈÐÂÎļþ
ÎļþÌ«´ó
SourceCode/Bond/Servo/sqlite3ext.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,719 @@
/*
** 2006 June 7
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the SQLite interface for use by
** shared libraries that want to be imported as extensions into
** an SQLite instance.  Shared libraries that intend to be loaded
** as extensions by SQLite should #include this file instead of
** sqlite3.h.
*/
#ifndef SQLITE3EXT_H
#define SQLITE3EXT_H
#include "sqlite3.h"
/*
** The following structure holds pointers to all of the SQLite API
** routines.
**
** WARNING:  In order to maintain backwards compatibility, add new
** interfaces to the end of this structure only.  If you insert new
** interfaces in the middle of this structure, then older different
** versions of SQLite will not be able to load each other's shared
** libraries!
*/
struct sqlite3_api_routines {
  void * (*aggregate_context)(sqlite3_context*,int nBytes);
  int  (*aggregate_count)(sqlite3_context*);
  int  (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
  int  (*bind_double)(sqlite3_stmt*,int,double);
  int  (*bind_int)(sqlite3_stmt*,int,int);
  int  (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
  int  (*bind_null)(sqlite3_stmt*,int);
  int  (*bind_parameter_count)(sqlite3_stmt*);
  int  (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
  const char * (*bind_parameter_name)(sqlite3_stmt*,int);
  int  (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
  int  (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
  int  (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
  int  (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
  int  (*busy_timeout)(sqlite3*,int ms);
  int  (*changes)(sqlite3*);
  int  (*close)(sqlite3*);
  int  (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
                           int eTextRep,const char*));
  int  (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
                             int eTextRep,const void*));
  const void * (*column_blob)(sqlite3_stmt*,int iCol);
  int  (*column_bytes)(sqlite3_stmt*,int iCol);
  int  (*column_bytes16)(sqlite3_stmt*,int iCol);
  int  (*column_count)(sqlite3_stmt*pStmt);
  const char * (*column_database_name)(sqlite3_stmt*,int);
  const void * (*column_database_name16)(sqlite3_stmt*,int);
  const char * (*column_decltype)(sqlite3_stmt*,int i);
  const void * (*column_decltype16)(sqlite3_stmt*,int);
  double  (*column_double)(sqlite3_stmt*,int iCol);
  int  (*column_int)(sqlite3_stmt*,int iCol);
  sqlite_int64  (*column_int64)(sqlite3_stmt*,int iCol);
  const char * (*column_name)(sqlite3_stmt*,int);
  const void * (*column_name16)(sqlite3_stmt*,int);
  const char * (*column_origin_name)(sqlite3_stmt*,int);
  const void * (*column_origin_name16)(sqlite3_stmt*,int);
  const char * (*column_table_name)(sqlite3_stmt*,int);
  const void * (*column_table_name16)(sqlite3_stmt*,int);
  const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
  const void * (*column_text16)(sqlite3_stmt*,int iCol);
  int  (*column_type)(sqlite3_stmt*,int iCol);
  sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
  void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
  int  (*complete)(const char*sql);
  int  (*complete16)(const void*sql);
  int  (*create_collation)(sqlite3*,const char*,int,void*,
                           int(*)(void*,int,const void*,int,const void*));
  int  (*create_collation16)(sqlite3*,const void*,int,void*,
                             int(*)(void*,int,const void*,int,const void*));
  int  (*create_function)(sqlite3*,const char*,int,int,void*,
                          void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
                          void (*xStep)(sqlite3_context*,int,sqlite3_value**),
                          void (*xFinal)(sqlite3_context*));
  int  (*create_function16)(sqlite3*,const void*,int,int,void*,
                            void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
                            void (*xStep)(sqlite3_context*,int,sqlite3_value**),
                            void (*xFinal)(sqlite3_context*));
  int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
  int  (*data_count)(sqlite3_stmt*pStmt);
  sqlite3 * (*db_handle)(sqlite3_stmt*);
  int (*declare_vtab)(sqlite3*,const char*);
  int  (*enable_shared_cache)(int);
  int  (*errcode)(sqlite3*db);
  const char * (*errmsg)(sqlite3*);
  const void * (*errmsg16)(sqlite3*);
  int  (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
  int  (*expired)(sqlite3_stmt*);
  int  (*finalize)(sqlite3_stmt*pStmt);
  void  (*free)(void*);
  void  (*free_table)(char**result);
  int  (*get_autocommit)(sqlite3*);
  void * (*get_auxdata)(sqlite3_context*,int);
  int  (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
  int  (*global_recover)(void);
  void  (*interruptx)(sqlite3*);
  sqlite_int64  (*last_insert_rowid)(sqlite3*);
  const char * (*libversion)(void);
  int  (*libversion_number)(void);
  void *(*malloc)(int);
  char * (*mprintf)(const char*,...);
  int  (*open)(const char*,sqlite3**);
  int  (*open16)(const void*,sqlite3**);
  int  (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
  int  (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
  void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
  void  (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
  void *(*realloc)(void*,int);
  int  (*reset)(sqlite3_stmt*pStmt);
  void  (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
  void  (*result_double)(sqlite3_context*,double);
  void  (*result_error)(sqlite3_context*,const char*,int);
  void  (*result_error16)(sqlite3_context*,const void*,int);
  void  (*result_int)(sqlite3_context*,int);
  void  (*result_int64)(sqlite3_context*,sqlite_int64);
  void  (*result_null)(sqlite3_context*);
  void  (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
  void  (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
  void  (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
  void  (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
  void  (*result_value)(sqlite3_context*,sqlite3_value*);
  void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
  int  (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
                         const char*,const char*),void*);
  void  (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
  char * (*xsnprintf)(int,char*,const char*,...);
  int  (*step)(sqlite3_stmt*);
  int  (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
                                char const**,char const**,int*,int*,int*);
  void  (*thread_cleanup)(void);
  int  (*total_changes)(sqlite3*);
  void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
  int  (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
  void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
                                         sqlite_int64),void*);
  void * (*user_data)(sqlite3_context*);
  const void * (*value_blob)(sqlite3_value*);
  int  (*value_bytes)(sqlite3_value*);
  int  (*value_bytes16)(sqlite3_value*);
  double  (*value_double)(sqlite3_value*);
  int  (*value_int)(sqlite3_value*);
  sqlite_int64  (*value_int64)(sqlite3_value*);
  int  (*value_numeric_type)(sqlite3_value*);
  const unsigned char * (*value_text)(sqlite3_value*);
  const void * (*value_text16)(sqlite3_value*);
  const void * (*value_text16be)(sqlite3_value*);
  const void * (*value_text16le)(sqlite3_value*);
  int  (*value_type)(sqlite3_value*);
  char *(*vmprintf)(const char*,va_list);
  /* Added ??? */
  int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
  /* Added by 3.3.13 */
  int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
  int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
  int (*clear_bindings)(sqlite3_stmt*);
  /* Added by 3.4.1 */
  int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
                          void (*xDestroy)(void *));
  /* Added by 3.5.0 */
  int (*bind_zeroblob)(sqlite3_stmt*,int,int);
  int (*blob_bytes)(sqlite3_blob*);
  int (*blob_close)(sqlite3_blob*);
  int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
                   int,sqlite3_blob**);
  int (*blob_read)(sqlite3_blob*,void*,int,int);
  int (*blob_write)(sqlite3_blob*,const void*,int,int);
  int (*create_collation_v2)(sqlite3*,const char*,int,void*,
                             int(*)(void*,int,const void*,int,const void*),
                             void(*)(void*));
  int (*file_control)(sqlite3*,const char*,int,void*);
  sqlite3_int64 (*memory_highwater)(int);
  sqlite3_int64 (*memory_used)(void);
  sqlite3_mutex *(*mutex_alloc)(int);
  void (*mutex_enter)(sqlite3_mutex*);
  void (*mutex_free)(sqlite3_mutex*);
  void (*mutex_leave)(sqlite3_mutex*);
  int (*mutex_try)(sqlite3_mutex*);
  int (*open_v2)(const char*,sqlite3**,int,const char*);
  int (*release_memory)(int);
  void (*result_error_nomem)(sqlite3_context*);
  void (*result_error_toobig)(sqlite3_context*);
  int (*sleep)(int);
  void (*soft_heap_limit)(int);
  sqlite3_vfs *(*vfs_find)(const char*);
  int (*vfs_register)(sqlite3_vfs*,int);
  int (*vfs_unregister)(sqlite3_vfs*);
  int (*xthreadsafe)(void);
  void (*result_zeroblob)(sqlite3_context*,int);
  void (*result_error_code)(sqlite3_context*,int);
  int (*test_control)(int, ...);
  void (*randomness)(int,void*);
  sqlite3 *(*context_db_handle)(sqlite3_context*);
  int (*extended_result_codes)(sqlite3*,int);
  int (*limit)(sqlite3*,int,int);
  sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
  const char *(*sql)(sqlite3_stmt*);
  int (*status)(int,int*,int*,int);
  int (*backup_finish)(sqlite3_backup*);
  sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
  int (*backup_pagecount)(sqlite3_backup*);
  int (*backup_remaining)(sqlite3_backup*);
  int (*backup_step)(sqlite3_backup*,int);
  const char *(*compileoption_get)(int);
  int (*compileoption_used)(const char*);
  int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
                            void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
                            void (*xStep)(sqlite3_context*,int,sqlite3_value**),
                            void (*xFinal)(sqlite3_context*),
                            void(*xDestroy)(void*));
  int (*db_config)(sqlite3*,int,...);
  sqlite3_mutex *(*db_mutex)(sqlite3*);
  int (*db_status)(sqlite3*,int,int*,int*,int);
  int (*extended_errcode)(sqlite3*);
  void (*log)(int,const char*,...);
  sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
  const char *(*sourceid)(void);
  int (*stmt_status)(sqlite3_stmt*,int,int);
  int (*strnicmp)(const char*,const char*,int);
  int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
  int (*wal_autocheckpoint)(sqlite3*,int);
  int (*wal_checkpoint)(sqlite3*,const char*);
  void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
  int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
  int (*vtab_config)(sqlite3*,int op,...);
  int (*vtab_on_conflict)(sqlite3*);
  /* Version 3.7.16 and later */
  int (*close_v2)(sqlite3*);
  const char *(*db_filename)(sqlite3*,const char*);
  int (*db_readonly)(sqlite3*,const char*);
  int (*db_release_memory)(sqlite3*);
  const char *(*errstr)(int);
  int (*stmt_busy)(sqlite3_stmt*);
  int (*stmt_readonly)(sqlite3_stmt*);
  int (*stricmp)(const char*,const char*);
  int (*uri_boolean)(const char*,const char*,int);
  sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
  const char *(*uri_parameter)(const char*,const char*);
  char *(*xvsnprintf)(int,char*,const char*,va_list);
  int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
  /* Version 3.8.7 and later */
  int (*auto_extension)(void(*)(void));
  int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
                     void(*)(void*));
  int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
                      void(*)(void*),unsigned char);
  int (*cancel_auto_extension)(void(*)(void));
  int (*load_extension)(sqlite3*,const char*,const char*,char**);
  void *(*malloc64)(sqlite3_uint64);
  sqlite3_uint64 (*msize)(void*);
  void *(*realloc64)(void*,sqlite3_uint64);
  void (*reset_auto_extension)(void);
  void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
                        void(*)(void*));
  void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
                         void(*)(void*), unsigned char);
  int (*strglob)(const char*,const char*);
  /* Version 3.8.11 and later */
  sqlite3_value *(*value_dup)(const sqlite3_value*);
  void (*value_free)(sqlite3_value*);
  int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
  int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
  /* Version 3.9.0 and later */
  unsigned int (*value_subtype)(sqlite3_value*);
  void (*result_subtype)(sqlite3_context*,unsigned int);
  /* Version 3.10.0 and later */
  int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
  int (*strlike)(const char*,const char*,unsigned int);
  int (*db_cacheflush)(sqlite3*);
  /* Version 3.12.0 and later */
  int (*system_errno)(sqlite3*);
  /* Version 3.14.0 and later */
  int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
  char *(*expanded_sql)(sqlite3_stmt*);
  /* Version 3.18.0 and later */
  void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
  /* Version 3.20.0 and later */
  int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
                    sqlite3_stmt**,const char**);
  int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
                      sqlite3_stmt**,const void**);
  int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
  void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
  void *(*value_pointer)(sqlite3_value*,const char*);
  int (*vtab_nochange)(sqlite3_context*);
  int (*value_nochange)(sqlite3_value*);
  const char *(*vtab_collation)(sqlite3_index_info*,int);
  /* Version 3.24.0 and later */
  int (*keyword_count)(void);
  int (*keyword_name)(int,const char**,int*);
  int (*keyword_check)(const char*,int);
  sqlite3_str *(*str_new)(sqlite3*);
  char *(*str_finish)(sqlite3_str*);
  void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
  void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
  void (*str_append)(sqlite3_str*, const char *zIn, int N);
  void (*str_appendall)(sqlite3_str*, const char *zIn);
  void (*str_appendchar)(sqlite3_str*, int N, char C);
  void (*str_reset)(sqlite3_str*);
  int (*str_errcode)(sqlite3_str*);
  int (*str_length)(sqlite3_str*);
  char *(*str_value)(sqlite3_str*);
  /* Version 3.25.0 and later */
  int (*create_window_function)(sqlite3*,const char*,int,int,void*,
                            void (*xStep)(sqlite3_context*,int,sqlite3_value**),
                            void (*xFinal)(sqlite3_context*),
                            void (*xValue)(sqlite3_context*),
                            void (*xInv)(sqlite3_context*,int,sqlite3_value**),
                            void(*xDestroy)(void*));
  /* Version 3.26.0 and later */
  const char *(*normalized_sql)(sqlite3_stmt*);
  /* Version 3.28.0 and later */
  int (*stmt_isexplain)(sqlite3_stmt*);
  int (*value_frombind)(sqlite3_value*);
  /* Version 3.30.0 and later */
  int (*drop_modules)(sqlite3*,const char**);
  /* Version 3.31.0 and later */
  sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
  const char *(*uri_key)(const char*,int);
  const char *(*filename_database)(const char*);
  const char *(*filename_journal)(const char*);
  const char *(*filename_wal)(const char*);
  /* Version 3.32.0 and later */
  const char *(*create_filename)(const char*,const char*,const char*,
                           int,const char**);
  void (*free_filename)(const char*);
  sqlite3_file *(*database_file_object)(const char*);
  /* Version 3.34.0 and later */
  int (*txn_state)(sqlite3*,const char*);
  /* Version 3.36.1 and later */
  sqlite3_int64 (*changes64)(sqlite3*);
  sqlite3_int64 (*total_changes64)(sqlite3*);
  /* Version 3.37.0 and later */
  int (*autovacuum_pages)(sqlite3*,
     unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
     void*, void(*)(void*));
  /* Version 3.38.0 and later */
  int (*error_offset)(sqlite3*);
  int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
  int (*vtab_distinct)(sqlite3_index_info*);
  int (*vtab_in)(sqlite3_index_info*,int,int);
  int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
  int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
  /* Version 3.39.0 and later */
  int (*deserialize)(sqlite3*,const char*,unsigned char*,
                     sqlite3_int64,sqlite3_int64,unsigned);
  unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
                              unsigned int);
  const char *(*db_name)(sqlite3*,int);
  /* Version 3.40.0 and later */
  int (*value_encoding)(sqlite3_value*);
  /* Version 3.41.0 and later */
  int (*is_interrupted)(sqlite3*);
  /* Version 3.43.0 and later */
  int (*stmt_explain)(sqlite3_stmt*,int);
  /* Version 3.44.0 and later */
  void *(*get_clientdata)(sqlite3*,const char*);
  int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
};
/*
** This is the function signature used for all extension entry points.  It
** is also defined in the file "loadext.c".
*/
typedef int (*sqlite3_loadext_entry)(
  sqlite3 *db,                       /* Handle to the database. */
  char **pzErrMsg,                   /* Used to set error string on failure. */
  const sqlite3_api_routines *pThunk /* Extension API function pointers. */
);
/*
** The following macros redefine the API routines so that they are
** redirected through the global sqlite3_api structure.
**
** This header file is also used by the loadext.c source file
** (part of the main SQLite library - not an extension) so that
** it can get access to the sqlite3_api_routines structure
** definition.  But the main library does not want to redefine
** the API.  So the redefinition macros are only valid if the
** SQLITE_CORE macros is undefined.
*/
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
#define sqlite3_aggregate_context      sqlite3_api->aggregate_context
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_aggregate_count        sqlite3_api->aggregate_count
#endif
#define sqlite3_bind_blob              sqlite3_api->bind_blob
#define sqlite3_bind_double            sqlite3_api->bind_double
#define sqlite3_bind_int               sqlite3_api->bind_int
#define sqlite3_bind_int64             sqlite3_api->bind_int64
#define sqlite3_bind_null              sqlite3_api->bind_null
#define sqlite3_bind_parameter_count   sqlite3_api->bind_parameter_count
#define sqlite3_bind_parameter_index   sqlite3_api->bind_parameter_index
#define sqlite3_bind_parameter_name    sqlite3_api->bind_parameter_name
#define sqlite3_bind_text              sqlite3_api->bind_text
#define sqlite3_bind_text16            sqlite3_api->bind_text16
#define sqlite3_bind_value             sqlite3_api->bind_value
#define sqlite3_busy_handler           sqlite3_api->busy_handler
#define sqlite3_busy_timeout           sqlite3_api->busy_timeout
#define sqlite3_changes                sqlite3_api->changes
#define sqlite3_close                  sqlite3_api->close
#define sqlite3_collation_needed       sqlite3_api->collation_needed
#define sqlite3_collation_needed16     sqlite3_api->collation_needed16
#define sqlite3_column_blob            sqlite3_api->column_blob
#define sqlite3_column_bytes           sqlite3_api->column_bytes
#define sqlite3_column_bytes16         sqlite3_api->column_bytes16
#define sqlite3_column_count           sqlite3_api->column_count
#define sqlite3_column_database_name   sqlite3_api->column_database_name
#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
#define sqlite3_column_decltype        sqlite3_api->column_decltype
#define sqlite3_column_decltype16      sqlite3_api->column_decltype16
#define sqlite3_column_double          sqlite3_api->column_double
#define sqlite3_column_int             sqlite3_api->column_int
#define sqlite3_column_int64           sqlite3_api->column_int64
#define sqlite3_column_name            sqlite3_api->column_name
#define sqlite3_column_name16          sqlite3_api->column_name16
#define sqlite3_column_origin_name     sqlite3_api->column_origin_name
#define sqlite3_column_origin_name16   sqlite3_api->column_origin_name16
#define sqlite3_column_table_name      sqlite3_api->column_table_name
#define sqlite3_column_table_name16    sqlite3_api->column_table_name16
#define sqlite3_column_text            sqlite3_api->column_text
#define sqlite3_column_text16          sqlite3_api->column_text16
#define sqlite3_column_type            sqlite3_api->column_type
#define sqlite3_column_value           sqlite3_api->column_value
#define sqlite3_commit_hook            sqlite3_api->commit_hook
#define sqlite3_complete               sqlite3_api->complete
#define sqlite3_complete16             sqlite3_api->complete16
#define sqlite3_create_collation       sqlite3_api->create_collation
#define sqlite3_create_collation16     sqlite3_api->create_collation16
#define sqlite3_create_function        sqlite3_api->create_function
#define sqlite3_create_function16      sqlite3_api->create_function16
#define sqlite3_create_module          sqlite3_api->create_module
#define sqlite3_create_module_v2       sqlite3_api->create_module_v2
#define sqlite3_data_count             sqlite3_api->data_count
#define sqlite3_db_handle              sqlite3_api->db_handle
#define sqlite3_declare_vtab           sqlite3_api->declare_vtab
#define sqlite3_enable_shared_cache    sqlite3_api->enable_shared_cache
#define sqlite3_errcode                sqlite3_api->errcode
#define sqlite3_errmsg                 sqlite3_api->errmsg
#define sqlite3_errmsg16               sqlite3_api->errmsg16
#define sqlite3_exec                   sqlite3_api->exec
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_expired                sqlite3_api->expired
#endif
#define sqlite3_finalize               sqlite3_api->finalize
#define sqlite3_free                   sqlite3_api->free
#define sqlite3_free_table             sqlite3_api->free_table
#define sqlite3_get_autocommit         sqlite3_api->get_autocommit
#define sqlite3_get_auxdata            sqlite3_api->get_auxdata
#define sqlite3_get_table              sqlite3_api->get_table
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_global_recover         sqlite3_api->global_recover
#endif
#define sqlite3_interrupt              sqlite3_api->interruptx
#define sqlite3_last_insert_rowid      sqlite3_api->last_insert_rowid
#define sqlite3_libversion             sqlite3_api->libversion
#define sqlite3_libversion_number      sqlite3_api->libversion_number
#define sqlite3_malloc                 sqlite3_api->malloc
#define sqlite3_mprintf                sqlite3_api->mprintf
#define sqlite3_open                   sqlite3_api->open
#define sqlite3_open16                 sqlite3_api->open16
#define sqlite3_prepare                sqlite3_api->prepare
#define sqlite3_prepare16              sqlite3_api->prepare16
#define sqlite3_prepare_v2             sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2           sqlite3_api->prepare16_v2
#define sqlite3_profile                sqlite3_api->profile
#define sqlite3_progress_handler       sqlite3_api->progress_handler
#define sqlite3_realloc                sqlite3_api->realloc
#define sqlite3_reset                  sqlite3_api->reset
#define sqlite3_result_blob            sqlite3_api->result_blob
#define sqlite3_result_double          sqlite3_api->result_double
#define sqlite3_result_error           sqlite3_api->result_error
#define sqlite3_result_error16         sqlite3_api->result_error16
#define sqlite3_result_int             sqlite3_api->result_int
#define sqlite3_result_int64           sqlite3_api->result_int64
#define sqlite3_result_null            sqlite3_api->result_null
#define sqlite3_result_text            sqlite3_api->result_text
#define sqlite3_result_text16          sqlite3_api->result_text16
#define sqlite3_result_text16be        sqlite3_api->result_text16be
#define sqlite3_result_text16le        sqlite3_api->result_text16le
#define sqlite3_result_value           sqlite3_api->result_value
#define sqlite3_rollback_hook          sqlite3_api->rollback_hook
#define sqlite3_set_authorizer         sqlite3_api->set_authorizer
#define sqlite3_set_auxdata            sqlite3_api->set_auxdata
#define sqlite3_snprintf               sqlite3_api->xsnprintf
#define sqlite3_step                   sqlite3_api->step
#define sqlite3_table_column_metadata  sqlite3_api->table_column_metadata
#define sqlite3_thread_cleanup         sqlite3_api->thread_cleanup
#define sqlite3_total_changes          sqlite3_api->total_changes
#define sqlite3_trace                  sqlite3_api->trace
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_transfer_bindings      sqlite3_api->transfer_bindings
#endif
#define sqlite3_update_hook            sqlite3_api->update_hook
#define sqlite3_user_data              sqlite3_api->user_data
#define sqlite3_value_blob             sqlite3_api->value_blob
#define sqlite3_value_bytes            sqlite3_api->value_bytes
#define sqlite3_value_bytes16          sqlite3_api->value_bytes16
#define sqlite3_value_double           sqlite3_api->value_double
#define sqlite3_value_int              sqlite3_api->value_int
#define sqlite3_value_int64            sqlite3_api->value_int64
#define sqlite3_value_numeric_type     sqlite3_api->value_numeric_type
#define sqlite3_value_text             sqlite3_api->value_text
#define sqlite3_value_text16           sqlite3_api->value_text16
#define sqlite3_value_text16be         sqlite3_api->value_text16be
#define sqlite3_value_text16le         sqlite3_api->value_text16le
#define sqlite3_value_type             sqlite3_api->value_type
#define sqlite3_vmprintf               sqlite3_api->vmprintf
#define sqlite3_vsnprintf              sqlite3_api->xvsnprintf
#define sqlite3_overload_function      sqlite3_api->overload_function
#define sqlite3_prepare_v2             sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2           sqlite3_api->prepare16_v2
#define sqlite3_clear_bindings         sqlite3_api->clear_bindings
#define sqlite3_bind_zeroblob          sqlite3_api->bind_zeroblob
#define sqlite3_blob_bytes             sqlite3_api->blob_bytes
#define sqlite3_blob_close             sqlite3_api->blob_close
#define sqlite3_blob_open              sqlite3_api->blob_open
#define sqlite3_blob_read              sqlite3_api->blob_read
#define sqlite3_blob_write             sqlite3_api->blob_write
#define sqlite3_create_collation_v2    sqlite3_api->create_collation_v2
#define sqlite3_file_control           sqlite3_api->file_control
#define sqlite3_memory_highwater       sqlite3_api->memory_highwater
#define sqlite3_memory_used            sqlite3_api->memory_used
#define sqlite3_mutex_alloc            sqlite3_api->mutex_alloc
#define sqlite3_mutex_enter            sqlite3_api->mutex_enter
#define sqlite3_mutex_free             sqlite3_api->mutex_free
#define sqlite3_mutex_leave            sqlite3_api->mutex_leave
#define sqlite3_mutex_try              sqlite3_api->mutex_try
#define sqlite3_open_v2                sqlite3_api->open_v2
#define sqlite3_release_memory         sqlite3_api->release_memory
#define sqlite3_result_error_nomem     sqlite3_api->result_error_nomem
#define sqlite3_result_error_toobig    sqlite3_api->result_error_toobig
#define sqlite3_sleep                  sqlite3_api->sleep
#define sqlite3_soft_heap_limit        sqlite3_api->soft_heap_limit
#define sqlite3_vfs_find               sqlite3_api->vfs_find
#define sqlite3_vfs_register           sqlite3_api->vfs_register
#define sqlite3_vfs_unregister         sqlite3_api->vfs_unregister
#define sqlite3_threadsafe             sqlite3_api->xthreadsafe
#define sqlite3_result_zeroblob        sqlite3_api->result_zeroblob
#define sqlite3_result_error_code      sqlite3_api->result_error_code
#define sqlite3_test_control           sqlite3_api->test_control
#define sqlite3_randomness             sqlite3_api->randomness
#define sqlite3_context_db_handle      sqlite3_api->context_db_handle
#define sqlite3_extended_result_codes  sqlite3_api->extended_result_codes
#define sqlite3_limit                  sqlite3_api->limit
#define sqlite3_next_stmt              sqlite3_api->next_stmt
#define sqlite3_sql                    sqlite3_api->sql
#define sqlite3_status                 sqlite3_api->status
#define sqlite3_backup_finish          sqlite3_api->backup_finish
#define sqlite3_backup_init            sqlite3_api->backup_init
#define sqlite3_backup_pagecount       sqlite3_api->backup_pagecount
#define sqlite3_backup_remaining       sqlite3_api->backup_remaining
#define sqlite3_backup_step            sqlite3_api->backup_step
#define sqlite3_compileoption_get      sqlite3_api->compileoption_get
#define sqlite3_compileoption_used     sqlite3_api->compileoption_used
#define sqlite3_create_function_v2     sqlite3_api->create_function_v2
#define sqlite3_db_config              sqlite3_api->db_config
#define sqlite3_db_mutex               sqlite3_api->db_mutex
#define sqlite3_db_status              sqlite3_api->db_status
#define sqlite3_extended_errcode       sqlite3_api->extended_errcode
#define sqlite3_log                    sqlite3_api->log
#define sqlite3_soft_heap_limit64      sqlite3_api->soft_heap_limit64
#define sqlite3_sourceid               sqlite3_api->sourceid
#define sqlite3_stmt_status            sqlite3_api->stmt_status
#define sqlite3_strnicmp               sqlite3_api->strnicmp
#define sqlite3_unlock_notify          sqlite3_api->unlock_notify
#define sqlite3_wal_autocheckpoint     sqlite3_api->wal_autocheckpoint
#define sqlite3_wal_checkpoint         sqlite3_api->wal_checkpoint
#define sqlite3_wal_hook               sqlite3_api->wal_hook
#define sqlite3_blob_reopen            sqlite3_api->blob_reopen
#define sqlite3_vtab_config            sqlite3_api->vtab_config
#define sqlite3_vtab_on_conflict       sqlite3_api->vtab_on_conflict
/* Version 3.7.16 and later */
#define sqlite3_close_v2               sqlite3_api->close_v2
#define sqlite3_db_filename            sqlite3_api->db_filename
#define sqlite3_db_readonly            sqlite3_api->db_readonly
#define sqlite3_db_release_memory      sqlite3_api->db_release_memory
#define sqlite3_errstr                 sqlite3_api->errstr
#define sqlite3_stmt_busy              sqlite3_api->stmt_busy
#define sqlite3_stmt_readonly          sqlite3_api->stmt_readonly
#define sqlite3_stricmp                sqlite3_api->stricmp
#define sqlite3_uri_boolean            sqlite3_api->uri_boolean
#define sqlite3_uri_int64              sqlite3_api->uri_int64
#define sqlite3_uri_parameter          sqlite3_api->uri_parameter
#define sqlite3_uri_vsnprintf          sqlite3_api->xvsnprintf
#define sqlite3_wal_checkpoint_v2      sqlite3_api->wal_checkpoint_v2
/* Version 3.8.7 and later */
#define sqlite3_auto_extension         sqlite3_api->auto_extension
#define sqlite3_bind_blob64            sqlite3_api->bind_blob64
#define sqlite3_bind_text64            sqlite3_api->bind_text64
#define sqlite3_cancel_auto_extension  sqlite3_api->cancel_auto_extension
#define sqlite3_load_extension         sqlite3_api->load_extension
#define sqlite3_malloc64               sqlite3_api->malloc64
#define sqlite3_msize                  sqlite3_api->msize
#define sqlite3_realloc64              sqlite3_api->realloc64
#define sqlite3_reset_auto_extension   sqlite3_api->reset_auto_extension
#define sqlite3_result_blob64          sqlite3_api->result_blob64
#define sqlite3_result_text64          sqlite3_api->result_text64
#define sqlite3_strglob                sqlite3_api->strglob
/* Version 3.8.11 and later */
#define sqlite3_value_dup              sqlite3_api->value_dup
#define sqlite3_value_free             sqlite3_api->value_free
#define sqlite3_result_zeroblob64      sqlite3_api->result_zeroblob64
#define sqlite3_bind_zeroblob64        sqlite3_api->bind_zeroblob64
/* Version 3.9.0 and later */
#define sqlite3_value_subtype          sqlite3_api->value_subtype
#define sqlite3_result_subtype         sqlite3_api->result_subtype
/* Version 3.10.0 and later */
#define sqlite3_status64               sqlite3_api->status64
#define sqlite3_strlike                sqlite3_api->strlike
#define sqlite3_db_cacheflush          sqlite3_api->db_cacheflush
/* Version 3.12.0 and later */
#define sqlite3_system_errno           sqlite3_api->system_errno
/* Version 3.14.0 and later */
#define sqlite3_trace_v2               sqlite3_api->trace_v2
#define sqlite3_expanded_sql           sqlite3_api->expanded_sql
/* Version 3.18.0 and later */
#define sqlite3_set_last_insert_rowid  sqlite3_api->set_last_insert_rowid
/* Version 3.20.0 and later */
#define sqlite3_prepare_v3             sqlite3_api->prepare_v3
#define sqlite3_prepare16_v3           sqlite3_api->prepare16_v3
#define sqlite3_bind_pointer           sqlite3_api->bind_pointer
#define sqlite3_result_pointer         sqlite3_api->result_pointer
#define sqlite3_value_pointer          sqlite3_api->value_pointer
/* Version 3.22.0 and later */
#define sqlite3_vtab_nochange          sqlite3_api->vtab_nochange
#define sqlite3_value_nochange         sqlite3_api->value_nochange
#define sqlite3_vtab_collation         sqlite3_api->vtab_collation
/* Version 3.24.0 and later */
#define sqlite3_keyword_count          sqlite3_api->keyword_count
#define sqlite3_keyword_name           sqlite3_api->keyword_name
#define sqlite3_keyword_check          sqlite3_api->keyword_check
#define sqlite3_str_new                sqlite3_api->str_new
#define sqlite3_str_finish             sqlite3_api->str_finish
#define sqlite3_str_appendf            sqlite3_api->str_appendf
#define sqlite3_str_vappendf           sqlite3_api->str_vappendf
#define sqlite3_str_append             sqlite3_api->str_append
#define sqlite3_str_appendall          sqlite3_api->str_appendall
#define sqlite3_str_appendchar         sqlite3_api->str_appendchar
#define sqlite3_str_reset              sqlite3_api->str_reset
#define sqlite3_str_errcode            sqlite3_api->str_errcode
#define sqlite3_str_length             sqlite3_api->str_length
#define sqlite3_str_value              sqlite3_api->str_value
/* Version 3.25.0 and later */
#define sqlite3_create_window_function sqlite3_api->create_window_function
/* Version 3.26.0 and later */
#define sqlite3_normalized_sql         sqlite3_api->normalized_sql
/* Version 3.28.0 and later */
#define sqlite3_stmt_isexplain         sqlite3_api->stmt_isexplain
#define sqlite3_value_frombind         sqlite3_api->value_frombind
/* Version 3.30.0 and later */
#define sqlite3_drop_modules           sqlite3_api->drop_modules
/* Version 3.31.0 and later */
#define sqlite3_hard_heap_limit64      sqlite3_api->hard_heap_limit64
#define sqlite3_uri_key                sqlite3_api->uri_key
#define sqlite3_filename_database      sqlite3_api->filename_database
#define sqlite3_filename_journal       sqlite3_api->filename_journal
#define sqlite3_filename_wal           sqlite3_api->filename_wal
/* Version 3.32.0 and later */
#define sqlite3_create_filename        sqlite3_api->create_filename
#define sqlite3_free_filename          sqlite3_api->free_filename
#define sqlite3_database_file_object   sqlite3_api->database_file_object
/* Version 3.34.0 and later */
#define sqlite3_txn_state              sqlite3_api->txn_state
/* Version 3.36.1 and later */
#define sqlite3_changes64              sqlite3_api->changes64
#define sqlite3_total_changes64        sqlite3_api->total_changes64
/* Version 3.37.0 and later */
#define sqlite3_autovacuum_pages       sqlite3_api->autovacuum_pages
/* Version 3.38.0 and later */
#define sqlite3_error_offset           sqlite3_api->error_offset
#define sqlite3_vtab_rhs_value         sqlite3_api->vtab_rhs_value
#define sqlite3_vtab_distinct          sqlite3_api->vtab_distinct
#define sqlite3_vtab_in                sqlite3_api->vtab_in
#define sqlite3_vtab_in_first          sqlite3_api->vtab_in_first
#define sqlite3_vtab_in_next           sqlite3_api->vtab_in_next
/* Version 3.39.0 and later */
#ifndef SQLITE_OMIT_DESERIALIZE
#define sqlite3_deserialize            sqlite3_api->deserialize
#define sqlite3_serialize              sqlite3_api->serialize
#endif
#define sqlite3_db_name                sqlite3_api->db_name
/* Version 3.40.0 and later */
#define sqlite3_value_encoding         sqlite3_api->value_encoding
/* Version 3.41.0 and later */
#define sqlite3_is_interrupted         sqlite3_api->is_interrupted
/* Version 3.43.0 and later */
#define sqlite3_stmt_explain           sqlite3_api->stmt_explain
/* Version 3.44.0 and later */
#define sqlite3_get_clientdata         sqlite3_api->get_clientdata
#define sqlite3_set_clientdata         sqlite3_api->set_clientdata
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
  /* This case when the file really is being compiled as a loadable
  ** extension */
# define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v;
# define SQLITE_EXTENSION_INIT3     \
    extern const sqlite3_api_routines *sqlite3_api;
#else
  /* This case when the file is being statically linked into the
  ** application */
# define SQLITE_EXTENSION_INIT1     /*no-op*/
# define SQLITE_EXTENSION_INIT2(v)  (void)v; /* unused parameter */
# define SQLITE_EXTENSION_INIT3     /*no-op*/
#endif
#endif /* SQLITE3EXT_H */