// 执行(有结果) bool CSQLiteHelper::Excute(const char* sql, CSQLRecordset& record_set) { assert(sql); assert(m_sqlite); char* msg = NULL; int row = -1; int colum = -1; char **result = NULL; //二维数组存放结果 if(SQLITE_OK != sqlite3_get_table(m_sqlite, sql, &result, &row, &colum, &msg)) { if(msg != NULL) { IsAnException(msg); //TPLOG_ERROR("exec %s failed-%s", (const char*)fcT2A(sql), // (const char*)fcU2A(errMsg)); sqlite3_free(msg); } else { //TPLOG_ERROR("exec %s failed", (const char*)fcT2A(sql)); } return false; } record_set.set_data(result, row, colum); return true; }
static value_t wrap_source_iterator( zone_t zone, value_t original ) { if (IsAnException( original )) return original; // Here's an iterator from the original sequence. Wrap it in one of our // parallelized iterators, then try to get one of our workers going on it. struct closure *out = ALLOC( pariter, ITERATOR_SLOT_COUNT ); out->slots[ITERATOR_WRAPPED_SLOT] = original; queue_iterator( zone, out ); return out; }
static value_t catch_exception_func( PREFUNC, value_t exp, value_t handler ) { ARGCHECK_2( NULL, handler ); if (IsAnException( exp )) { value_t val = exp->slots[0]; assert( handler ); exp = CALL_1( handler, val ); } return exp; }
static value_t List_constructor( PREFUNC, value_t exp ) { ARGCHECK_1( exp ); // This intrinsic function represents the brackets syntax for list // construction. Our exp is whatever was enclosed in the brackets. // This ought to be a tuple, or something which looks like one; each // element of the tuple will be a new entry in the array. value_t out = &list_empty; if (exp) { value_t item_count = METHOD_0( exp, sym_size ); if (IsAnException( item_count )) return item_count; unsigned int items = IntFromFixint( item_count ); for (unsigned int i = 0; i < items; i++) { value_t item = CALL_1( exp, NumberFromInt( zone, i ) ); if (IsAnException( item )) return item; out = METHOD_1( out, sym_append, item ); } } return out; }
static value_t parseq_iterate( PREFUNC, value_t sequence ) { ARGCHECK_1( sequence ); // Retrieve our target sequence. Call its "iterate" method to retrieve its // first iterator. Wrap that iterator in our populated-iterator wrapper, // which will compute and pull the "current" value and then keep pulling // iterators until it has gotten all of the workers in on the game. value_t original_sequence = sequence->slots[0]; value_t src_iterator = METHOD_0( original_sequence, sym_iterate ); if (IsAnException( src_iterator )) return src_iterator; return wrap_source_iterator( zone, src_iterator ); }
int IntFromRelation( zone_t zone, value_t relation ) { assert( !IsAnException( relation ) ); // A relation is a function which returns one of its three arguments. It's // possible that the relation is one of the stock relations we've defined // here, in which case we can perform a trivial pointer check. Otherwise, // we can convert a relation to an int by passing specific arguments in and // seeing which one comes back out. if (relation == &s_less_than) return -1; if (relation == &s_equal) return 0; if (relation == &s_greater_than) return 1; relation = CALL_3( relation, &s_less_than, &s_equal, &s_greater_than ); if (relation == &s_less_than) return -1; if (relation == &s_equal) return 0; if (relation == &s_greater_than) return 1; assert( false ); }
static void process_iterator( zone_t zone, value_t it ) { if (IsAnException( it )) return; // Flatten out this iterator, right here and now. We are a wrapper around // some source-sequence iterator; our job is to memoize all of its // functions. This is technically a violation of object immutability, but // it has to happen somewhere. We'll never let anyone look at the contents // of a wrapper iterator before flattening it, and there is no way to clone // it (or to end up with two wrappers for the same target), so it still // works like an immutable object even if we actually change its contents. struct closure *iter = CLOSURE(it); value_t source = iter->slots[ITERATOR_WRAPPED_SLOT]; if (!source) return; // Find out whether the iterator is valid, or is the terminator. value_t valid = METHOD_0( source, sym_is_valid ); iter->slots[ITERATOR_VALID_SLOT] = valid; if (BoolFromBoolean( zone, valid )) { // Get a reference to the next iterator in the sequence. We do this // before evaluating the element value in hopes of getting it running // on a(nother) worker. value_t next = METHOD_0( source, sym_next ); iter->slots[ITERATOR_NEXT_SLOT] = wrap_source_iterator( zone, next ); // Evaluate the element value. If we are lucky, this will take a long // time. value_t current = METHOD_0( source, sym_current ); iter->slots[ITERATOR_CURRENT_SLOT] = current; } // Zero out the source reference. This is how we signal that the iterator // wrapper has already been flattened and does not need any more processing. iter->slots[ITERATOR_WRAPPED_SLOT] = NULL; }
// 执行(无结果) bool CSQLiteHelper::Excute(const char* sql) { assert(sql); assert(m_sqlite); char* msg = NULL; int rc = sqlite3_exec(m_sqlite, sql, 0, 0, &msg); if(SQLITE_OK == rc) { return true; } if(msg != NULL) { IsAnException(msg); //TPLOG_ERROR("exec %s failed-%s", (const char*)fcT2A(sql), // (const char*)fcU2A(errMsg)); sqlite3_free(msg); } return false; }
static value_t Pointer_function( PREFUNC, value_t parameter ) { if (IsAnException(parameter)) return parameter; return ThrowCStr( zone, "symbol does not have that member" ); }
static value_t List_concatenate( PREFUNC, value_t listObj, value_t otherList ) { ARGCHECK_2( listObj, otherList ); // If the list to be concatenated is also a multi-item list, we will do an // efficient concatenation by taking advantage of our knowledge of its // internal structure. Otherwise, we will hope it is a sequence and append // each of its items. if (otherList->function == (function_t)List_function) { value_t ourHeadChunk = listObj->slots[LIST_HEAD_CHUNK_SLOT]; value_t ourColdStorage = listObj->slots[LIST_COLD_STORAGE_SLOT]; value_t ourTailChunk = listObj->slots[LIST_TAIL_CHUNK_SLOT]; value_t otherHeadChunk = otherList->slots[LIST_HEAD_CHUNK_SLOT]; value_t otherColdStorage = otherList->slots[LIST_COLD_STORAGE_SLOT]; value_t otherTailChunk = otherList->slots[LIST_TAIL_CHUNK_SLOT]; // We need to put these chunks into cold storage somehow. There are // enough possibilities that it would be tedious to do it all with if- // statements. Instead, we have this matrix, which will map each of the // sixteen possible combinations down to one of six actions. The // horizontal axis represents the size of the other list's head chunk; // the vertical axis represents the size of our list's tail chunk. int actions[4][4] = { {0, 1, 2, 2}, {0, 4, 4, 2}, {3, 4, 4, 5}, {3, 3, 5, 5}}; int x_size = chunk_item_count(otherHeadChunk); int y_size = chunk_item_count(ourTailChunk); switch(actions[y_size][x_size]) { case 0: { // Append other chunk's head to our chunk. Append our chunk to // our cold storage; let the other chunk drop. value_t item = chunk_head( otherHeadChunk ); ourTailChunk = chunk_append( zone, ourTailChunk, item ); ourColdStorage = METHOD_1( ourColdStorage, sym_append, ourTailChunk ); } break; case 1: { // Push our chunk's tail onto the other chunk. Push the other // chunk onto its cold storage, then let ours drop. value_t item = chunk_tail( zone, ourTailChunk ); otherHeadChunk = chunk_push( zone, otherHeadChunk, item ); otherColdStorage = METHOD_1( otherColdStorage, sym_push, otherHeadChunk ); } break; case 2: { // Append other chunk's head to our chunk. Append our chunk to // our cold storage and push the other chunk onto its. value_t item = chunk_head( otherHeadChunk ); otherHeadChunk = chunk_pop( zone, otherHeadChunk ); otherColdStorage = METHOD_1( otherColdStorage, sym_push, otherHeadChunk ); ourTailChunk = chunk_append( zone, ourTailChunk, item ); ourColdStorage = METHOD_1( ourColdStorage, sym_append, ourTailChunk ); } break; case 3: { // Push our chunk's tail onto the other chunk. Put each chunk // into its own cold storage. value_t item = chunk_tail( zone, ourTailChunk ); ourTailChunk = chunk_chop( zone, ourTailChunk ); ourColdStorage = METHOD_1( ourColdStorage, sym_append, ourTailChunk ); otherHeadChunk = chunk_push( zone, otherHeadChunk, item ); otherColdStorage = METHOD_1( otherColdStorage, sym_push, otherHeadChunk ); } break; case 4: { // Put each chunk into its own cold storage. ourColdStorage = METHOD_1( ourColdStorage, sym_append, ourTailChunk ); otherColdStorage = METHOD_1( otherColdStorage, sym_push, otherHeadChunk ); } break; case 5: { // Split one item off of each chunk to create a new middle // chunk. Put each original chunk onto its own list, then add // the middle chunk to our cold storage. value_t item = chunk_tail( zone, ourTailChunk ); ourTailChunk = chunk_chop( zone, ourTailChunk ); ourColdStorage = METHOD_1( ourColdStorage, sym_append, ourTailChunk ); value_t midChunk = chunk_alloc_1( zone, item ); item = chunk_head( otherHeadChunk ); otherHeadChunk = chunk_pop( zone, otherHeadChunk ); otherColdStorage = METHOD_1( otherColdStorage, sym_push, otherHeadChunk ); midChunk = chunk_append( zone, midChunk, item ); ourColdStorage = METHOD_1( ourColdStorage, sym_append, midChunk ); } break; } // Having dealt with the active chunks, we now have a head chunk for // the whole list, a tail chunk for the whole list, and two cold // storage lists. We will recursively concatenate the cold storage // lists, then assemble our output list from these pieces. value_t combined_storage = METHOD_1( ourColdStorage, sym_concatenate, otherColdStorage ); listObj = alloc_list( zone, ourHeadChunk, combined_storage, otherTailChunk ); } else { value_t iter = METHOD_0( otherList, sym_iterate ); if (IsAnException( iter )) return iter; while (BoolFromBoolean( zone, METHOD_0( iter, sym_is_valid ) )) { value_t val = METHOD_0( iter, sym_current ); listObj = METHOD_1( listObj, sym_append, val ); iter = METHOD_0( iter, sym_next ); } } return listObj; }
value_t ExceptionContents( value_t exception ) { assert( IsAnException( exception ) ); return exception->slots[0]; }
static value_t is_not_exceptional_func( PREFUNC, value_t exp ) { ARGCHECK_1( NULL ); return BooleanFromBool( !IsAnException( exp ) ); }