Beispiel #1
0
void test_class_end(void) {
    db_result_free(result);
    result = NULL;
    db_result_free(result2);
    result2 = NULL;
    CU_PASS("db_result_free");

    db_value_set_free(value_set);
    value_set = NULL;
    db_value_set_free(value_set2);
    value_set2 = NULL;
    CU_PASS("db_value_set_free");

    db_object_field_list_free(object_field_list);
    object_field_list = NULL;
    CU_PASS("db_object_field_list_free");
    CU_PASS("db_object_field_free");

    db_connection_free(connection);
    connection = NULL;
    CU_PASS("db_connection_free");

    db_backend_free(backend);
    backend = NULL;
    CU_PASS("db_backend_handle_free");
    CU_PASS("db_backend_free");
}
Beispiel #2
0
Datei: db.c Projekt: carnil/nodau
/* create a new note */
int db_new(char* search)
{
    /* search by name */
    sql_result *result;
    result = db_get("SELECT * FROM nodau WHERE name = '%s'",search);

    if (result) {
        /* there's already a note with that name, so error and return */
        if (result->num_rows) {
            printf("There is already a note called '%s'\n",search);
            db_result_free(result);
            return 1;
        }

        /* free the search result */
        db_result_free(result);
    }

    /* create the new entry */
    db_insert(search,"new entry");

    if (error_msg)
        printf("%s\n",error_msg);

    /* open for editing */
    return db_edit(search);
}
Beispiel #3
0
CWERROR db_cont_get_list(CW_DB_CONNECTION *db,
                         CW_CONTACT **clist,
                         CW_UINT32 *count)
{
    static const char query[] = "SELECT cid,sid,uid,name,mname,lname,addr,phone,mphone,fax,www,email,company,notes FROM contacts";

    CW_DB_RESULT       res;
	CW_DB_RESULT_ROW   *row;
	CW_CONTACT         *list = NULL;
	CW_UINT32          n, i = 0;
	CWERROR	           err = CW_ER_OK;

	if ((err = db_query(db, &res, query, sizeof(query)-1, NULL, 0)) != CW_ER_OK) {
        DEBUG_ERROR();
        db_result_free(&res);
        return err;
    }

    if ((n = *count = DB_RESULT_ROW_COUNT(res)) == 0) {
        db_result_free(&res);
        return CW_ER_OK;
    }

    if ((list = *clist = DLL_MALLOC(sizeof(CW_CONTACT) * n)) == NULL) {
		DEBUG_ERROR();
		db_result_free(&res);
		return CW_ER_MEMORY;
	}

	row = DB_RESULT_ROW_FIRST(res);
	do {
        list[i].cid = DB_RESULT_AS_INT64(row, 0);
        list[i].sid = (CW_UINT32)DB_RESULT_AS_INT64(row, 1);
        list[i].uid = (CW_UINT32)DB_RESULT_AS_INT64(row, 2);
        #define WSTRCPY(to, n) \
            if (wcscpy_s((to), DB_RESULT_AS_BLOB(row, (n)), sizeof((to))) == NULL) { \
                DEBUG_ERROR(); \
                DLL_FREE(list); \
                db_result_free(&res); \
                return CW_ER_INTERNAL; \
            }
        WSTRCPY(list[i].name, 3);
        WSTRCPY(list[i].mname, 4);
        WSTRCPY(list[i].lname, 5);
        WSTRCPY(list[i].addr, 6);
        WSTRCPY(list[i].phone, 7);
        WSTRCPY(list[i].mphone, 8);
        WSTRCPY(list[i].fax, 9);
        WSTRCPY(list[i].www, 10);
        WSTRCPY(list[i].email, 11);
        WSTRCPY(list[i].comp, 12);
        WSTRCPY(list[i].notes, 13);
        #undef WSTRCPY        
        ++i;
    } while (((row = DB_RESULT_ROW_NEXT(row)) != NULL) && (--n));

    db_result_free(&res);

    return CW_ER_OK;
}
Beispiel #4
0
CWERROR db_cont_get_by_id(CW_DB_CONNECTION *db,
                          CW_CONTACT *cont,
                          CW_BOOL *exists,
                          const CW_UINT32 sid,
                          const CW_UINT32 uid)
{
    static const char query[] = "SELECT cid,sid,uid,name,mname,lname,addr,phone,mphone,fax,www,email,company,notes FROM contacts WHERE sid=? AND uid=?";

    CW_DB_RESULT       res;
	CW_DB_RESULT_ROW   *row;
	CW_DB_VALUE        binds[2] = {{DB_INT64, (CW_INT64)sid},
                                   {DB_INT64, (CW_INT64)uid}};
	CWERROR	           err = CW_ER_OK;
	
	*exists = FALSE;

	if ((err = db_query(db, &res, query, sizeof(query)-1, &binds[0], 2)) != CW_ER_OK) {
        DEBUG_ERROR();
        db_result_free(&res);
        return err;
    }
    
    if (DB_RESULT_ROW_COUNT(res) == 0) {
        db_result_free(&res);
        return CW_ER_OK;
    }
    
    row = DB_RESULT_ROW_FIRST(res);
	
    cont->cid = DB_RESULT_AS_INT64(row, 0);
    cont->sid = (CW_UINT32)DB_RESULT_AS_INT64(row, 1);
    cont->uid = (CW_UINT32)DB_RESULT_AS_INT64(row, 2);
    #define WSTRCPY(to, n) \
        if (wcscpy_s((to), DB_RESULT_AS_BLOB(row, (n)), sizeof((to))) == NULL) { \
            DEBUG_ERROR(); \
            db_result_free(&res); \
            return CW_ER_INTERNAL; \
        }
    WSTRCPY(cont->name, 3);
    WSTRCPY(cont->mname, 4);
    WSTRCPY(cont->lname, 5);
    WSTRCPY(cont->addr, 6);
    WSTRCPY(cont->phone, 7);
    WSTRCPY(cont->mphone, 8);
    WSTRCPY(cont->fax, 9);
    WSTRCPY(cont->www, 10);
    WSTRCPY(cont->email, 11);
    WSTRCPY(cont->comp, 12);
    WSTRCPY(cont->notes, 13);
    #undef WSTRCPY
    
    *exists = TRUE;

    db_result_free(&res);
    
    return CW_ER_OK;   
}
Beispiel #5
0
Datei: db.c Projekt: carnil/nodau
/* list notes according to search criteria */
int db_list(char* search)
{
    sql_result *res;
    int i;
    char* pref = "match";

    /* if search is null, list all */
    if (search == NULL) {
        pref = "note";
        res = db_get("SELECT * FROM nodau");

        /* nothing there */
        if (res->num_rows == 0) {
            printf("No notes to list\n");
            db_result_free(res);
            return 0;
        }
    } else {
        /* first try a name search */
        res = db_get("SELECT * FROM nodau WHERE name LIKE '%%%s%%'",search);

        /* if there's nothing then try a time search */
        if (res->num_rows == 0) {
            unsigned int idate;
            db_result_free(res);
            /* at time */
            if (strncmp(search,"t@",2) == 0) {
                idate = db_getstamp(search+2);
                res = db_get("SELECT * FROM nodau WHERE date = %u", idate);
                /* after time */
            } else if (strncmp(search,"t+",2) == 0) {
                idate = db_getstamp(search+2);
                res = db_get("SELECT * FROM nodau WHERE date > %u", idate);
                /* before time */
            } else if (strncmp(search,"t-",2) == 0) {
                idate = db_getstamp(search+2);
                res = db_get("SELECT * FROM nodau WHERE date < %u", idate);
            }
        }
        /* nothing there */
        if (!res || !res->num_rows || !res->num_cols) {
            printf("No notes match '%s'\n",search);
            return 0;
        }
    }

    /* print the list */
    for (i=0; i<res->num_rows; i++) {
        printf("%s %d: %s\n",pref,i+1,res->data[COLUMN(i,COL_NAME)]);
    }

    /* free the result */
    db_result_free(res);

    return 0;
}
Beispiel #6
0
CWERROR db_reports_get_list(CW_DB_CONNECTION *db,
                            CW_REPORT **rlist,
                            CW_UINT32 *count)
{
	static const char query[] = "SELECT rid,sid,uid,datetime(add_dt,'localtime'),code FROM reports ORDER BY add_dt COLLATE NOCASE DESC";
	    
    CW_DB_RESULT       res;
	CW_DB_RESULT_ROW   *row;
	CW_REPORT          *list = NULL;
	CW_UINT32          n, i = 0;
	CWERROR	           err = CW_ER_OK;

	if ((err = db_query(db, &res, query, sizeof(query)-1, NULL, 0)) != CW_ER_OK) {
        DEBUG_ERROR();
        db_result_free(&res);
        return err;
    }

    if ((n = *count = DB_RESULT_ROW_COUNT(res)) == 0) {
        db_result_free(&res);
        return CW_ER_OK;
    }

    if ((list = *rlist = DLL_MALLOC(sizeof(CW_REPORT) * n)) == NULL) {
		DEBUG_ERROR();
		db_result_free(&res);
		return CW_ER_MEMORY;
	}

	row = DB_RESULT_ROW_FIRST(res);
	do {
        list[i].rid = DB_RESULT_AS_INT64(row, 0);
        list[i].pckt.rcpt_sid = (CW_UINT32)DB_RESULT_AS_INT64(row, 1);
        list[i].pckt.rcpt_uid = (CW_UINT32)DB_RESULT_AS_INT64(row, 2);
        if (strcpy_s(list[i].add_dt, DB_RESULT_AS_TEXT(row, 3), sizeof(list[i].add_dt)) == NULL) {
            DEBUG_ERROR();
            DLL_FREE(list);
            db_result_free(&res);
            return CW_ER_INTERNAL;
        }
	    list[i].pckt.code = (CW_UINT32)DB_RESULT_AS_INT64(row, 4);
        ++i;
    } while (((row = DB_RESULT_ROW_NEXT(row)) != NULL) && (--n));

    db_result_free(&res);

    return CW_ER_OK;
}
Beispiel #7
0
Datei: db.c Projekt: carnil/nodau
/* open an existing note */
int db_edit(char* search)
{
    char* date;
    char* name;
    char* text;
    char* crypt;
    int r;
    /* get the note by name */
    sql_result *result;
    result = db_get("SELECT * FROM nodau WHERE name = '%s'",search);

    /* nothing there */
    if (result->num_rows == 0) {
        db_result_free(result);
        if (config_read("edit_autocreate","false")) {
            printf("No notes match '%s'\n",search);
        } else {
            return db_new(search);
        }
        return 0;
    }

    /* get the data */
    date = db_gettime(result->data[COLUMN(0,COL_DATE)]);
    name = result->data[COLUMN(0,COL_NAME)];
    text = result->data[COLUMN(0,COL_TEXT)];
    crypt = result->data[COLUMN(0,COL_CRYPT)];

    /* get the passphrase if it's encrypted */
    if (!strcmp(crypt,"true")) {
        crypt = crypt_get_key();
        text = note_decrypt(text,crypt);
        if (!text)
            return 1;
    }

    /* edit the note */
    r = edit(name, date, text);

    /* free the result */
    db_result_free(result);

    return r;
}
Beispiel #8
0
void ListMgr_CloseReport(struct lmgr_report_t *p_iter)
{
    db_result_free(&p_iter->p_mgr->conn, &p_iter->select_result);

    if (p_iter->str_tab != NULL)
        MemFree(p_iter->str_tab);

    MemFree(p_iter->result);
    MemFree(p_iter);
}
Beispiel #9
0
Datei: db.c Projekt: carnil/nodau
/* encrypt an existing note, or create a new encrypted note */
int db_encrypt(char* search)
{
    /* search by name */
    sql_result *result;
    char* crypt;
    int r;
    result = db_get("SELECT * FROM nodau WHERE name = '%s'",search);

    /* there's already a note with that name */
    if (result->num_rows) {
        char* name;
        char* text;

        /* get the data */
        name = result->data[COLUMN(0,COL_NAME)];
        text = result->data[COLUMN(0,COL_TEXT)];
        crypt = result->data[COLUMN(0,COL_CRYPT)];

        /* encrypt it if it's not already */
        if (!strcmp(crypt,"false")) {
            crypt = crypt_get_key();
            r = db_update(name,text);
        } else {
            printf("Note '%s' is already encrypted\n",search);
        }
        db_result_free(result);
        return r;
    }

    /* free the search result */
    db_result_free(result);

    /* create the new entry */
    db_insert(search,"new entry");

    if (error_msg)
        fprintf(stderr,"%s\n",error_msg);

    crypt = crypt_get_key();
    /* open for editing */
    return db_edit(search);
}
Beispiel #10
0
Datei: db.c Projekt: carnil/nodau
/* decrypt an existing note or create a new encrypted note */
int db_decrypt(char* search)
{
    /* search by name */
    sql_result *result;
    int r;
    result = db_get("SELECT * FROM nodau WHERE name = '%s'",search);

    /* found the note */
    if (result->num_rows) {
        char* text;
        char* crypt;

        /* get the data */
        text = result->data[COLUMN(0,COL_TEXT)];
        crypt = result->data[COLUMN(0,COL_CRYPT)];

        /* decrypt it if it is encrypted */
        if (!strcmp(crypt,"true")) {
            char* t;
            crypt = crypt_get_key();
            t = note_decrypt(text,crypt);
            if (!t)
                return 1;
            free(crypt_key);
            crypt_key = NULL;
            r = db_update(search,t);
            db_result_free(result);
            return r;
        } else {
            printf("Note '%s' is not encrypted\n",search);
            db_result_free(result);
        }
        return 0;
    }

    printf("No notes matches '%s'\n",search);
    db_result_free(result);

    return 0;
}
Beispiel #11
0
Datei: db.c Projekt: carnil/nodau
/* show an existing note */
int db_show(char* search)
{
    char* date;
    char* name;
    char* text;
    char* crypt;
    /* get the note by name */
    sql_result *result;
    result = db_get("SELECT * FROM nodau WHERE name = '%s'",search);

    /* nothing there */
    if (result->num_rows == 0) {
        printf("No notes match '%s'\n",search);
        db_result_free(result);
        return 0;
    }

    /* get the data */
    date = db_gettime(result->data[COLUMN(0,COL_DATE)]);
    name = result->data[COLUMN(0,COL_NAME)];
    text = result->data[COLUMN(0,COL_TEXT)];
    crypt = result->data[COLUMN(0,COL_CRYPT)];

    /* get the passphrase if it's encrypted */
    if (!strcmp(crypt,"true")) {
        crypt = crypt_get_key();
        text = note_decrypt(text,crypt);
        if (!text)
            return 1;
    }

    /* display the note */
    printf("%s (%s):\n%s\n",name,date,text);

    /* free the result */
    db_result_free(result);

    return 0;
}
Beispiel #12
0
/**
 * \retval DB_NOT_EXISTS if the recovery table does not exist
 */
int ListMgr_RecovStatus( lmgr_t * p_mgr, lmgr_recov_stat_t * p_stats )
{
    int  rc, i;
    result_handle_t result;
    char * status[3];

    /* test if a RECOVERY table already exist, and contains entries */
    rc = db_exec_sql_quiet( &p_mgr->conn, "SELECT recov_status,COUNT(*),SUM(size) FROM "RECOV_TABLE
                            " GROUP BY recov_status", &result );
    if (rc)
        return rc;

    /* table exists, fill status tab */
    p_stats->total = 0;
    for (i = 0; i < RS_COUNT; i++ )
    {
        p_stats->status_count[i] = 0;
        p_stats->status_size[i] = 0;
    }

    while ( (rc = db_next_record( &p_mgr->conn, &result, status, 3 ))
            != DB_END_OF_LIST )
    {
        long long cnt;
        uint64_t sz;
        if (rc)
            return rc;

        cnt = str2bigint( status[1] );
        if ( cnt == -1LL)
            return DB_INVALID_ARG;

        sz = str2size(  status[2] );
        if ( sz == -1LL)
            return DB_INVALID_ARG;

        p_stats->total += cnt;

        if ( status[0] != NULL )
        {
            int idx = str2int( status[0] );
            if ((idx >= RS_COUNT) || (idx == -1) )
                return DB_REQUEST_FAILED;
            p_stats->status_count[idx] = cnt;
            p_stats->status_size[idx] = sz;
        }
    }

    db_result_free( &p_mgr->conn, &result );
    return 0;
}
Beispiel #13
0
int ListMgr_Exists(lmgr_t *p_mgr, const entry_id_t *p_id)
{
    GString        *req;
    int             rc;
    result_handle_t result;
    char           *str_count = NULL;
    DEF_PK(pk);
    int             retry_status;

    /* retrieve primary key */
    entry_id2pk(p_id, PTR_PK(pk));

    /* verify it exists in main table */
    req = g_string_new("SELECT id FROM " MAIN_TABLE " WHERE id=");
    g_string_append_printf(req, DPK, pk);

retry:
    /* execute the request (must return negative value on error) */
    rc = -db_exec_sql(&p_mgr->conn, req->str, &result);
    retry_status = lmgr_delayed_retry(p_mgr, -rc);
    if (retry_status == 1)
        goto retry;
    else if (retry_status == 2) {
        rc = -DB_RBH_SIG_SHUTDOWN;
        goto free_str;
    } else if (rc)
        goto free_str;

    rc = db_next_record(&p_mgr->conn, &result, &str_count, 1);
    if (rc == 0)
        rc = 1; /* return 1 if entry exists */
    else if (rc != DB_END_OF_LIST)
    {
        retry_status = lmgr_delayed_retry(p_mgr, -rc);
        if (retry_status == 1)
            goto retry;
        else if (retry_status == 2) {
            rc = -DB_RBH_SIG_SHUTDOWN;
            goto free_result;
        }
    }
    else
        rc = 0;

free_result:
    db_result_free(&p_mgr->conn, &result);

free_str:
    g_string_free(req, TRUE);
    return rc;
}
Beispiel #14
0
CWERROR db_outbox_get_by_id(CW_DB_CONNECTION *db,
                            CW_MSG_DESC *msg,
                            const CW_INT64 mid)
{
    static const char query[] = "SELECT mid,sid,uid,add_dt,msg_sz,file FROM outbox_mail WHERE mid=?";
    
    CW_DB_VALUE        bind = {DB_INT64, mid};
	CW_DB_RESULT       res;
	CW_DB_RESULT_ROW   *row;
	CW_UINT32          n, i = 0;
	CWERROR	           err = CW_ER_OK;

	if ((err = db_query(db, &res, query, sizeof(query)-1, &bind, 1)) != CW_ER_OK) {
        DEBUG_ERROR();
        db_result_free(&res);
        return err;
    }
	row = DB_RESULT_ROW_FIRST(res);
    
    msg->mid = DB_RESULT_AS_INT64(row, 0);
    msg->sid = (CW_UINT32)DB_RESULT_AS_INT64(row, 1);
    msg->uid = (CW_UINT32)DB_RESULT_AS_INT64(row, 2);
    if (strcpy_s(msg->add_dt, DB_RESULT_AS_TEXT(row, 3), sizeof(msg->add_dt)) == NULL) {
        DEBUG_ERROR();
        db_result_free(&res);
        return CW_ER_INTERNAL;
    }
	msg->sz = (CW_UINT64)DB_RESULT_AS_INT64(row, 4);
	if (strcpy_s(msg->file, DB_RESULT_AS_TEXT(row, 5), sizeof(msg->file)) == NULL) {
        DEBUG_ERROR();
        db_result_free(&res);
        return CW_ER_INTERNAL;
    }

    db_result_free(&res);

    return CW_ER_OK;
}
Beispiel #15
0
int lmgr_get_var(db_conn_t *pconn, const char *varname, char *value, int bufsize)
{
    int             rc;
    result_handle_t result;
    char           *str_val = NULL;
    GString        *req = NULL;

    if (!varname || !value)
        return DB_INVALID_ARG;

    req = g_string_new("SELECT value FROM "VAR_TABLE" WHERE varname=");
    g_string_append_printf(req, "'%s'", varname);

    /* execute the request */
    rc = db_exec_sql(pconn, req->str, &result);
    if (rc)
        goto free_str;

    rc = db_next_record(pconn, &result, &str_val, 1);

    if (rc == DB_END_OF_LIST)
        rc = DB_NOT_EXISTS;

    if (rc)
        goto free_res;

    if (str_val == NULL)
    {
        rc = DB_REQUEST_FAILED;
        goto free_res;
    }

    /* copy the result */
    if (strlen(str_val) >= bufsize)
    {
        rc = DB_BUFFER_TOO_SMALL;
    }
    else
    {
        strcpy(value, str_val);
        rc = DB_SUCCESS;
    }

free_res:
    db_result_free(pconn, &result);
free_str:
    g_string_free(req, TRUE);
    return rc;
}
Beispiel #16
0
/* Retrieve the FID from the database given the parent FID and the file name. */
int ListMgr_Get_FID_from_Path( lmgr_t * p_mgr, const entry_id_t * parent_fid,
                               const char *name, entry_id_t * fid)
{
    result_handle_t result;
    GString        *req = NULL;
    char            escaped[RBH_NAME_MAX*2+1];
    DEF_PK(pk);
    int rc;
    char            *str_info[1];
    int             retry_status;

    entry_id2pk(parent_fid, PTR_PK(pk));

    db_escape_string(&p_mgr->conn, escaped, sizeof(escaped), name);

    req = g_string_new("SELECT id FROM "DNAMES_TABLE" WHERE pkn=");
    g_string_append_printf(req, HNAME_FMT, pk, escaped);

retry:
    rc = db_exec_sql(&p_mgr->conn, req->str, &result);
    retry_status = lmgr_delayed_retry(p_mgr, rc);
    if (retry_status == 1)
        goto retry;
    else if (retry_status == 2) {
        rc = DB_RBH_SIG_SHUTDOWN;
        goto free_str;
    } else if (rc)
        goto free_str;

    rc = db_next_record(&p_mgr->conn, &result, str_info, 1);

    retry_status = lmgr_delayed_retry(p_mgr, rc);
    if (retry_status == 1)
        goto retry;
    else if (retry_status == 2) {
        rc = DB_RBH_SIG_SHUTDOWN;
        goto free_res;
    } else if (rc != DB_SUCCESS)
        goto free_res;

    rc = pk2entry_id(p_mgr, str_info[0], fid);

free_res:
    db_result_free(&p_mgr->conn, &result);
free_str:
    g_string_free(req, TRUE);
    return rc;
}
Beispiel #17
0
CWERROR db_inbox_get_list(CW_DB_CONNECTION *db,
                          CW_MSG_DESC **dlist,
                          CW_UINT32 *count)
{
	static const char query[] = "SELECT mid,sid,uid,datetime(add_dt,'localtime'),read_flag,msg_sz,file FROM inbox_mail ORDER BY add_dt COLLATE NOCASE DESC";

	CW_DB_RESULT       res;
	CW_DB_RESULT_ROW   *row;
	CW_MSG_DESC        *list = NULL;
	CW_UINT32          n, i = 0;
	CWERROR	           err = CW_ER_OK;

	if ((err = db_query(db, &res, query, sizeof(query)-1, NULL, 0)) != CW_ER_OK) {
        DEBUG_ERROR();
        db_result_free(&res);
        return err;
    }

    if ((n = *count = DB_RESULT_ROW_COUNT(res)) == 0) {
        db_result_free(&res);
        return CW_ER_OK;    
    }
    
    if ((list = *dlist = DLL_MALLOC(sizeof(CW_MSG_DESC) * n)) == NULL) {
		DEBUG_ERROR();
		db_result_free(&res);
		return CW_ER_MEMORY;
	}
	
	row = DB_RESULT_ROW_FIRST(res);
	do {
        list[i].mid = DB_RESULT_AS_INT64(row, 0);
        list[i].sid = (CW_UINT32)DB_RESULT_AS_INT64(row, 1);
        list[i].uid = (CW_UINT32)DB_RESULT_AS_INT64(row, 2);
        if (strcpy_s(list[i].add_dt, DB_RESULT_AS_TEXT(row, 3), sizeof(list[i].add_dt)) == NULL) {
            DEBUG_ERROR();
            DLL_FREE(list);
            db_result_free(&res);
            return CW_ER_INTERNAL;
        }
        list[i].read_flag = ((strcmp(DB_RESULT_AS_TEXT(row, 4), "Y") == 0) ? TRUE : FALSE);
	    list[i].sz = (CW_UINT64)DB_RESULT_AS_INT64(row, 5);
	    if (strcpy_s(list[i].file, DB_RESULT_AS_TEXT(row, 6), sizeof(list[i].file)) == NULL) {
            DEBUG_ERROR();
            DLL_FREE(list);
            db_result_free(&res);
            return CW_ER_INTERNAL;
        }
        ++i;  
    } while (((row = DB_RESULT_ROW_NEXT(row)) != NULL) && (--n));

    db_result_free(&res);
	
    return CW_ER_OK;
}
Beispiel #18
0
/* check that validator is matching for a given entry */
int ListMgr_CheckStripe( lmgr_t * p_mgr, const entry_id_t * p_id )
{
    char           query[1024];
    char          *res;
    result_handle_t result;
    int            rc = DB_SUCCESS;
    DEF_PK(pk);

    rc = entry_id2pk( p_mgr, p_id, FALSE, PTR_PK(pk) );
    if (rc)
        return rc;

    sprintf( query, "SELECT validator FROM " STRIPE_INFO_TABLE " WHERE id="DPK, pk );

    rc = db_exec_sql( &p_mgr->conn, query, &result );
    if ( rc )
        goto out;

    rc = db_next_record( &p_mgr->conn, &result, &res, 1 );

    if ( rc == DB_END_OF_LIST )
        rc = DB_NOT_EXISTS;

    if ( rc )
        goto res_free;

    if ( res == NULL )
    {
        rc = DB_ATTR_MISSING;
        goto res_free;
    }

    if ( atoi( res ) != VALID(p_id) )
    {
        delete_stipe_info( p_mgr, pk );
        rc = DB_OUT_OF_DATE;
    }
    else
        rc = DB_SUCCESS;

  res_free:
    db_result_free( &p_mgr->conn, &result );
  out:
    return rc;
}
Beispiel #19
0
Datei: db.c Projekt: carnil/nodau
/* delete notes */
int db_del(char* search)
{
    char sql[512];
    unsigned int date = 0;
    /* try a name search */
    sql_result *result;
    result = db_get("SELECT * FROM nodau WHERE name = '%s'",search);

    /* TODO: request passphrase before deleting encrypted notes?
     * File can be deleted without the passphrase anyway,
     * or the db can be edited with sqlite3 shell, so is there a
     * point to protecting from deletion? */

    /* if we got something, delete it */
    if (result->num_rows) {
        sprintf(sql, "DELETE FROM nodau WHERE name = '%s'", search);
        /* or try a delete by time at */
    } else if (strncmp(search,"t@",2) == 0) {
        date = db_getstamp(search+2);
        sprintf(sql, "DELETE FROM nodau WHERE date = %u", date);
        /* or try a delete by later than */
    } else if (strncmp(search,"t+",2) == 0) {
        date = db_getstamp(search+2);
        sprintf(sql, "DELETE FROM nodau WHERE date > %u", date);
        /* or try a delete by earlier than */
    } else if (strncmp(search,"t-",2) == 0) {
        date = db_getstamp(search+2);
        sprintf(sql, "DELETE FROM nodau WHERE date < %u", date);
        /* or print an error */
    } else {
        printf("No notes matches '%s'\n",search);
        return 0;
    }

    /* run the statement */
    sqlite3_exec(db, sql, NULL, 0, &error_msg);

    /* free the earlier result */
    db_result_free(result);

    return 0;
}
Beispiel #20
0
int ListMgr_Exists( lmgr_t * p_mgr, const entry_id_t * p_id )
{
    char           request[4096];
    int            rc;
    result_handle_t result;
    char          *str_count = NULL;
    DEF_PK( pk );

    /* retrieve primary key */
    entry_id2pk(p_id, PTR_PK(pk));

    /* verify it exists in main table */

    sprintf( request, "SELECT id FROM " MAIN_TABLE " WHERE id="DPK, pk );

retry:
    /* execute the request */
    rc = db_exec_sql(&p_mgr->conn, request, &result);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc)
        return -rc;

    rc = db_next_record( &p_mgr->conn, &result, &str_count, 1 );
    if (rc == 0)
        rc = 1;
    else if (rc != DB_END_OF_LIST)
    {
        if (lmgr_delayed_retry(p_mgr, rc))
            goto retry;
        rc = -rc;
    }
    else
        rc = 0;

    db_result_free( &p_mgr->conn, &result );
    return rc;
}
Beispiel #21
0
/* Retrieve the FID from the database given the parent FID and the file name. */
int ListMgr_Get_FID_from_Path( lmgr_t * p_mgr, const entry_id_t * parent_fid,
                               const char *name, entry_id_t * fid)
{
    result_handle_t result;
    char           query[4096];
    char           escaped[RBH_NAME_MAX*2];
    DEF_PK(pk);
    int rc;
    char            *str_info[1];

    entry_id2pk(parent_fid, PTR_PK(pk));

    db_escape_string(&p_mgr->conn, escaped, RBH_NAME_MAX*2, name);

    sprintf(query, "SELECT id FROM "DNAMES_TABLE" WHERE pkn="HNAME_FMT,
            pk, escaped);

retry:
    rc = db_exec_sql(&p_mgr->conn, query, &result);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc)
        return rc;

    rc = db_next_record( &p_mgr->conn, &result, str_info, 1 );

    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc != DB_SUCCESS)
        goto free_res;

    rc = pk2entry_id(p_mgr, str_info[0], fid);

  free_res:
    db_result_free( &p_mgr->conn, &result );
    return rc;
}
Beispiel #22
0
int ListMgr_EntryCount(lmgr_t * p_mgr, uint64_t *count)
{
    int            rc;
    result_handle_t result;
    char          *str_count = NULL;

    /* execute the request */
retry:
    rc = db_exec_sql( &p_mgr->conn, "SELECT COUNT(*) FROM " MAIN_TABLE, &result );
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc)
        return rc;

    rc = db_next_record( &p_mgr->conn, &result, &str_count, 1 );
    if (rc)
        return rc;

    if ( sscanf( str_count, "%"SCNu64, count ) != 1 )
        rc = DB_REQUEST_FAILED;

    db_result_free( &p_mgr->conn, &result );
    return rc;
}
void ListMgr_CloseIterator( struct lmgr_iterator_t *p_iter )
{
    db_result_free( &p_iter->p_mgr->conn, &p_iter->select_result );
    MemFree( p_iter );
}
Beispiel #24
0
int get_stripe_info( lmgr_t * p_mgr, PK_ARG_T pk, stripe_info_t * p_stripe_info,
                     stripe_items_t * p_items )
{
    char           query[1024];
    char          *res[3];
    result_handle_t result;
    int            i;
    int            rc = DB_SUCCESS;

    /* retrieve basic stripe info */
    sprintf( query,
             "SELECT stripe_count, stripe_size, pool_name FROM " STRIPE_INFO_TABLE " WHERE id="DPK,
             pk );

    rc = db_exec_sql( &p_mgr->conn, query, &result );
    if ( rc )
        goto out;

    rc = db_next_record( &p_mgr->conn, &result, res, 3 );
    if ( rc == DB_END_OF_LIST )
        rc = DB_NOT_EXISTS;
    if ( rc )
        goto res_free;

    if ( res[0] == NULL || res[1] == NULL || res[2] == NULL )
    {
        rc = DB_ATTR_MISSING;
        goto res_free;
    }

    p_stripe_info->stripe_count = atoi( res[0] );
    p_stripe_info->stripe_size = atoi( res[1] );
    strncpy( p_stripe_info->pool_name, res[2], MAX_POOL_LEN );

    db_result_free( &p_mgr->conn, &result );

    if ( p_items )
    {
        /* retrieve stripe list */
        sprintf( query, "SELECT storage_item FROM " STRIPE_ITEMS_TABLE " WHERE id="DPK, pk );

        rc = db_exec_sql( &p_mgr->conn, query, &result );
        if ( rc )
            goto out;

        if ( p_stripe_info->stripe_count != db_result_nb_records( &p_mgr->conn, &result ) )
        {
            DisplayLog( LVL_MAJOR, LISTMGR_TAG,
                        "Warning: the number of stripe items (%d) doesn't match stripe count (%u)! (Pk="DPK")",
                        db_result_nb_records( &p_mgr->conn, &result ), p_stripe_info->stripe_count, pk );
        }
        p_items->count = db_result_nb_records( &p_mgr->conn, &result );

        if ( p_items->count > 0 )
        {

            /* allocate stripe array */
            p_items->stripe_units = MemCalloc( p_items->count, sizeof( storage_unit_id_t ) );

            if ( !p_items->stripe_units )
            {
                rc = DB_NO_MEMORY;
                goto res_free;
            }

            /* fill stripe units */
            for ( i = 0; i < p_items->count; i++ )
            {
                rc = db_next_record( &p_mgr->conn, &result, res, 1 );
                if ( rc )
                    goto stripe_free;

                if ( res[0] == NULL )
                {
                    rc = DB_ATTR_MISSING;
                    goto stripe_free;
                }

                p_items->stripe_units[i] = atoi( res[0] );
            }
        }
        else
            p_items->stripe_units = NULL;

        /* last query result must be freed */
        rc = DB_SUCCESS;
        goto res_free;
    }

    /* nothing to free */
    return DB_SUCCESS;

    stripe_free:
    MemFree( p_items->stripe_units );
    p_items->stripe_units = NULL;
    p_items->count = 0;
    p_stripe_info->stripe_count = 0;
    res_free:
    db_result_free( &p_mgr->conn, &result );
    out:
    return rc;
}
Beispiel #25
0
/** retrieve directory attributes (nbr of entries, avg size of entries)*/
int listmgr_get_dirattrs( lmgr_t * p_mgr, PK_ARG_T dir_pk, attr_set_t * p_attrs )
{
    GString         *req;
    result_handle_t  result;
    char            *str_info[1];
    int              rc = 0;
    int              tmp_val;
    long long        tmp_long;

    if (ATTR_MASK_TEST(p_attrs, type) &&
        (strcmp(ATTR(p_attrs, type), STR_TYPE_DIR) != 0))
    {
        DisplayLog(LVL_FULL, LISTMGR_TAG,
                   "Type='%s' != 'dir' => unsetting dirattrs in attr mask",
                   ATTR(p_attrs, type));
        p_attrs->attr_mask = attr_mask_and_not(&p_attrs->attr_mask, &dir_attr_set);
        return 0;
    }

    req = g_string_new(NULL);

    /* get child entry count from DNAMES_TABLE */
    if (ATTR_MASK_TEST(p_attrs, dircount))
    {
        g_string_printf(req, "SELECT %s FROM "DNAMES_TABLE" WHERE parent_id="DPK,
                        dirattr2str(ATTR_INDEX_dircount), dir_pk);

        rc = db_exec_sql(&p_mgr->conn, req->str, &result);
        if (rc)
            goto free_str;

        rc = db_next_record(&p_mgr->conn, &result, str_info, 1);
        if (rc == DB_END_OF_LIST)
        {
            ATTR_MASK_UNSET(p_attrs, dircount);
            rc = DB_SUCCESS;
        }
        else if (rc == DB_SUCCESS)
        {
            if (str_info[0] == NULL)
                /* count(*) should at least return 0 */
                rc = DB_REQUEST_FAILED;
            else
            {
                tmp_val = str2int(str_info[0]);
                if (tmp_val != -1)
                {
                    ATTR_MASK_SET(p_attrs, dircount);
                    ATTR(p_attrs, dircount) = tmp_val;
                    rc = DB_SUCCESS;
                }
                else
                    /* invalid output format */
                    rc = DB_REQUEST_FAILED;
            }
        }
        db_result_free(&p_mgr->conn, &result);
        if (rc)
            goto free_str;
    }

    /* get avgsize of child entries from MAIN_TABLE */
    if (ATTR_MASK_TEST(p_attrs, avgsize))
    {
        g_string_printf(req, "SELECT %s FROM "MAIN_TABLE" m, "DNAMES_TABLE" d"
                        " WHERE m.id = d.id and type='file' and d.parent_id="DPK,
                        dirattr2str(ATTR_INDEX_avgsize), dir_pk);

        rc = db_exec_sql(&p_mgr->conn, req->str, &result);
        if (rc)
            goto free_str;

        rc = db_next_record(&p_mgr->conn, &result, str_info, 1);
        if (rc == DB_END_OF_LIST)
            ATTR_MASK_UNSET(p_attrs, avgsize);
        else if (rc == DB_SUCCESS)
        {
            if (str_info[0] == NULL)
            {
                /* NULL if no entry matches the criteria */
                ATTR_MASK_UNSET(p_attrs, avgsize);
                rc = DB_SUCCESS;
            }
            else
            {
                tmp_long = str2bigint(str_info[0]);
                if (tmp_long != -1LL)
                {
                    ATTR_MASK_SET(p_attrs, avgsize);
                    ATTR(p_attrs, avgsize) = tmp_long;
                    rc = DB_SUCCESS;
                }
                else
                    /* invalid output format */
                    rc = DB_REQUEST_FAILED;
            }
        }
        db_result_free(&p_mgr->conn, &result);
    }

free_str:
    g_string_free(req, TRUE);
    return rc;
}
Beispiel #26
0
/**
 *  Retrieve entry attributes from its primary key
 */
int listmgr_get_by_pk( lmgr_t * p_mgr, PK_ARG_T pk, attr_set_t * p_info )
{
    int             rc;
    char           *first_table = NULL;
    GString        *req, *from;
    /* attribute count is up to 1 per bit (8 per byte).
     * x2 for bullet proofing */
    char           *result_tab[2*8*sizeof(p_info->attr_mask)];
    result_handle_t result;
    bool            checkmain   = true;
    int             main_count  = 0,
                    annex_count = 0,
                    name_count  = 0;
    attr_mask_t     gen = gen_fields(p_info->attr_mask);

    if (p_info == NULL)
        return 0;

    /* init entry info */
    memset(&p_info->attr_values, 0, sizeof(entry_info_t));
    req = g_string_new("SELECT ");
    from = g_string_new(" FROM ");

    /* retrieve source info for generated fields (only about std fields)*/
    add_source_fields_for_gen(&p_info->attr_mask.std);

    /* don't get fields that are not in main, names, annex, stripe...
     * This allows the caller to set all bits 'on' to get everything.
     * Note: this also clear generated fields. They will be restored after.
     */
    supported_bits_only(&p_info->attr_mask);

    /* get info from main table (if asked) */
    main_count = attrmask2fieldlist(req, p_info->attr_mask, T_MAIN, "", "", 0);
    if (main_count < 0)
    {
        rc = -main_count;
        goto free_str;
    }
    else if (main_count > 0)
    {
        checkmain = false;
        first_table = MAIN_TABLE;
        g_string_append(from, MAIN_TABLE);
    }

    annex_count = attrmask2fieldlist(req, p_info->attr_mask, T_ANNEX, "", "",
                                     first_table != NULL ? AOF_LEADING_SEP : 0);
    if (annex_count < 0)
    {
        rc = -annex_count;
        goto free_str;
    }
    else if (annex_count > 0)
    {
        if (first_table != NULL)
            g_string_append_printf(from, " LEFT JOIN "ANNEX_TABLE" ON %s.id="
                                   ANNEX_TABLE".id", first_table);
        else
        {
            first_table = ANNEX_TABLE;
            g_string_append(from, ANNEX_TABLE);
        }
    }

    name_count = attrmask2fieldlist(req, p_info->attr_mask, T_DNAMES, "", "",
                                    first_table != NULL ? AOF_LEADING_SEP : 0);
    if (name_count < 0)
    {
        rc = -name_count;
        goto free_str;
    }
    else if (name_count > 0)
    {
        if (first_table)
            /* it's OK to JOIN with NAMES table here even if there are multiple paths,
             * as we only take one result record. The important thing is to return
             * consistent values for parent_id, name and fullpath. */
            g_string_append_printf(from, " LEFT JOIN "DNAMES_TABLE" ON %s.id="
                                   DNAMES_TABLE".id", first_table);
        else
        {
            first_table = DNAMES_TABLE;
            g_string_append(from, DNAMES_TABLE);
        }
    }

    if (first_table != NULL)
    {
        int shift = 0;

        g_string_append_printf(req, "%s WHERE %s.id="DPK, from->str,
                               first_table, pk);

        rc = db_exec_sql(&p_mgr->conn, req->str, &result);
        if (rc)
            goto free_str;

        rc = db_next_record(&p_mgr->conn, &result, result_tab,
                            main_count + annex_count + name_count);
        /* END_OF_LIST means it does not exist */
        if (rc == DB_END_OF_LIST)
        {
            clean_std_table_bits(&p_info->attr_mask);

            /* not found, but did not check MAIN yet */
            if (checkmain)
                goto next_table;

            rc = DB_NOT_EXISTS;
        }
        if (rc)
            goto free_res;

        /* set info from result */
        if (main_count)
        {
            rc = result2attrset(T_MAIN, result_tab + shift, main_count, p_info);
            shift += main_count;
            if (rc)
                goto free_res;
        }
        if (annex_count)
        {
            rc = result2attrset(T_ANNEX, result_tab + shift, annex_count,
                                p_info);
            shift += annex_count;
            if (rc)
                goto free_res;
        }
        if (name_count)
        {
            rc = result2attrset(T_DNAMES, result_tab + shift, name_count,
                                p_info);
            shift += name_count;
            if (rc)
                goto free_res;
        }

next_table:
        db_result_free(&p_mgr->conn, &result);
    }

    /* remove stripe info if it is not a file */
    if (stripe_fields(p_info->attr_mask) && ATTR_MASK_TEST(p_info, type)
        && strcmp(ATTR(p_info, type), STR_TYPE_FILE) != 0)
    {
        p_info->attr_mask = attr_mask_and_not(&p_info->attr_mask, &stripe_attr_set);
    }

    /* get stripe info if asked */
#ifdef _LUSTRE
    if (stripe_fields(p_info->attr_mask))
    {
        rc = get_stripe_info(p_mgr, pk, &ATTR(p_info, stripe_info),
                             ATTR_MASK_TEST(p_info, stripe_items)?
                                &ATTR(p_info, stripe_items) : NULL);
        if (rc == DB_ATTR_MISSING || rc == DB_NOT_EXISTS)
        {
            /* stripe info is in std mask */
            p_info->attr_mask.std &= ~ATTR_MASK_stripe_info;

            if (ATTR_MASK_TEST(p_info, stripe_items))
                p_info->attr_mask.std &= ~ATTR_MASK_stripe_items;
        }
        else if (rc)
            goto free_str;
        else
            checkmain = false; /* entry exists */
    }
#else
    /* POSIX: always clean stripe bits */
    p_info->attr_mask = attr_mask_and_not(&p_info->attr_mask, &stripe_attr_set);
#endif

    /* special field dircount */
    if (dirattr_fields(p_info->attr_mask))
    {
        if (listmgr_get_dirattrs(p_mgr, pk, p_info))
        {
            DisplayLog(LVL_MAJOR, LISTMGR_TAG, "listmgr_get_dirattrs failed for "DPK, pk);
            p_info->attr_mask = attr_mask_and_not(&p_info->attr_mask, &dir_attr_set);
        }
    }

    if (checkmain)
    {
        /* verify it exists in main table */
        g_string_printf(req, "SELECT id FROM " MAIN_TABLE " WHERE id="DPK, pk);

        /* execute the request */
        rc = db_exec_sql(&p_mgr->conn, req->str, &result);
        if (rc)
            goto free_str;

        rc = db_next_record(&p_mgr->conn, &result, result_tab, 1);
        db_result_free(&p_mgr->conn, &result);
        if (rc)
        {
            rc = DB_NOT_EXISTS;
            goto free_str;
        }
    }

    /* restore generated fields in attr mask */
    p_info->attr_mask = attr_mask_or(&p_info->attr_mask, &gen);
    /* generate them */
    generate_fields(p_info);

    /* update operation stats */
    p_mgr->nbop[OPIDX_GET]++;

    rc = DB_SUCCESS;
    goto free_str;

  free_res:
    db_result_free(&p_mgr->conn, &result);
  free_str:
    g_string_free(req, TRUE);
    g_string_free(from, TRUE);
    return rc;
} /* listmgr_get_by_pk */
Beispiel #27
0
/**
 * Get the list of children of a given parent (or list of parents).
 * \param parent_list       [in]  list of parents to get the child of
 * \param parent_count      [in]  number of ids in parent list
 * \param attr_mask         [in]  required attributes for children
 * \param child_id_list     [out] ptr to array of child ids
 * \param child_attr_list   [out] ptr to array of child attrs
 * \param child_count       [out] number of returned children
 */
int ListMgr_GetChild(lmgr_t *p_mgr, const lmgr_filter_t *p_filter,
                     const wagon_t *parent_list, unsigned int parent_count,
                     attr_mask_t attr_mask,
                     wagon_t **child_id_list, attr_set_t **child_attr_list,
                     unsigned int *child_count)
{
    result_handle_t result;
    char *path = NULL;
    int path_len;
    int                rc, i;
    GString           *req = NULL;
    GString           *fields = NULL;
    GString           *from = NULL;
    GString           *where = NULL;
    struct field_count field_cnt = {0};
    struct field_count filter_cnt = {0};
    table_enum         query_tab = T_DNAMES;
    bool               distinct = false;
    int                retry_status;

    /* XXX: querying children from several parent cannot work, since
     * we need to get the paths of the children. Or we could do a
     * lookup into parent_list to find the right one. In the meantime,
     * try not to mess up the code. */
    if (unlikely(parent_count != 1))
        RBH_BUG("cannot get children for several parent simultaneously");

    /* always request for name to build fullpath in wagon */
    attr_mask_set_index(&attr_mask, ATTR_INDEX_name);

    fields = g_string_new(NULL);

    /* append fields for all tables */
    if (!attr_mask_is_null(attr_mask))
    {
        /* retrieve source info for generated fields */
        add_source_fields_for_gen(&attr_mask.std);

        field_cnt.nb_names = attrmask2fieldlist(fields, attr_mask, T_DNAMES,
                                                DNAMES_TABLE".", "",
                                                AOF_LEADING_SEP);

        field_cnt.nb_main = attrmask2fieldlist(fields, attr_mask, T_MAIN,
                                               MAIN_TABLE".", "",
                                               AOF_LEADING_SEP);

        field_cnt.nb_annex = attrmask2fieldlist(fields, attr_mask, T_ANNEX,
                                                ANNEX_TABLE".", "",
                                                AOF_LEADING_SEP);
    }
    else
    {
        /* no returned attrs */
        if (child_attr_list != NULL)
            *child_attr_list = NULL;
    }

    where = g_string_new(NULL);

    /* starts with condition on parent */
    rc = append_parent_cond(p_mgr, where, parent_list, parent_count, DNAMES_TABLE".");
    if (rc != DB_SUCCESS)
        goto free_str;

    /* check filters on other tables */
    if (!no_filter(p_filter))
    {
        if (unlikely(dir_filter(p_mgr, NULL, p_filter, NULL, NULL) != FILTERDIR_NONE))
        {
            DisplayLog(LVL_MAJOR, LISTMGR_TAG, "Directory filter not supported in %s()", __func__);
            rc = DB_NOT_SUPPORTED;
            goto free_str;
        }
        else if (unlikely(func_filter(p_mgr, NULL, p_filter, T_MAIN, 0)))
        {
            DisplayLog(LVL_MAJOR, LISTMGR_TAG, "Function filter not supported in %s()", __func__);
            rc = DB_NOT_SUPPORTED;
            goto free_str;
        }

        /* There is always a filter on T_DNAMES, which is the parent condition.
         * Look for optional filters.
         */
        filter_where(p_mgr, p_filter, &filter_cnt, where,
                     AOF_LEADING_SEP | AOF_SKIP_NAME);
        /** @FIXME process other filters on NAMES */
    }

    from = g_string_new(DNAMES_TABLE);

    /* add filter_count + field_count to build the FROM clause.
     * Preserve field count which is needed to interpret the result.
     */
    filter_cnt.nb_main += field_cnt.nb_main;
    filter_cnt.nb_annex += field_cnt.nb_annex;
    filter_cnt.nb_names += field_cnt.nb_names;
    /* query tab is DNAMES, skip_name=true, is_first_tab=T_DNAMES */
    filter_from(p_mgr, &filter_cnt, from, &query_tab, &distinct,
                AOF_LEADING_SEP | AOF_SKIP_NAME);

    /* request is always on the DNAMES table (which contains [parent_id, id] relationship */
    if (distinct)
        req = g_string_new("SELECT DISTINCT("DNAMES_TABLE".id) as id");
    else
        req = g_string_new("SELECT "DNAMES_TABLE".id as id");

    /* build the whole request */
    g_string_append_printf(req, "%s FROM %s WHERE %s", fields->str, from->str, where->str);

retry:
    rc = db_exec_sql(&p_mgr->conn, req->str, &result);
    retry_status = lmgr_delayed_retry(p_mgr, rc);
    if (retry_status == 1)
        goto retry;
    else if (retry_status == 2) {
        rc = DB_RBH_SIG_SHUTDOWN;
        goto free_str;
    } else if (rc)
        goto free_str;

    /* copy result to output structures */
    *child_count = db_result_nb_records(&p_mgr->conn, &result);

    /* allocate entry_id array */
    *child_id_list = MemCalloc(*child_count, sizeof(wagon_t));
    if (*child_id_list == NULL)
    {
        rc = DB_NO_MEMORY;
        goto free_str;
    }

    if (child_attr_list)
    {
        *child_attr_list = MemCalloc(*child_count, sizeof(attr_set_t));
        if (*child_attr_list == NULL)
        {
            rc = DB_NO_MEMORY;
            goto array_free;
        }
    }

    /* Allocate a string long enough to contain the parent path and a
     * child name. */
    path_len = strlen(parent_list[0].fullname) + RBH_NAME_MAX + 2;
    path = malloc(path_len);
    if (!path) {
        DisplayLog(LVL_MAJOR, LISTMGR_TAG, "Can't alloc enough memory (%d bytes)",
                    path_len);
        rc = DB_NO_MEMORY;
        goto array_free;
    }

    for (i = 0; i < *child_count; i++)
    {
        char *res[128]; /* 128 fields per record is large enough */

        rc = db_next_record(&p_mgr->conn, &result, res, sizeof(res)/sizeof(*res));
        if (rc)
            goto array_free;

        /* copy id to array */
        pk2entry_id(p_mgr, res[0], &((*child_id_list)[i].id));

        /* copy attributes to array */
        if (child_attr_list)
        {
            unsigned int shift = 1; /* first was NAMES.id */

            (*child_attr_list)[i].attr_mask = attr_mask;

            /* first id, then dnames attrs, then main attrs, then annex attrs */
            if (field_cnt.nb_names > 0)
            {
                /* shift of 1 for id */
                rc = result2attrset(T_DNAMES, res + shift, field_cnt.nb_names, &((*child_attr_list)[i]));
                if (rc)
                    goto array_free;
                shift += field_cnt.nb_names;
            }

            if (field_cnt.nb_main > 0)
            {
                /* first id, then main attrs, then annex attrs */
                /* shift of 1 for id */
                rc = result2attrset(T_MAIN, res + shift, field_cnt.nb_main, &((*child_attr_list)[i]));
                if (rc)
                    goto array_free;
                shift += field_cnt.nb_main;
            }

            if (field_cnt.nb_annex > 0)
            {
                /* shift of main_attrs count */
                rc = result2attrset(T_ANNEX, res + shift, field_cnt.nb_annex,
                                     &((*child_attr_list)[i]));
                if (rc)
                    goto array_free;
                shift += field_cnt.nb_annex;
            }

#ifdef _LUSTRE
            if (stripe_fields(attr_mask))
            {
                if (get_stripe_info(p_mgr, res[0], &ATTR(&(*child_attr_list)[i], stripe_info),
                                     &ATTR(&(*child_attr_list)[i], stripe_items)))
                {
                    ATTR_MASK_UNSET(&(*child_attr_list)[i], stripe_info);
                    ATTR_MASK_UNSET(&(*child_attr_list)[i], stripe_items);
                }
            }
#endif

            generate_fields(&((*child_attr_list)[i]));

            /* Note: path is properly sized already to not overflow. */
            snprintf(path, path_len, "%s/%s", parent_list[0].fullname,
                     (*child_attr_list)[i].attr_values.name);
            (*child_id_list)[i].fullname = strdup(path);
        }
    }

    if (path)
        free(path);

    db_result_free(&p_mgr->conn, &result);
    g_string_free(req, TRUE);
    g_string_free(fields, TRUE);
    g_string_free(from, TRUE);
    g_string_free(where, TRUE);
    return 0;

array_free:
    if (path)
        free(path);
    if (child_attr_list && *child_attr_list)
    {
        MemFree(*child_attr_list);
        *child_attr_list = NULL;
    }
    MemFree(*child_id_list);
    *child_id_list = NULL;
free_str:
    g_string_free(req, TRUE);
    g_string_free(fields, TRUE);
    g_string_free(from, TRUE);
    g_string_free(where, TRUE);
    return rc;
}
Beispiel #28
0
/**
 * Get the list of children of a given parent (or list of parents).
 * \param parent_list       [in]  list of parents to get the child of
 * \param parent_count      [in]  number of ids in parent list
 * \param attr_mask         [in]  required attributes for children
 * \param child_id_list     [out] ptr to array of child ids
 * \param child_attr_list   [out] ptr to array of child attrs
 * \param child_count       [out] number of returned children
 */
int ListMgr_GetChild( lmgr_t * p_mgr, const lmgr_filter_t * p_filter,
                      const wagon_t * parent_list, unsigned int parent_count,
                      int attr_mask,
                      wagon_t ** child_id_list, attr_set_t ** child_attr_list,
                      unsigned int * child_count)
{
    result_handle_t result;
    char *curr;
    int  filter_main = 0;
    int  filter_annex = 0;
    int main_attrs = 0;
    int dnames_attrs = 0;
    int annex_attrs = 0;
    char query[4096];
    char fieldlist_main[1024] = "";
    char fieldlist_dnames[1024] = "";
    char fieldlist_annex[1024] = "";
    char filter_str_main[1024] = "";
    char filter_str_annex[1024] = "";
    char tmp[2048];
    char *path = NULL;
    int path_len;
    char * pc;
    int rc, i;

    /* TODO: querying children from several parent cannot work, since
     * we need to get the paths of the children. Or we could do a
     * lookup into parent_list to find the right one. In the meantime,
     * try not to mess up the code. */
    if (parent_count != 1)
        RBH_BUG("cannot get children for several parent simultaneously");

    /* always request for name to build fullpath in wagon */
    attr_mask |= ATTR_MASK_name;

    /* request is always on the MAIN table (which contains [parent_id, id] relationship */

    /* /!\ possible cases:
     * - simplest: the fields of the filter and the attributes to be retrieved are in the MAIN table
     * - harder: the fields of the filter and attributes are in a different table
     */

    /* 1) location of filters */
    if ( p_filter )
    {
        char           dummy_str[1024];
        unsigned int   dummy_uint;
        if (dir_filter(p_mgr, dummy_str, p_filter, &dummy_uint) != FILTERDIR_NONE)
        {
            DisplayLog( LVL_MAJOR, LISTMGR_TAG, "Directory filter not supported in %s()", __func__ );
            return DB_NOT_SUPPORTED;
        }
        else if (func_filter(p_mgr, dummy_str, p_filter, T_MAIN, FALSE, FALSE))
        {
            DisplayLog( LVL_MAJOR, LISTMGR_TAG, "Function filter not supported in %s()", __func__ );
            return DB_NOT_SUPPORTED;
        }

        /* There is always a filter on T_DNAMES, which is the parent condition.
         * Look for optional filters:
         */
        filter_main = filter2str( p_mgr, filter_str_main, p_filter, T_MAIN,
                                  FALSE, TRUE );

        if ( annex_table )
            filter_annex = filter2str( p_mgr, filter_str_annex, p_filter,
                                       T_ANNEX, FALSE, TRUE );
        else
            filter_annex = 0;

        /* @TODO to be implemented */
#if 0
        filter_stripe_info =
            filter2str( p_mgr, filter_str_stripe_info, p_filter, T_STRIPE_INFO,
                        ( filter_main > 0 ) || ( filter_annex > 0 ), TRUE );

        filter_stripe_items =
            filter2str( p_mgr, filter_str_stripe_items, p_filter, T_STRIPE_ITEMS,
                        ( filter_main > 0 ) || ( filter_annex > 0 )
                        || ( filter_stripe_info > 0 ), TRUE );
#endif
    }

    /* 2) location of requested attributes */
    if (attr_mask)
    {
        /* retrieve source info for generated fields */
        add_source_fields_for_gen( &attr_mask );

        main_attrs = attrmask2fieldlist( fieldlist_main, attr_mask, T_MAIN,
                                         /* leading comma */ TRUE, /* for update */ FALSE,
                                         /* prefix */ MAIN_TABLE".", /* postfix */ "" );

        dnames_attrs += attrmask2fieldlist( fieldlist_dnames, attr_mask, T_DNAMES,
                                            /* leading comma */ TRUE, /* for update */ FALSE,
                                            /* prefix */ DNAMES_TABLE".", /* postfix */ "" );

        if ( annex_table )
            annex_attrs = attrmask2fieldlist( fieldlist_annex, attr_mask, T_ANNEX,
                                             /* leading comma */ TRUE, /* for update */ FALSE,
                                             /* prefix */ ANNEX_TABLE".", /* postfix */ "" );
        else
            annex_attrs = 0;
    }
    else
    {
        /* no returned attrs */
        if (child_attr_list)
            *child_attr_list = NULL;
    }
    pc = parent_cond(p_mgr, tmp, sizeof(tmp), parent_list, parent_count, DNAMES_TABLE".");
    if (!pc)
        return DB_BUFFER_TOO_SMALL;

    curr = query;

    /* SELECT clause */
    /* id + dname fields */
    curr += sprintf(curr, "SELECT "DNAMES_TABLE".id%s", fieldlist_dnames);
    /* main attrs */
    if (main_attrs)
        curr += sprintf(curr, "%s", fieldlist_main);
    /* annex attrs */
    if (annex_attrs)
        curr += sprintf(curr, "%s", fieldlist_annex);

    /* FROM clause */
    curr += sprintf(curr, " FROM "DNAMES_TABLE);
    if (main_attrs || filter_main)
        curr += sprintf(curr, " LEFT JOIN "MAIN_TABLE
                              " ON "DNAMES_TABLE".id="MAIN_TABLE".id");
    if (annex_attrs || filter_annex)
        curr += sprintf(curr, " LEFT JOIN "ANNEX_TABLE
                              " ON "DNAMES_TABLE".id="ANNEX_TABLE".id");

    /* WHERE clause */
    curr += sprintf(curr, " WHERE %s", pc);
    if (filter_main)
        curr += sprintf(curr, " AND %s", filter_str_main);
    if (filter_annex)
        curr += sprintf(curr, " AND %s", filter_str_annex);

retry:
    rc = db_exec_sql(&p_mgr->conn, query, &result);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc)
        return rc;

    /* copy result to output structures */
    *child_count = db_result_nb_records(&p_mgr->conn, &result);

    /* allocate entry_id array */
    *child_id_list = MemCalloc(*child_count, sizeof(wagon_t));
    if (*child_id_list == NULL)
        return DB_NO_MEMORY;

    if (child_attr_list)
    {
        *child_attr_list = MemCalloc(*child_count, sizeof(attr_set_t));
        if (*child_attr_list == NULL)
        {
            rc = DB_NO_MEMORY;
            goto array_free;
        }
    }

    /* Allocate a string long enough to contain the parent path and a
     * child name. */
    path_len = strlen(parent_list[0].fullname) + RBH_NAME_MAX + 2;
    path = malloc(path_len);
    if (!path) {
        DisplayLog( LVL_MAJOR, LISTMGR_TAG, "Can't alloc enough memory (%d bytes)",
                    path_len );
        rc = DB_NO_MEMORY;
        goto array_free;
    }

    for (i = 0; i < *child_count; i++)
    {
        char *res[128]; /* 128 fields per row is large enough */
        rc = db_next_record(&p_mgr->conn, &result, res, 128);
        if ( rc )
            goto array_free;

        /* copy id to array */
        pk2entry_id(p_mgr, res[0], &((*child_id_list)[i].id));

        /* copy attributes to array */
        if (child_attr_list)
        {
            (*child_attr_list)[i].attr_mask = attr_mask;

            /* first id, then dnames attrs, then main attrs, then annex attrs */
            if (dnames_attrs)
            {
                /* shift of 1 for id */
                rc = result2attrset( T_DNAMES, res + 1, dnames_attrs, &((*child_attr_list)[i]) );
                if ( rc )
                    goto array_free;
            }

            if (main_attrs)
            {
                /* first id, then main attrs, then annex attrs */
                /* shift of 1 for id */
                rc = result2attrset( T_MAIN, res + dnames_attrs + 1, main_attrs, &((*child_attr_list)[i]) );
                if ( rc )
                    goto array_free;
            }

            if (annex_attrs)
            {
                /* shift of main_attrs count */
                rc = result2attrset( T_ANNEX, res + dnames_attrs + main_attrs + 1, annex_attrs,
                                     &((*child_attr_list)[i]) );
                if ( rc )
                    goto array_free;
            }

#ifdef _LUSTRE
            if (stripe_fields(attr_mask))
            {
                if (get_stripe_info( p_mgr, res[0], &ATTR(&(*child_attr_list)[i], stripe_info),
                                     &ATTR(&(*child_attr_list)[i], stripe_items) ))
                {
                    ATTR_MASK_UNSET(&(*child_attr_list)[i], stripe_info);
                    ATTR_MASK_UNSET(&(*child_attr_list)[i], stripe_items);
                }
            }
#endif

            generate_fields(&((*child_attr_list)[i]));

            /* Note: path is properly sized already to not overflow. */
            sprintf(path, "%s/%s", parent_list[0].fullname,
                    (*child_attr_list)[i].attr_values.name);
            (*child_id_list)[i].fullname = strdup(path);
        }
    }

    if (path)
        free(path);
    db_result_free( &p_mgr->conn, &result );
    return 0;

array_free:
    if (path)
        free(path);
    if (child_attr_list && *child_attr_list)
    {
        MemFree(*child_attr_list);
        *child_attr_list = NULL;
    }
    MemFree(*child_id_list);
    *child_id_list = NULL;
    return rc;
}
Beispiel #29
0
/**
 * \retval DB_NOT_EXISTS if the recovery table does not exist
 */
static int expected_recov_status( lmgr_t * p_mgr, lmgr_recov_stat_t * p_stats )
{
    int  rc, i;
    result_handle_t result;
    char * status[5];

    /* test if a RECOVERY table already exist, and contains entries */
    rc = db_exec_sql_quiet( &p_mgr->conn, "SELECT status,type,COUNT(*),(size=0) as empty,SUM(size) FROM "RECOV_TABLE
                            " GROUP BY status,type,empty", &result );
    if (rc)
        return rc;

    /* @TODO manage dirs and symlinks differently */

    p_stats->total = 0;
    for (i = 0; i < RS_COUNT; i++ )
    {
        p_stats->status_count[i] = 0;
        p_stats->status_size[i] = 0;
    }

    while ( (rc = db_next_record( &p_mgr->conn, &result, status, 5 ))
            != DB_END_OF_LIST )
    {
        long long cnt;
        uint64_t sz;
        int isempty;

        if (rc)
            return rc;

        cnt = str2bigint( status[2] );
        if ( cnt == -1LL)
            return DB_INVALID_ARG;

        isempty = str2int(  status[3] );
        if ( isempty == -1)
            return DB_INVALID_ARG;

        sz = str2size(  status[4] );
        if ( sz == -1LL)
            return DB_INVALID_ARG;

        p_stats->total += cnt;

        if ( status[0] != NULL )
        {
            int st = str2int( status[0] );

            /* archived entries: file and (optionally) symlinks  */
            if (!strcasecmp(status[1], STR_TYPE_FILE))
            {
                if (isempty)
                {
                     p_stats->status_count[RS_FILE_EMPTY] += cnt;
                     p_stats->status_size[RS_FILE_EMPTY] += sz;
                }
                else
                {
                    switch (st)
                    {
                        case STATUS_NEW:
                            p_stats->status_count[RS_NOBACKUP] += cnt;
                            p_stats->status_size[RS_NOBACKUP] += sz;
                            break;
                        case STATUS_MODIFIED:
                        case STATUS_ARCHIVE_RUNNING:
                            p_stats->status_count[RS_FILE_DELTA] += cnt;
                            p_stats->status_size[RS_FILE_DELTA] += sz;
                            break;
                        case STATUS_SYNCHRO:
                        case STATUS_RELEASED:
                            p_stats->status_count[RS_FILE_OK] += cnt;
                            p_stats->status_size[RS_FILE_OK] += sz;
                            break;
                    }
                }
            }
            else if (!strcasecmp(status[1], STR_TYPE_LINK)
                     || !strcasecmp(status[1], STR_TYPE_DIR))
            {
                /* symlinks and dirs always recoverable from DB */
                p_stats->status_count[RS_NON_FILE] += cnt;
                p_stats->status_size[RS_NON_FILE] += sz;
            }
            else
            {
                /* non recoverable : special entry like fifo, blk, ... */
                p_stats->status_count[RS_NOBACKUP] += cnt;
                p_stats->status_size[RS_NOBACKUP] += sz;
            }
        }
    }

    db_result_free( &p_mgr->conn, &result );
    return 0;
}
Beispiel #30
0
/**
 *  Retrieve entry attributes from its primary key
 */
int listmgr_get_by_pk( lmgr_t * p_mgr, PK_ARG_T pk, attr_set_t * p_info )
{
    int            rc;
    char           fieldlist[4096] = "";
    char          *first_table = NULL;
    char           from[1024] = "";
    char           query[4096] = "";
    /* we assume there is not more than 128 fields */
    char          *result_tab[128];
    result_handle_t result;
    int checkmain = 1;
    int main_count = 0, annex_count = 0, name_count = 0;

    if (p_info == NULL)
        return 0;

    /* init entry info */
    memset( &p_info->attr_values, 0, sizeof( entry_info_t ) );
    fieldlist[0] = '\0';

    /* retrieve source info for generated fields */
    add_source_fields_for_gen( &p_info->attr_mask );

    /* get info from main table (if asked) */
    main_count = attrmask2fieldlist(fieldlist, p_info->attr_mask, T_MAIN, FALSE,
                                    FALSE, "", "");
    if (main_count < 0)
        return -main_count;
    else if (main_count > 0)
    {
        checkmain = 0;
        first_table = MAIN_TABLE;
        sprintf(from, MAIN_TABLE);
    }

    annex_count = attrmask2fieldlist(fieldlist + strlen(fieldlist),
                                     p_info->attr_mask, T_ANNEX,
                                     first_table != NULL, FALSE, "", "");
    if (annex_count < 0)
        return -annex_count;
    else if (annex_count > 0)
    {
        if (first_table)
            sprintf(from + strlen(from), " LEFT JOIN "ANNEX_TABLE" ON %s.id="
                    ANNEX_TABLE".id", first_table);
        else
        {
            first_table = ANNEX_TABLE;
            sprintf(from, ANNEX_TABLE);
        }
    }

    name_count = attrmask2fieldlist(fieldlist + strlen(fieldlist),
                                    p_info->attr_mask, T_DNAMES,
                                    first_table != NULL, FALSE, "", "");
    if (name_count < 0)
        return -name_count;
    else if (name_count > 0)
    {
        if (first_table)
            /* it's OK to JOIN with NAMES table here even if there are multiple paths,
             * as we only take one result record. The important thing is to return
             * consistent values for parent_id, name and fullpath. */
            sprintf(from + strlen(from), " LEFT JOIN "DNAMES_TABLE" ON %s.id="
                    DNAMES_TABLE".id", first_table);
        else
        {
            first_table = DNAMES_TABLE;
            sprintf(from, DNAMES_TABLE);
        }
    }

    if (first_table != NULL)
    {
        int shift = 0;
        sprintf(query, "SELECT %s FROM %s WHERE %s.id="DPK, fieldlist, from,
                first_table, pk);

        rc = db_exec_sql(&p_mgr->conn, query, &result);
        if (rc)
            return rc;

        rc = db_next_record(&p_mgr->conn, &result, result_tab,
                            main_count + annex_count + name_count);
        /* END_OF_LIST means it does not exist */
        if (rc == DB_END_OF_LIST)
            rc = DB_NOT_EXISTS;
        if (rc)
            goto free_res;

        /* set info from result */
        if (main_count)
        {
            rc = result2attrset(T_MAIN, result_tab + shift, main_count, p_info);
            shift += main_count;
            if (rc)
                goto free_res;
        }
        if (annex_count)
        {
            rc = result2attrset(T_ANNEX, result_tab + shift, annex_count,
                                p_info);
            shift += annex_count;
            if (rc)
                goto free_res;
        }
        if (name_count)
        {
            rc = result2attrset(T_DNAMES, result_tab + shift, name_count,
                                p_info);
            shift += name_count;
            if (rc)
                goto free_res;
        }

        db_result_free(&p_mgr->conn, &result);
    }

    /* remove stripe info if it is not a file */
    if (stripe_fields(p_info->attr_mask) && ATTR_MASK_TEST(p_info, type)
        && strcmp(ATTR(p_info, type), STR_TYPE_FILE) != 0)
    {
        p_info->attr_mask &= ~stripe_attr_set;
    }

    /* get stripe info if asked */
#ifdef _LUSTRE
    if (stripe_fields( p_info->attr_mask ))
    {
        rc = get_stripe_info( p_mgr, pk, &ATTR( p_info, stripe_info ),
                              ATTR_MASK_TEST( p_info, stripe_items ) ? &ATTR( p_info,
                                                                              stripe_items ) :
                              NULL );
        if ( rc == DB_ATTR_MISSING || rc == DB_NOT_EXISTS )
        {
            p_info->attr_mask &= ~ATTR_MASK_stripe_info;

            if ( ATTR_MASK_TEST( p_info, stripe_items ) )
                p_info->attr_mask &= ~ATTR_MASK_stripe_items;
        }
        else if ( rc )
            return rc;
        else
            checkmain = 0; /* entry exists */
    }
#else
    /* always clean them */
    p_info->attr_mask &= ~(ATTR_MASK_stripe_info | ATTR_MASK_stripe_items);
#endif

    /* special field dircount */
    if (dirattr_fields( p_info->attr_mask ))
    {
        if (listmgr_get_dirattrs(p_mgr, pk, p_info))
        {
            DisplayLog( LVL_MAJOR, LISTMGR_TAG, "listmgr_get_dirattrs failed for "DPK, pk );
            p_info->attr_mask &= ~dir_attr_set;
        }
    }

    if (checkmain)
    {
        /* verify it exists in main table */
        sprintf( query, "SELECT id FROM " MAIN_TABLE " WHERE id="DPK, pk );

        /* execute the request */
        rc = db_exec_sql( &p_mgr->conn, query, &result );
        if ( rc )
            return rc;

        rc = db_next_record( &p_mgr->conn, &result, result_tab, 1 );
        db_result_free( &p_mgr->conn, &result );
        if (rc)
            return DB_NOT_EXISTS;
    }

    /* compute generated fields if asked */
    generate_fields( p_info );

    p_mgr->nbop[OPIDX_GET]++;

    return DB_SUCCESS;

  free_res:
    db_result_free( &p_mgr->conn, &result );
    return rc;
}                               /* listmgr_get_by_pk */