Пример #1
0
static int __may_fail
query_create_schema_impl (query_result *r, char *name, int strict)
{
  __returns_int;

  // make checks
  __precondition(NULL != r);
  schema *s = datastore_get_schema_by_name(name);
  parser_assert_err(QUERY_ERR_SCHEMA_EEXISTS, !(strict && s), name);

  // handle query
  if (s)
    return 0;

  __checked_call(NULL != (s = schema_create(name)));
  __checked_call(0 == datastore_add_schema(s),
    schema_destroy(s);
  );
Пример #2
0
/*
 * schema_fromascii - input a converted schema ASCII string into a schema
 *
 * - memory is allocated for the schema, application shall later call 
 *   schema_destroy to clean up
 * - assume the ascii string is produced by schema_toascii
 * - return a  pointer to the initialized schema if OK, NULL on error
 *
 */
schema_t *schema_fromascii(const char *asc_schema)
{
    int fieldind;
    char *buf, *saveptr;
    char *endian, *fieldnum, *name, *size, *offset, *type;
    schema_t *schema;

    if ((schema = schema_create(NULL)) == NULL) {
        fprintf(stderr, "schema_fromascii: cannot create schema stub\n");
        return NULL;
    }
    
    if ((buf = strdup(asc_schema)) == NULL) {
        perror("schema_fromascii: strdup");
        return NULL;
    }

    endian = (char *)strtok_r(buf, " ", &saveptr);
    if (strcmp(endian, "L") == 0) 
        schema->endian = little;
    else if (strcmp(endian, "B") == 0) 
        schema->endian = big;
    else {
        fprintf(stderr, "schema_fromascii: unknown endianness %s\n", endian);
        free(schema);
        return NULL;
    }
    
    fieldnum = (char *)strtok_r(NULL, " ", &saveptr);
    if (fieldnum == NULL) {
        fprintf(stderr, "schema_fromascii: missing fieldnum %s\n", asc_schema);
        free(schema);
        return NULL;
    }

    if (sscanf(fieldnum, "%d", &schema->fieldnum) != 1) {
        fprintf(stderr, "schema_fromascii: unknown fieldnum specifier %s\n",
                fieldnum);
    }
    
    /* allocate the field table */
    schema->field = (field_t *)malloc(schema->fieldnum * sizeof(field_t));
    if (schema->field == NULL) {
        perror("schema_fromascii: malloc field table");
        free(schema);
        return NULL;
    }

    for (fieldind = 0 ; fieldind < schema->fieldnum; fieldind++) {
        name = (char *)strtok_r((char *)NULL, " ", &saveptr);
        type = (char *)strtok_r((char *)NULL, " ", &saveptr); 
        size = (char *)strtok_r((char *)NULL, " ", &saveptr);
        offset = (char *)strtok_r((char *)NULL, " ", &saveptr);
        
        if ((name == NULL) || (type == NULL) ||
            (size == NULL) || (offset == NULL)) {
            fprintf(stderr, "schema_fromascii: incomplete ascii schema %s\n",
                    asc_schema);
            break;
        }
        
        if (sscanf(size, "%d", &schema->field[fieldind].size) != 1) {
            fprintf(stderr, "schema_fromascii: unknown size specifier %s\n",
                    size);
            break;
        }
        
        if (sscanf(offset, "%d", &schema->field[fieldind].offset) != 1) {
            fprintf(stderr, "schema_fromascii: unknown offset specifer %s\n",
                    offset);
            break;
        }
            

        if ((schema->field[fieldind].name = strdup(name)) == NULL) {
            perror("schema_fromascii: strdup field name");
            break;
        }
        
        if ((schema->field[fieldind].type = strdup(type)) == NULL) {
            perror("schema_fromascii: strdup field type");
            break;
        }
        
    }

    free(buf);  /* we need to free the memory */

    if (fieldind < schema->fieldnum) {
        /* 
           break out of the loop because of error 
           here is a trick to guarantee the proper behavior 
           of schema_destroy 
        */
        schema->fieldnum = fieldind; 
        schema_destroy(schema);
        return NULL;
    }


    return schema;
    
}
Пример #3
0
/*
 * returns a pointer to a schema, or NULL if fails
 */
static struct schema *schema_create_from_hash(uint64_t hash, const char *bucket_name) {
    struct schema *schema = NULL;
    char buf[1024];
    snprintf(buf, sizeof(buf), "%s/schemas/%016"PRIx64, bucket_name, hash);
    log_notice("read schema from file [%s]", buf);
    FILE *f = fopen(buf, "r");
    if (f == NULL) {
        // legacy file path
        snprintf(buf, sizeof(buf), "schemas/%016"PRIx64, hash);        
        log_notice("read schema from file [%s]", buf);
        f = fopen(buf, "r");
    }

    if (f == NULL) {
        log_notice("read schema failed");
        return NULL;
    }
    
    schema = schema_create();
    if (!schema) {
        log_error("can't create schema");
        goto fail;
    }

    while (fgets(buf, sizeof(buf), f)) {
        char *saveptr;
        char *token = strtok_r(buf, " \n\r\t", &saveptr);
        
        uint8_t is_primary_key = 0;
        uint8_t is_signed = 0;
        char *name = NULL;
        uint16_t nbits = 0;
                
        if (strcmp(token, "upgrade_to") == 0) {
            token = next_token(&saveptr);
            if (token == NULL)
                goto fail;
            if (sscanf(token, "%"SCNx64, &schema->upgrade_to) != 1)
                goto fail;
            if (schema->upgrade_to == 0)
                goto fail;
        }
        else {

            /* backward compat */
            if (strcmp(token, "field") == 0)
                token = next_token(&saveptr);

            while (token) {
                if (token[0] >= '1' && token[1] <= '9')
                    nbits = atoi(token);
                else if (strcmp(token, "primary_key") == 0)
                    is_primary_key = 1;
                else if (strcmp(token, "signed") == 0)
                    is_signed = 1;
                else if (token[0] == '[') { // field name
                    size_t len = strlen(token);
                    if (token[len - 1] == ']') {
                        token[len - 1] = '\0';
                        name = &token[1];
                        if (!is_valid_name(name))
                            goto fail;
                    }
                    else
                        goto fail;
                }
                else
                    goto fail;
                
                token = next_token(&saveptr);
            }

            int res = schema_field_add(schema, name, is_signed, nbits, is_primary_key);
            if (res != 0)
                goto fail;
        }
    }
    fclose(f);
    schema->hash = hash;
    return schema;

fail:
    fclose(f);
    if (schema)
        slab_free(schema);
    log_error("schema file %016"PRIx64" is invalid", hash);
    return NULL;
}