alliedmodders / sourcemod

SourceMod - Source Engine Scripting and Administration
http://www.sourcemod.net/
990 stars 425 forks source link

Cloning a DBResultSet randomly deletes rows from it #2197

Closed bottiger1 closed 4 months ago

bottiger1 commented 4 months ago

Help us help you

Environment

If you clone a DBResultSet so you can process it later (because it gets automatically deleted when the callback ends), random rows are missing from this DBResultSet.

Nothing is missing when I process the rows on the callback so it is a problem with CloneHandle and the Database driver.

Handle g_db;
DBResultSet g_resultset;

public OnPluginStart()
{
       SQL_TConnect(OnConnected);
       CreateTimer(0.015, Timer_ProcessResults, _, TIMER_REPEAT);
}

public OnConnected(Handle:driver, Handle:db, const String:error[], any:data) 
{
      g_db = db;
      SQL_TQuery(g_db, OnQueryComplete, "SELECT id FROM foo");
}

public OnQueryComplete(Database db, DBResultSet query, const char[] error)
{
    g_resultset = view_as<DBResultSet>(CloneHandle(query));

    // no missing rows if I just process the uncloned results right here
    /*
        int processed;
        while(query.FetchRow())
        {
            processed++;
        }
        PrintToServer("processed %i", processed); // 1000
    */
}

static Action Timer_ProcessResults(Handle timer)
{
    if(!g_resultset)
    {
        return Plugin_Continue;
    }

    PrintToServer("rows %i", g_resultset.RowCount); // 1000

    int processed;
    while(g_resultset.FetchRow() && processed <= 2000)
    {
        processed++;
    }

    PrintToServer("processed %i", processed); // 994 (random rows missing)

    if(g_resultset.MoreRows)
    {
        return Plugin_Continue;
    }

    delete g_resultset;
}
bottiger1 commented 4 months ago

Never mind, I believe it may be due to connection issues.