示例#1
0
rho::String js_SQLite3_execute(const rho::String& strObjID, CJSONArray& argv, const rho::String&, const rho::String&, const rho::String& )
{
    rho::database::ISQLite3* pObj = rho::database::CSQLite3FactoryBase::getInstance()->getModuleByID(strObjID);
    void* pDB =  static_cast<rho::database::CSQLite3Impl*>(pObj)->getDb();

    sqlite3 * db = NULL;
    void **ppDB = &pDB;
    sqlite3_stmt *statement = NULL;
    const char* sql = NULL;
    Vector< rho::Hashtable<rho::String, rho::String> > arRes;
    rho::apiGenerator::CMethodResult oResult;

    int nRes = 0;
    char * szErrMsg = 0;
    int is_batch = 0;

    db = (sqlite3 *)rho_db_get_handle(*ppDB);
    sql = argv[0].getString();
    is_batch = argv[1].getBoolean();

    RAWTRACE1("db_execute: %s", sql);

    PROF_START_CREATED("SQLITE");
    if ( is_batch )
    {
        PROF_START_CREATED("SQLITE_EXEC");

        rho_db_lock(*ppDB);
        nRes = sqlite3_exec(db, sql,  NULL, NULL, &szErrMsg);
        rho_db_unlock(*ppDB);

        PROF_STOP("SQLITE_EXEC");
    }
    else
    {
        rho_db_lock(*ppDB);
        PROF_START_CREATED("SQLITE_PREPARE");
        nRes = rho_db_prepare_statement(*ppDB, sql, -1, &statement);
        PROF_STOP("SQLITE_PREPARE");
        if ( nRes != SQLITE_OK)
        {
            szErrMsg = (char *)sqlite3_errmsg(db);
            rho_db_unlock(*ppDB);

            oResult.setArgError( String("could not prepare statement: ") + convertToStringA(nRes) + "; Message: " + (szErrMsg?szErrMsg:""));
            return oResult.toJSON();
        }

        if ( argv.getSize() > 2 && argv[2].isArray() )
        {
            int i = 0;
            CJSONArray args( argv[2] );

            for( ; i < args.getSize(); i++ )
            {
                CJSONEntry arg = args[i];
                if ( arg.isNull() )
                {
                    sqlite3_bind_null(statement, i+1);
                    continue;
                }

                if ( arg.isString() )
                    sqlite3_bind_text(statement, i+1, arg.getString(), strlen(arg.getString()), SQLITE_TRANSIENT);
                else if (arg.isFloat())
                    sqlite3_bind_double(statement, i+1, arg.getDouble() );
                else if (arg.isInteger())
                    sqlite3_bind_int64(statement, i+1, arg.getUInt64() );
                else if (arg.isBoolean())
                    sqlite3_bind_int(statement, i+1, arg.getBoolean() ? 1 : 0 );
                else
                {
                    sqlite3_reset(statement);

                    oResult.setArgError( String("Unsupported argument type. Argument number: ") + convertToStringA(i));
                    return oResult.toJSON();
                }
            }
        }

        PROF_START_CREATED("SQLITE_EXEC");
        nRes = sqlite3_step(statement);
        PROF_STOP("SQLITE_EXEC");

        while( nRes== SQLITE_ROW )
        {
            int nCount = sqlite3_data_count(statement);
            int nCol = 0;
            rho::Hashtable<rho::String, rho::String> hashRec;

            for(; nCol<nCount; nCol++)
            {
                int nColType = sqlite3_column_type(statement,nCol);
                const char* szColName = sqlite3_column_name(statement,nCol);
                String colValue;

                switch(nColType)
                {
                case SQLITE_NULL:
                    break;
                case SQLITE_FLOAT:
                {
                    double dVal = sqlite3_column_double(statement, nCol);
                    colValue = convertToStringA(dVal);
                    break;
                }
                case SQLITE_INTEGER:
                {
                    sqlite_int64 nVal = sqlite3_column_int64(statement, nCol);
                    colValue = convertToStringA(nVal);
                    break;
                }
                default: {
                    sqlite3_value * sqlValue = sqlite3_column_value(statement, nCol);
                    int nLen = sqlite3_value_bytes(sqlValue);
                    const char*  szValue = (const char *)sqlite3_value_text(sqlValue);
                    colValue = String(szValue, nLen);
                    break;
                }
                }

                hashRec[szColName] = colValue;
            }

            arRes.addElement( hashRec );

            PROF_START_CREATED("SQLITE_EXEC");
            nRes = sqlite3_step(statement);
            PROF_STOP("SQLITE_EXEC");

        }

        rho_db_unlock(*ppDB);

    }

    if ( statement )
        sqlite3_reset(statement);

    PROF_STOP("SQLITE");

    if ( nRes != SQLITE_OK && nRes != SQLITE_ROW && nRes != SQLITE_DONE )
    {
        if ( !szErrMsg )
            szErrMsg = (char*)sqlite3_errmsg(db);

        oResult.setError( String("could not execute statement: ") + convertToStringA(nRes) + "; Message: " + (szErrMsg?szErrMsg:""));
        return oResult.toJSON();
    }

    oResult.set(arRes);

    return oResult.toJSON();
}