⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subsql.cpp

📁 用于嵌入式环境的数据库
💻 CPP
📖 第 1 页 / 共 5 页
字号:
               case tpInteger:
                 *(int2*)dst = (int2)sattr.ivalue;
                 continue;
               case tpBoolean:
                 *(int2*)dst = sattr.bvalue ? 1 : 0;
                 continue;
               case tpReal:
                 *(int2*)dst = (int2)sattr.fvalue;
                 continue;
               case tpString:
                 *(int2*)dst = (int2)atoi((char*)sattr.base);
                 continue;
             }
             break;
           case dbField::tpInt4:
             switch (expr->type) { 
               case tpInteger:
                 *(int4*)dst = (int4)sattr.ivalue;
                 continue;
               case tpBoolean:
                 *(int4*)dst = sattr.bvalue ? 1 : 0;
                 continue;
               case tpReal:
                 *(int4*)dst = (int4)sattr.fvalue;
                 continue;
               case tpString:
                 *(int4*)dst = (int1)atoi((char*)sattr.base);
                 continue;
             }
             break;
           case dbField::tpInt8:
             switch (expr->type) { 
               case tpInteger:
                 *(db_int8*)dst = sattr.ivalue;
                 continue;
               case tpBoolean:
                 *(db_int8*)dst = sattr.bvalue ? 1 : 0;
                 continue;
               case tpReal:
                 *(db_int8*)dst = (db_int8)sattr.fvalue;
                 continue;
               case tpString:
                 *(db_int8*)dst = (db_int8)atoi((char*)sattr.base);
                 continue;
             }
             break;
           case dbField::tpReal4:
             switch (expr->type) { 
               case tpInteger:
                 *(real4*)dst = (real4)sattr.ivalue;
                 continue;
               case tpBoolean:
                 *(real4*)dst = (real4)(sattr.bvalue ? 1 : 0);
                 continue;
               case tpReal:
                 *(real4*)dst = (real4)sattr.fvalue;
                 continue;
               case tpString:
                 *(real4*)dst = (real4)atof((char*)sattr.base);
                 continue;
             }
             break;
           case dbField::tpReal8:
             switch (expr->type) { 
               case tpInteger:
                 *(real8*)dst = (real8)sattr.ivalue;
                 continue;
               case tpBoolean:
                 *(real8*)dst = sattr.bvalue ? 1.0 : 0.0;
                 continue;
               case tpReal:
                 *(real8*)dst = sattr.fvalue;
                 continue;
               case tpString:
                 *(real8*)dst = atof((char*)sattr.base);
                 continue;
             }
             break;
           case dbField::tpString:
             src = buf;
             switch (expr->type) { 
               case tpInteger:
                 sprintf(buf, INT8_FORMAT, sattr.ivalue);
                 break;
               case tpBoolean:
                 strcpy(buf, sattr.bvalue ? "t" : "f");
                 break;
               case tpReal:
                 sprintf(buf, "%f", sattr.fvalue);
                 break;
               case tpString:
                 src = (char*)sattr.base;
                 break;
             }
             *(char**)dst = new char[strlen(src)+1];
             strcpy(*(char**)dst, src);
             elems->strValue = *(char**)dst;
             continue;
           case dbField::tpReference:
             if (expr->type == tpInteger) { 
                 *(oid_t*)dst = sattr.oid;
                 continue;
             }
         }
         assert(false);
     } while ((elems = elems->next) != NULL);

     return true;
}

bool dbSubSql::parse() 
{
    dbTableDescriptor* desc;
    dbFieldDescriptor* fd;
    int tkn;
    bool count, outputOid, compactify;

    line = 1;
    pos = 0;

    while (true) { 
        if (in == stdin) { 
            printf(prompt);
            tkn = scan();
            pos += strlen(prompt);
        } else { 
            tkn = scan();
        }           

        switch (tkn) { 
          case tkn_update:
            if (!opened) { 
                error("Database not opened");
                continue;
            }
            if (accessType == dbReadOnly) { 
                error("Operation is not possible in read-only mode");
                continue;
            }
            if (expect("table name", tkn_ident)) {
                if ((desc = findTable(name)) == NULL) { 
                    error("No such table in database");
                    continue;
                }
                if (!expect("set", tkn_set)) { 
                    continue;
                }

                dbDatabaseThreadContext* ctx = threadContext.get();
                byte *record = dbMalloc(desc->appSize);
                ctx->interactive = true;
                ctx->catched = true;
                dbUpdateElement* elems = NULL;
                if (!expect("field name", tkn_ident)) { 
                    goto updateCleanup;
                }
        
#ifdef THROW_EXCEPTION_ON_ERROR
                try {
#else
                if (setjmp(ctx->unwind) == 0) {
#endif
                    
                    char* condition = NULL;
                    int startPos = pos;
                    while (true) { 
                        dbUpdateElement* elem = new dbUpdateElement;
                        dbFieldDescriptor* fd = desc->findSymbol(name);
                        if (fd == NULL) { 
                            error("No such field in the table");
                            goto updateCleanup;
                        }
                        if (fd->type > dbField::tpReference) { 
                            error("Field can not be updated");
                            goto updateCleanup;
                        }
                        elem->field = fd;
                        elem->next = elems;
                        elems = elem;
                        if (!expect("=", tkn_eq)) { 
                            goto updateCleanup;
                        }
                        startPos = pos;
                        int ch = readExpression();
                        if (ch == EOF) { 
                            error("unexpected end of input");
                            goto updateCleanup;
                        } 
                        condition = strstr(buf, "where");
                        if (condition != NULL) {
                            *condition = '\0';
                        }
                        dbExprNode* expr = ctx->compiler.compileExpression(desc, buf, startPos);
                        if (expr == NULL) { 
                            goto updateCleanup;
                        }
                        if (expr->type > tpString) { 
                            error("Invalid expression type");
                            goto updateCleanup;
                        }
                        elem->value = expr;
                        if (condition == NULL && ch == ',') { 
                            if (!expect("field name", tkn_ident)) { 
                                goto updateCleanup;
                            }
                        } else { 
                            break;
                        }
                    }
                    dbAnyCursor cursor(*desc, dbCursorForUpdate, record);
                    cursor.reset();
                        
                    if (condition != NULL) { 
                        query.pos = startPos + (condition - buf) + 5;
                        query = (char const*)(condition + 5);
                        select(&cursor, query);
                        if (!query.compiled()) { 
                            goto updateCleanup;
                        }                                   
                    } else { 
                        select(&cursor);
                    }
                    if (cursor.gotoFirst()) { 
                        do { 
                            cursor.fetch();
                            if (!updateFields(&cursor, elems)) { 
                                goto updateCleanup;
                            }   
                            cursor.update();
                        } while (cursor.gotoNext());
                    }
                    printf("\n\t%d records updated\n", cursor.getNumberOfRecords());
#ifdef THROW_EXCEPTION_ON_ERROR
                } catch(dbException const&) {}
#else
                } else { 
                    if (query.mutexLocked) { 
                        query.mutexLocked = false;
                        query.mutex.unlock();
                    }
                }
#endif
              updateCleanup:
                query.reset();
                while (elems != NULL) { 
                    dbUpdateElement* elem = elems;
                    elems = elems->next;
                    delete elem;
                }
                if (autocommit || !modified) { 
                    commit(); // release locks
                }
                dbExprNodeAllocator::instance.reset();
                ctx->catched = false;
                dbFree(record);
            }
            continue;

          case tkn_select:
            if (!opened) { 
                error("Database not opened");
                continue;
            }
            outputOid = true;
            count = false;
            if ((tkn = scan()) == tkn_all) { 
                outputOid = false;
                tkn = scan();
            } else if (tkn == tkn_count) { 
                if (!expect("'('", tkn_lpar)
                    || !expect("'*'", tkn_all)
                    || !expect("')'", tkn_rpar))
                {
                    continue;
                }
                count = true;
                tkn = scan();
            }
            if (tkn != tkn_from) { 
                error("'from' keyword expected");
                continue;
            }
            if (scan() != tkn_ident) { 
                error("Table name expected");
                continue;
            }
            if ((desc = findTable(name)) != NULL) {     
                dbAnyCursor cursor(*desc, dbCursorViewOnly, NULL);
                query.pos = pos;
                dbDatabaseThreadContext* ctx = threadContext.get();
                ctx->interactive = true;
                ctx->catched = true;
#ifdef THROW_EXCEPTION_ON_ERROR
                try {
#else
                if (setjmp(ctx->unwind) == 0) {
#endif
                    if (readCondition()) { 
                        query = (char const*)buf;
                        cursor.reset();
                        select(&cursor, query);
                        if (!query.compiled()) { 
                            dbExprNodeAllocator::instance.reset();
                            ctx->catched = false;
                            continue;
                        }                
                    } else { 
                        ctx->catched = false;
                        continue;
                    }
                    if (count) { 
                        printf("%d records selected\n",
                               cursor.getNumberOfRecords());
                    } else { 
                        if (cursor.gotoFirst()) { 
                            dbFieldDescriptor* fd = desc->columns; 
                            do { 
                                printf("%s ", fd->name);
                            } while ((fd = fd->next) != desc->columns);
                            if (outputOid) { 
                            printf("\n#%x: (", cursor.currId);
                            } else { 
                                printf("\n(");
                            }
                            dumpRecord((byte*)getRow(cursor.currId), 
                                       cursor.table->columns);
                            printf(")");
                            while (cursor.gotoNext()) { 
                                if (outputOid) { 
                                    printf(",\n#%x: (", cursor.currId);
                                } else { 
                                    printf(",\n(");
                                }
                                dumpRecord((byte*)getRow(cursor.currId),
                                           cursor.table->columns);
                                printf(")");
                            }
                            printf("\n\t%d records selected\n", 
                                   cursor.getNumberOfRecords());
                        } else { 
                            fprintf(stderr, "No records selected\n");
                        }
                    }
#ifdef THROW_EXCEPTION_ON_ERROR
                } catch(dbException const&) {}
#else
                } else { 
                    if (query.mutexLocked) { 
                        query.mutexLocked = false;
                        query.mutex.unlock();
                    }
                }
#endif
                ctx->catched = false;
                if (!modified || autocommit) { 
                    commit(); // release locks
                }
            } else { 
                error("No such table in database");
            }
            continue;
                
          case tkn_open:
            if (expect("database name", tkn_sconst)) { 
                char* databaseName = new char[strlen(buf)+1];
                strcpy(databaseName, buf);
                char* fileName = NULL;
                if ((tkn = scan()) == tkn_sconst) { 
                    fileName = buf;
                } else if (tkn != tkn_semi) { 
                    delete[] databaseName;
                    error("database file name expected");
                    continue;
                }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -