Figure 6: SQL statement caching classes
#define CHECK_QUERY_LENGTH 128
class StoredQuery : public LstLink0 {
public :
    Query* data;
    ExactString stackName;
    ExactString queryText;
    StoredQuery(const Query& query, char* text);
    ~StoredQuery()  {
        data->state &= ~DQS_CACHED;
        delete data;
    }
};

class StackOfQuery : public LstList {
public :
    StackOfQuery() : LstList("Query Stack") {};
    ~StackOfQuery() { flush(); }
    Result Add(const Query& query, char* text);
    Result Remove(const char* name);
    Result RemoveStack(const char* name);
    StoredQuery* findByName(const char* name);
    static void flush();
};


StoredQuery:: StoredQuery(const Query& query, char* text) 
        : LstLink0() {
    stackName = query.getStackName();
    if (strlen(text) > CHECK_QUERY_LENGTH)
        queryText = StdFormat("%.*s", CHECK_QUERY_LENGTH,text);
    else
        queryText = text;
    data = query.dup();
    data->cloneFrom(query);
    data->state = DQS_PREPARED | DQS_CACHED | DQS_HAS_STMT;
}

StackOfQuery stackOfQuery;

void StackOfQuery::flush() {
    for (Pointer item = stackOfQuery.getFirst(); item;
            item = stackOfQuery.getFirst()) {
        stackOfQuery.LstList::Detach(item);
        delete (StoredQuery*)item;
    }
}

StoredQuery* StackOfQuery::findByName(const char* name) {
    for (Pointer item = getFirst(); item; item = getNext(item))
        if (strcmp(((StoredQuery*)item)->data->getQueryName(),
                   name)==0)
            return (StoredQuery*)item;
    return 0;
}

Query* Query::findByName(const char* name) {
    StoredQuery* item = stackOfQuery.findByName(name);
    return item ? item->data : 0;
}

Result StackOfQuery::Add(const Query& query, char* text) {
    if (!(query.state & DQS_PREPARED) 
            || findByName(query.getQueryName()))
        return FAIL;
    StoredQuery* storedQuery = new StoredQuery(query,text);
    return LstList::Add(storedQuery);
}

Result StackOfQuery::Remove(const char* name) {
    StoredQuery* storedQuery = findByName(name);
    if (!storedQuery)
        return FAIL;
    if (LstList::Detach(storedQuery)==FAIL)
        return FAIL;
    delete storedQuery;
    return OK;
}

Result StackOfQuery::RemoveStack(const char* name) {
    for (Pointer next, item = getFirst(); item; item = next) {
        next = getNext(item);
        StoredQuery* q = (StoredQuery*)item;
        if (strcmp(q->stackName,name) == 0) {
            LstList::Detach(q);
            delete q;
        }
    }
    return OK;
}

/* End of File */