Пример #1
0
dbt_table_p dbt_load_file(const str *tbn, const str *dbn)
{
	FILE *fin=NULL;
	char path[512], buf[4096];
	int c, crow, ccol, bp, sign, max_auto;
	dbt_val_t dtval;
	dbt_table_p dtp = NULL;
	dbt_column_p colp, colp0 = NULL;
	dbt_row_p rowp, rowp0 = NULL;
		
	enum {DBT_FLINE_ST, DBT_NLINE_ST, DBT_DATA_ST} state;
	
	LM_DBG("request for table [%.*s]\n", tbn->len, tbn->s);
	
	if(!tbn || !tbn->s || tbn->len<=0 || tbn->len>=255)
		return NULL;
	path[0] = 0;
	if(dbn && dbn->s && dbn->len>0)
	{
		LM_DBG("db is [%.*s]\n", dbn->len, dbn->s);
		if(dbn->len+tbn->len<511)
		{
			strncpy(path, dbn->s, dbn->len);
			path[dbn->len] = '/';
			strncpy(path+dbn->len+1, tbn->s, tbn->len);
			path[dbn->len+tbn->len+1] = 0;
		}
	}
	if(path[0] == 0)
	{
		strncpy(path, tbn->s, tbn->len);
		path[tbn->len] = 0;
	}
	
	LM_DBG("loading file [%s]\n", path);
	fin = fopen(path, "rt");
	if(!fin)
		return NULL;	
	
	dtp = dbt_table_new(tbn, dbn, path);
	if(!dtp)
		goto done;
	
	state = DBT_FLINE_ST;
	crow = ccol = -1;
	colp = colp0 = NULL;
	rowp = rowp0 = NULL;
	c = fgetc(fin);
	max_auto = 0;
	while(c!=EOF)
	{
		switch(state)
		{
			case DBT_FLINE_ST:
				//LM_DBG("state FLINE!\n");
				bp = 0;
				while(c==DBT_DELIM_C)
					c = fgetc(fin);
				if(c==DBT_DELIM_R && !colp0)
					goto clean;
				if(c==DBT_DELIM_R)
				{
					if(dtp->nrcols <= 0)
						goto clean;
					dtp->colv = (dbt_column_p*)
							shm_malloc(dtp->nrcols*sizeof(dbt_column_p));
					if(!dtp->colv)
						goto clean;
					colp0 = dtp->cols;
					for(ccol=0; ccol<dtp->nrcols && colp0; ccol++)
					{
						dtp->colv[ccol] = colp0;
						colp0 = colp0->next;
					}
					state = DBT_NLINE_ST;
					break;
				}
				while(c!=DBT_DELIM_C && c!='(' && c!=DBT_DELIM_R)
				{
					if(c==EOF)
						goto clean;
					buf[bp++] = c;
					c = fgetc(fin);
				}
				colp = dbt_column_new(buf, bp);
				if(!colp)
					goto clean;
				//LM_DBG("new col [%.*s]\n", bp, buf);
				while(c==DBT_DELIM_C)
					c = fgetc(fin);
				if(c!='(')
					goto clean;
				c = fgetc(fin);
				while(c==DBT_DELIM_C)
					c = fgetc(fin);
				
				switch(c)
				{
					case 's':
					case 'S':
						colp->type = DB_STR;
						LM_DBG("column[%d] is STR!\n", ccol+1);
					break;
					case 'i':
					case 'I':
						colp->type = DB_INT;
						LM_DBG("column[%d] is INT!\n", ccol+1);
					break;
					case 'l':
					case 'L':
						colp->type = DB_BIGINT;
						LM_DBG("column[%d] is BIGINT!\n", ccol+1);
					break;
					case 'd':
					case 'D':
						colp->type = DB_DOUBLE;
						LM_DBG("column[%d] is DOUBLE!\n", ccol+1);
					break;
					case 'b':
					case 'B':
						colp->type = DB_BLOB;
						LM_DBG("column[%d] is BLOB!\n", ccol+1);
					break;
					case 't':
					case 'T':
						colp->type = DB_DATETIME;
						LM_DBG("column[%d] is TIME!\n", ccol+1);
					break;
					default:
						LM_DBG("wrong column type!\n");
						goto clean;
				}

				while(c!='\n' && c!=EOF && c!=')' && c!= ',')
				{
					if(colp->type == DB_STR && (c=='i'|| c=='I'))
					{
						colp->type = DB_STRING;
						LM_DBG("column[%d] is actually STRING!\n", ccol+1);
					}
					c = fgetc(fin);
				}
				if(c==',')
				{
					//LM_DBG("c=%c!\n", c);
					c = fgetc(fin);
					while(c==DBT_DELIM_C)
						c = fgetc(fin);
					if(c=='N' || c=='n')
					{
						//LM_DBG("NULL flag set!\n");
						colp->flag |= DBT_FLAG_NULL;
					}
					else if(colp->type==DB_INT && dtp->auto_col<0
							&& (c=='A' || c=='a'))
					{
						//LM_DBG("AUTO flag set!\n");
						colp->flag |= DBT_FLAG_AUTO;
						dtp->auto_col = ccol+1;
					}
					else
						goto clean;
					while(c!=')' && c!=DBT_DELIM_R && c!=EOF)
						c = fgetc(fin);
				}
				if(c == ')')
				{
					//LM_DBG("c=%c!\n", c);
					if(colp0)
					{
						colp->prev = colp0;
						colp0->next = colp;
					}
					else
						dtp->cols = colp;
					colp0 = colp;
					dtp->nrcols++;
					c = fgetc(fin);
				}
				else
					goto clean;
				ccol++;
			break;

			case DBT_NLINE_ST:
				//LM_DBG("state NLINE!\n");
				while(c==DBT_DELIM_R)
					c = fgetc(fin);
				if(rowp)
				{
					if(dbt_table_check_row(dtp, rowp))
						goto clean;

					if(!rowp0)
						dtp->rows = rowp;
					else
					{
						rowp0->next = rowp;
						rowp->prev = rowp0;
					}
					rowp0 = rowp;
					dtp->nrrows++;
				}
				if(c==EOF)
					break;
				crow++;
				ccol = 0;
				rowp = dbt_row_new(dtp->nrcols);
				if(!rowp)
					goto clean;
				state = DBT_DATA_ST;
				
			break;
			
			case DBT_DATA_ST:
				//LM_DBG("state DATA!\n");
				//while(c==DBT_DELIM)
				//	c = fgetc(fin);
				if(ccol == dtp->nrcols && (c==DBT_DELIM_R || c==EOF))
				{
					state = DBT_NLINE_ST;
					break;
				}
				if(ccol>= dtp->nrcols)
					goto clean;
				
				switch(dtp->colv[ccol]->type)
				{
					case DB_INT:
					case DB_BIGINT:
					case DB_DATETIME:
						//LM_DBG("INT value!\n");
						dtval.val.int_val = 0;
						dtval.type = dtp->colv[ccol]->type;

						if(c==DBT_DELIM || 
								(ccol==dtp->nrcols-1
								 && (c==DBT_DELIM_R || c==EOF)))
							dtval.nul = 1;
						else
						{
							dtval.nul = 0;
							sign = 1;
							if(c=='-')
							{
								sign = -1;
								c = fgetc(fin);
							}
							if(c<'0' || c>'9')
								goto clean;
							while(c>='0' && c<='9')
							{
								dtval.val.int_val=dtval.val.int_val*10+c-'0';
								c = fgetc(fin);
							}
							dtval.val.int_val *= sign;
							//LM_DBG("data[%d,%d]=%d\n", crow,
							//	ccol, dtval.val.int_val);
						}
						if(c!=DBT_DELIM && c!=DBT_DELIM_R && c!=EOF)
							goto clean;
						if(dbt_row_set_val(rowp,&dtval,dtp->colv[ccol]->type,
									ccol))
							goto clean;
						if(ccol == dtp->auto_col)
							max_auto = (max_auto<dtval.val.int_val)?
									dtval.val.int_val:max_auto;
					break;
					
					case DB_DOUBLE:
						//LM_DBG("DOUBLE value!\n");
						dtval.val.double_val = 0.0;
						dtval.type = DB_DOUBLE;

						if(c==DBT_DELIM || 
								(ccol==dtp->nrcols-1
								 && (c==DBT_DELIM_R || c==EOF)))
							dtval.nul = 1;
						else
						{
							dtval.nul = 0;
							sign = 1;
							if(c=='-')
							{
								sign = -1;
								c = fgetc(fin);
							}
							if(c<'0' || c>'9')
								goto clean;
							while(c>='0' && c<='9')
							{
								dtval.val.double_val = dtval.val.double_val*10
										+ c - '0';
								c = fgetc(fin);
							}
							if(c=='.')
							{
								c = fgetc(fin);
								bp = 1;
								while(c>='0' && c<='9')
								{
									bp *= 10;
									dtval.val.double_val+=((double)(c-'0'))/bp;
									c = fgetc(fin);
								}
							}
							dtval.val.double_val *= sign;
							//LM_DBG("data[%d,%d]=%10.2f\n",
							//	crow, ccol, dtval.val.double_val);
						}
						if(c!=DBT_DELIM && c!=DBT_DELIM_R && c!=EOF)
							goto clean;
						if(dbt_row_set_val(rowp,&dtval,DB_DOUBLE,ccol))
							goto clean;
					break;
					
					case DB_STR:
					case DB_STRING:
					case DB_BLOB:
						//LM_DBG("STR value!\n");
						
						dtval.val.str_val.s = NULL;
						dtval.val.str_val.len = 0;
						dtval.type = dtp->colv[ccol]->type;
						
						bp = 0;
						if(c==DBT_DELIM || 
								(ccol == dtp->nrcols-1
								 && (c == DBT_DELIM_R || c==EOF)))
							dtval.nul = 1;
						else
						{
							dtval.nul = 0;
							while(c!=DBT_DELIM && c!=DBT_DELIM_R && c!=EOF)
							{
								if(c=='\\')
								{
									c = fgetc(fin);
									switch(c)
									{
										case 'n':
											c = '\n';	
										break;
										case 'r':
											c = '\r';
										break;
										case 't':
											c = '\t';
										break;
										case '\\':
											c = '\\';
										break;
										case DBT_DELIM:
											c = DBT_DELIM;
										break;
										case '0':
											c = 0;
										break;
										default:
											goto clean;
									}
								}
								buf[bp++] = c;
								c = fgetc(fin);
							}
							dtval.val.str_val.s = buf;
							dtval.val.str_val.len = bp;
							//LM_DBG("data[%d,%d]=%.*s\n",
							///	crow, ccol, bp, buf);
						}
						if(c!=DBT_DELIM && c!=DBT_DELIM_R && c!=EOF)
							goto clean;
						if(dbt_row_set_val(rowp,&dtval,dtp->colv[ccol]->type,
									ccol))
							goto clean;
					break;
					default:
						goto clean;
				}
				if(c==DBT_DELIM)
					c = fgetc(fin);
				ccol++;
			break; // state DBT_DATA_ST
		}
	}

	if(max_auto)
		dtp->auto_val = max_auto;

done:
	if(fin)
		fclose(fin);
	return dtp;
clean:
	/// ????? FILL IT IN - incomplete row/column
	// memory leak?!?! with last incomplete row
	LM_DBG("error at row=%d col=%d c=%c\n", crow+1, ccol+1, c);
	if(dtp)
		dbt_table_free(dtp);
	return NULL;
}
Пример #2
0
int dbt_query(db1_con_t* _h, db_key_t* _k, db_op_t* _op, db_val_t* _v,
			db_key_t* _c, int _n, int _nc, db_key_t _o, db1_res_t** _r)
{
	dbt_table_p _tbc = NULL;
	dbt_table_p _tbc_temp = NULL;
	dbt_row_p _drp = NULL;
	dbt_row_p *_res = NULL;
//	dbt_result_p _dres = NULL;
	int result = 0;
	int counter = 0;
	int i=0;

	int *lkey=NULL, *lres=NULL;

	db_key_t *_o_k=NULL;    /* columns in order-by */
	char *_o_op=NULL;       /* operators for oder-by */
	int _o_n;               /* no of elements in order-by */
	int *_o_l=NULL;         /* column selection for order-by */
//	int _o_nc;              /* no of elements in _o_l but not lres */

	if(_r)
		*_r = NULL;

	if ((!_h) || !CON_TABLE(_h))
	{
		LM_ERR("invalid parameters\n");
		return -1;
	}

	if (_o)
	{
		if (dbt_parse_orderbyclause(&_o_k, &_o_op, &_o_n, _o) < 0)
			return -1;
	}

	_tbc_temp = dbt_db_get_temp_table(DBT_CON_CONNECTION(_h));
	if(!_tbc_temp)
	{
		LM_ERR("unable to allocate temp table\n");
		return -1;
	}

	/* lock database */
	_tbc = dbt_db_get_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
	if(!_tbc)
	{
		LM_ERR("table %.*s does not exist!\n", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
		dbt_db_del_table(DBT_CON_CONNECTION(_h), &_tbc_temp->name, 0);
		return -1;
	}


	if(!_tbc || _tbc->nrcols < _nc)
	{
		LM_ERR("table %s not loaded! (too few columns)\n", CON_TABLE(_h)->s);
		goto error;
	}
	if(_k)
	{
		lkey = dbt_get_refs(_tbc, _k, _n);
		if(!lkey)
			goto error;
	}
	if(_c)
	{
		lres = dbt_get_refs(_tbc, _c, _nc);
		if(!lres)
			goto error;
	}
	if(_o_k)
	{
		_o_l = dbt_get_refs(_tbc, _o_k, _o_n);
		if (!_o_l)
			goto error;
		/* enlarge select-columns lres by all order-by columns, _o_nc is how many */
//		if (dbt_mangle_columnselection(&lres, &_nc, &_o_nc, _o_l, _o_n) < 0)
//			goto error;
	}

/*
	LM_DBG("new res with %d cols\n", _nc);
	_dres = dbt_result_new(_tbc, lres, _nc);

	if(!_dres)
		goto error;
*/

		dbt_column_p pPrevCol = NULL;
		_tbc_temp->colv = (dbt_column_p*) shm_malloc(_nc*sizeof(dbt_column_p));
		for(i=0; i < _nc; i++) {
			dbt_column_p pCol = dbt_column_new(_tbc->colv[ lres[i] ]->name.s, _tbc->colv[ lres[i] ]->name.len);
			pCol->type = _tbc->colv[ lres[i] ]->type;
			pCol->flag = _tbc->colv[ lres[i] ]->flag;
			if(pPrevCol)
			{
				pCol->prev = pPrevCol;
				pPrevCol->next = pCol;
			}
			else
				_tbc_temp->cols = pCol;

			_tbc_temp->colv[i] = pCol;
			pPrevCol = pCol;
			_tbc_temp->nrcols++;
		}

	_res = (dbt_row_p*) pkg_malloc(_db_text_max_result_rows * sizeof(dbt_row_p));
	if(!_res) {
		LM_ERR("no more space to allocate for query rows\n");
		goto error;
	}


	_drp = _tbc->rows;
	while(_drp && counter < _db_text_max_result_rows)
	{
		if(dbt_row_match(_tbc, _drp, lkey, _op, _v, _n))
		{
			_res[counter] = _drp;
//			if(dbt_result_extract_fields(_tbc, _drp, lres, _dres))
//			{
//				LM_ERR("failed to extract result fields!\n");
//				goto clean;
//			}
			counter++;
		}
		_drp = _drp->next;
	}

	if (_o_l)
	{
		if (counter > 1)
		{
			if (dbt_sort_result_temp(_res, counter, _o_l, _o_op, _o_n) < 0)
				goto error;
		}

		/* last but not least, remove surplus columns */
//		if (_o_nc)
//			dbt_project_result(_dres, _o_nc);
	}

	// copy results to temp table
	_tbc_temp->rows = dbt_result_extract_results(_tbc, _res, counter, lres, _nc);
	_tbc_temp->nrrows = (_tbc_temp->rows == NULL ? 0 : counter);

	dbt_table_update_flags(_tbc, DBT_TBFL_ZERO, DBT_FL_IGN, 1);

	/* unlock database */
	dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));

// 	DBT_CON_TEMP_TABLE(_h) = _tbc_temp;
	last_temp_table = _tbc_temp;
//	dbt_release_table(DBT_CON_CONNECTION(_h), &_tbc_temp->name);

//	dbt_result_print(_tbc_temp);

	if(lkey)
		pkg_free(lkey);
	if(lres)
		pkg_free(lres);
	if(_o_k)
 		pkg_free(_o_k);
 	if(_o_op)
 		pkg_free(_o_op);
 	if(_o_l)
 		pkg_free(_o_l);
 	if(_res)
 		pkg_free(_res);

 	if(_r) {
 		result = dbt_get_result(_r, _tbc_temp);
// 		dbt_db_del_table(DBT_CON_CONNECTION(_h), &_tbc_temp->name, 1);
		if(result != 0)
 			dbt_result_free(_h, _tbc_temp);
 	}

	return result;

error:
    /* unlock database */
    dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
    /* delete temp table */
    dbt_db_del_table(DBT_CON_CONNECTION(_h), &_tbc_temp->name, 1);
	if(_res)
		pkg_free(_res);
	if(lkey)
		pkg_free(lkey);
	if(lres)
		pkg_free(lres);
	if(_o_k)
		pkg_free(_o_k);
	if(_o_op)
		pkg_free(_o_op);
	if(_o_l)
		pkg_free(_o_l);
	LM_ERR("failed to query the table!\n");

	return -1;

/*
clean:
	dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
	if(lkey)
		pkg_free(lkey);
	if(lres)
		pkg_free(lres);
	if(_o_k)
		pkg_free(_o_k);
	if(_o_op)
		pkg_free(_o_op);
	if(_o_l)
		pkg_free(_o_l);

	return -1;
*/
}