示例#1
0
int
main(int argc, char **argv)
{
	double          modified_after =now() , last_lddate, last_mtime, mtime;
	char           *orbname = NULL;
	char           *dbname = NULL;
	int             orb;
	int             naptime = -1, check_lddate_interval = -1;
	Dbptr           db, dbt, dbs;
	char           *prefix = NULL;
	struct stat     filestat;
	int             i;
	Tbl            *tablenames, *tables_containing_dfile, *check_tables = NULL,
	               *ignore_tables = NULL;
	long            table_present, recc, is_view;
	char           *tablename, *schemaname;
	char           *filename;
	int             counter = 0, force_check = 0;
	char            expr[512];
	char           *statefilename = NULL, *pfname = "dbnew2orb";
	Pf             *pf = NULL;
	void           *priv_dfile = (void *) NULL;
	void           *private = (void *) NULL;
	int             pmsi;	/* poor man's string index, replacment for
				 * searchtbl... */
	char           *pmsp;
	double          lastburytime;
	Relic           relic;
	char           *s;
	Expression     *expr_lddate;
	double         *mtimes;
	double         *lddates;

	elog_init(argc, argv);

	if (argc < 2) {
		usage();
		exit(1);
	}
	for (argc--, argv++; argc > 0; argc--, argv++) {
		if (!strcmp(*argv, "-modified_after")) {
			argc--;
			argv++;
			if (argc < 1) {
				complain(0, "Need -modified_after argument.\n");
				usage();
				exit(1);
			}
			modified_after = str2epoch(*argv);
		} else if (!strcmp(*argv, "-prefix")) {
			argc--;
			argv++;
			if (argc < 1) {
				complain(0, "Need -prefix argument.\n");
				usage();
				exit(1);
			}
			prefix = *argv;
		} else if (!strcmp(*argv, "-pf")) {
			argc--;
			argv++;
			if (argc < 1) {
				complain(0, "Need -pf argument.\n");
				usage();
				exit(1);
			}
			pfname = *argv;
		} else if (!strcmp(*argv, "-state")) {
			argc--;
			argv++;
			if (argc < 1) {
				complain(0, "Need -state argument.\n");
				usage();
				exit(1);
			}
			statefilename = *argv;
		} else if (!strcmp(*argv, "-sleep")) {
			argc--;
			argv++;
			if (argc < 1) {
				complain(0, "Need -sleep argument.\n");
				usage();
				exit(1);
			}
			naptime = atoi(*argv);
		} else if (!strcmp(*argv, "-check_lddate_interval")) {
			argc--;
			argv++;
			if (argc < 1) {
				complain(0, "Need -check_lddate_interval argument.\n");
				usage();
				exit(1);
			}
			check_lddate_interval = atoi(*argv);
		} else if (!strcmp(*argv, "-v")) {
			verbose++;
		} else if (**argv != '-') {
			break;
		} else {
			complain(0, "Unrecognized argument '%s'.\n", *argv);
			usage();
			exit(1);
		}
	}


	if (pfread(pfname, &pf)) {
		elog_die(0, "parse_pf: pfread('%s') error.\n", pfname);
	}
	if (check_lddate_interval < 1) {
		if (parse_param(pf, "check_lddate_interval", P_LINT, 1, &check_lddate_interval) < 0) {
			elog_die(1, "parse_pf: sleep check_lddate_interval needed!\n");
		} else {
			if (check_lddate_interval < 0) {
				check_lddate_interval = 1;
			}
		}
	}
	if (naptime < 1) {
		if (parse_param(pf, "sleep", P_LINT, 1, &naptime) < 0) {
			elog_die(1, "parse_pf: sleep value needed!\n");
		} else {
			if (naptime < 0) {
				naptime = 1;
			}
		}
	}
	if (!prefix) {
		if (parse_param(pf, "prefix", P_STR, 0, &prefix) < 0) {
			printf("NO PREFIX!\n");
			prefix = NULL;
		}
	}
	parse_param(pf, "check_tables", P_TBL, 0, &check_tables);
	if (check_tables) {
		if (maxtbl(check_tables) < 1) {
			freetbl(check_tables, 0);
			check_tables = NULL;
		}
	}
	parse_param(pf, "ignore_tables", P_TBL, 0, &ignore_tables);
	if (ignore_tables) {
		if (maxtbl(ignore_tables) < 1) {
			freetbl(ignore_tables, 0);
			ignore_tables = NULL;
		}
	}
	/*
	 * no good here, would erase the table above pffree(pf);
	 */

	if (argc < 1) {
		complain(0, "Need db argument.\n");
		usage();
		exit(1);
	}
	dbname = *argv;

	argc--;
	argv++;
	if (argc < 1) {
		complain(0, "Need orb argument.\n");
		usage();
		exit(1);
	}
	orbname = *argv;
	argc--;
	argv++;
	if (argc > 0) {
		complain(0, "Unrecognized argument '%s'.\n", *argv);
		usage();
		exit(1);
	}
	if (dbopen(dbname, "r", &db) < 0) {
		elog_complain(0, "Can't open database");
		exit(1);
	}
	dbquery(db, dbSCHEMA_NAME, &schemaname);
	orb = orbopen(orbname, "w&");
	if (orb < 0) {
		elog_die(0, "orbopen(%s) error\n", orbname);
	}
	/*
	 * prepare for later call to dbquery(dbFIELD_TABLES) to find only
	 * tables containing lddate
	 */

	/*
	 * dbtables is much better, does not require the existence of table
	 * origin dbf = dblookup(db, 0, "origin", "lddate", "dbNULL");
	 * dbquery(dbf, dbFIELD_TABLES, &tablenames);
	 */

	dbex_compile(db, "max(lddate)", &expr_lddate, dbTIME);
	tablenames = dbtables(db, "lddate");
	tables_containing_dfile = dbtables(db, "dfile");

	/* waste a few bytes... */
	ntables = maxtbl(tablenames);
	mtimes = malloc(ntables * sizeof(double));
	lddates = malloc(ntables * sizeof(double));
	bury_times = malloc(ntables * sizeof(double));
	static_flags = malloc(ntables * sizeof(long));
	if (statefilename) {
		if (exhume(statefilename, &Stop, 10, mortician)) {
			elog_notify(0, "read old state file\n");
		} else {
			elog_complain(0, "could not read old statefile\n");
		}
	}
	for (i = 0; i < ntables; i++) {
		/*
		 * mtimes[i] = modified_after; lddates[i] = modified_after;
		 */
		static_flags[i] = NEW_TABLE;
	}
	for (;;) {
		tablenames = dbtables(db, "lddate");

		for (i = 0; i < ntables; i++) {
			tablename = gettbl(tablenames, i);
			if (!tablename) {
				continue;
			}
			dbt = dblookup(db, 0, tablename, 0, 0);
			dbquery(dbt, dbTABLE_PRESENT, &table_present);
			if (!table_present) {
				continue;
			}
			dbquery(dbt, dbTABLE_IS_VIEW, &is_view);
			if (is_view) {
				continue;
			}
			/* lastid is not a good idea (my personal choice)... */
			if (strcmp(tablename, "lastid") == 0) {
				continue;
			}
			/* remove after Dan fixed the bug with remark */
			if (strcmp(tablename, "remark") == 0) {
				continue;
			}
			if (findtbl(tablename, tables_containing_dfile)) {
				continue;
			}
			if (check_tables) {
				if (!findtbl(tablename,check_tables)) {
					if (verbose > 1 && static_flags[i]==NEW_TABLE) elog_notify(0,"ignoring table %s because it's NOT in 'check_tables'\n",tablename);
					continue;
				}
			}
			if (ignore_tables) {
				if (findtbl(tablename,ignore_tables)) {
					if (verbose > 1 && static_flags[i]==NEW_TABLE) elog_notify(0,"ignoring table %s because it's in 'ignore_tables'\n",tablename);
					continue;
				}
			}
			dbquery(dbt, dbRECORD_COUNT, &recc);
			if (recc < 1) {
				continue;
			}
			if (statefilename) {
			if (static_flags[i] == NEW_TABLE) {
				relic.dp = &bury_times[i];
				if (resurrect(tablename, relic, TIME_RELIC) == 0) {
					mtimes[i] = bury_times[i];
					lddates[i] = bury_times[i];
					if (verbose > 1) {
						elog_notify(0, "resurrection successful: check %s after %s\n", tablename, s = strtime(bury_times[i]));
						free(s);
					}
				} else {
					bury_times[i] = modified_after;
					mtimes[i] = modified_after;
					lddates[i] = modified_after;
					if (verbose > 1) {
						elog_notify(0, "resurrection unsuccessful: check %s after %s\n", tablename, s = strtime(modified_after));
						free(s);
					}
				}
				static_flags[i] = TABLE_SEEN;
			}
			} else {
				if (static_flags[i] == NEW_TABLE) {
					bury_times[i] = modified_after;
					mtimes[i] = modified_after;
					lddates[i] = modified_after;
					static_flags[i] = TABLE_SEEN;
				}
			}
			dbquery(dbt, dbTABLE_FILENAME, &filename);
			if (stat(filename, &filestat) < 0) {
				elog_die(1, "stat(%s) error.\n", filename);
			}
			last_mtime = mtimes[i];
			last_lddate = lddates[i];

			mtime = filestat.st_mtime;
			/*
			 * the whole mtime stuff is not soo good: mtime is
			 * typically > lddate, so setting modified_after to
			 * mtime will certainly ignore the last value. To get
			 * everything, I will have to keep 2 arrays: mtimes
			 * to detect file modifications and lddates to get
			 * the actual entries...
			 */
			if (force_check || mtime > last_mtime) {
				sprintf(expr, "lddate > %f", last_lddate);
				dbs = dbsubset(dbt, expr, 0);
				dbquery(dbs, dbRECORD_COUNT, &recc);
				if (recc > 0) {
					if (dbrows2orb(dbs, orb, prefix) == 0) {
						/*
						 * dbex_evalstr(dbs,
						 * "max(lddate)", dbTIME,
						 * &lddates[i]);
						 */
						dbex_eval(dbs, expr_lddate, 0, &lddates[i]);
						mtimes[i] = mtime;
						bury_times[i] = lddates[i];
					}
				}
				dbfree(dbs);
			}
			/*
			 * a call to dbfree(dbt) would remove it from the
			 * list of tablenames, all later calls to tablename
			 * would return NIL...
			 */
			if (Stop) {
				bury();
				return (0);
			}
		}
		sleep(naptime);
		if ((counter + 1) >= check_lddate_interval) {
			counter = 0;
			force_check = 1;
		} else {
			force_check = 0;
			counter++;
		}
		if (statefilename) {
			double          nowtime;

			nowtime = now();
			if (nowtime - lastburytime > 600.0) {
				lastburytime = nowtime;
				bury();
			}
		}
	}
}
void mexFunction ( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
	Dbptr	db;
	Point	*polygon;
	int 	nrec;
	int 	single_record;
	double 	NaN;
	double	*lat;
	double	*lon;
	int		nvertices;
	int 	nsaved,closed;
	int		i,j;
	double  *lat_pr, *lon_pr;
	Expression	*expr;
	int		maxneeded;
	int		sumpoints;
	int		*nanindices;
	char 	closedstr[2];

	
	NaN=mxGetNaN();

	if ( nrhs != 1 ) {
		antelope_mexUsageMsgTxt ( USAGE ); return;
	} else if ( ! get_dbptr( prhs[0], &db ) ) {
		antelope_mexUsageMsgTxt ( USAGE ); return;
	} else if ( nlhs != 2 ) {
		antelope_mexUsageMsgTxt ( USAGE ); return;
	}

	if (dbquery( db, dbRECORD_COUNT, &nrec) < 0) {
		antelope_mex_clear_register( 1 );
		mexErrMsgTxt("readpolygon: dbquery(recordcount) failed\n");
	}
	if (nrec <= 0 ) {
		mexErrMsgTxt("readpolygon: no rows in database view\n");
	}
	if (db.record == dbALL) {
		if (nrec == 1) {
			single_record= 1;
			db.record=0;
			dbgetv(db,0,"npoints",&sumpoints,0);
			maxneeded= (nrec*2) + sumpoints;
		} else {
			single_record=0;
			db.record=0;
			dbex_compile(db,"sum(npoints)",&expr,dbINTEGER);
			dbex_eval(db,expr,0,&sumpoints);
			dbex_free(expr);
			maxneeded= (nrec*2) + sumpoints;
			nanindices=mxCalloc(nrec,sizeof(int));
		}
	} else {
		if (db.record >= 0) {
			single_record= 1;
			dbgetv(db,0,"npoints",&sumpoints,"closed",&closedstr,0);
			maxneeded= (nrec*2) + sumpoints;
		} else {
			mexErrMsgTxt("readpolygon: unspecified subset?!?\n");
		}
	}
	
	nsaved= 0;
	nvertices= readPolygon(db,&polygon);
	lat= mxCalloc(maxneeded+1, sizeof(double));
	lon= mxCalloc(maxneeded+1, sizeof(double));
	for (j= 0; j < nvertices; j++) {
		lat[j]= polygon[j].lat;
		lon[j]= polygon[j].lon;
	}
	nsaved += nvertices;
	free(polygon);
	/* eventually close polygon*/
	if (strncmp(closedstr,"y",1)==0) {
		if ( (lat[nvertices-1] != lat[0]) || (lon[nvertices-1] != lon[0]) ) {
			nsaved++;
			lat[nsaved-1]= lat[0];
			lon[nsaved-1]= lon[0];
		}
	}
	if ( (single_record == 0) && (nrec > 1) ) {
		for (i= 1; i < nrec; i++) {
			db.record=i;
			dbgetv(db,0,"closed",&closedstr,0);
			nvertices= readPolygon(db,&polygon);
			/* separate (sub)polygons by NaN */
			lat[nsaved + 1]=NaN;
			lon[nsaved + 1]=NaN;
			nanindices[i-1]= nsaved+1;
			nsaved++;
			for (j= 0; j < nvertices; j++) {
				lat[j+nsaved]= polygon[j].lat;
				lon[j+nsaved]= polygon[j].lon;
			}
			nsaved += nvertices;
			/* eventually close polygon*/
			if (strncmp(closedstr,"y",1)==0) {
				if ( (lat[nvertices-1] != lat[0]) || (lon[nvertices-1] != lon[0]) ) {
					lat[nsaved]= lat[nsaved-nvertices];
					lon[nsaved]= lon[nsaved-nvertices];
					nsaved++;
				}
			}	
			free(polygon);
		}
	}
	plhs[0] = mxCreateDoubleMatrix(nsaved,1,mxREAL);
	lat_pr=(double *)mxGetPr(plhs[0]);
	memcpy(lat_pr, lat, nsaved*sizeof(double));	
	
	plhs[1] = mxCreateDoubleMatrix(nsaved,1,mxREAL);
	lon_pr=(double *)mxGetPr(plhs[1]);
	memcpy(lon_pr, lon, nsaved*sizeof(double));	
	/* NaN does NOT pass the memcpy */
	if (single_record == 0) {
		for (i=0; i < nrec-1; i++) {
			lat_pr[nanindices[i]-1]=NaN;
			lon_pr[nanindices[i]-1]=NaN;
		}
		mxFree(nanindices);
	}

	mxFree(lat);
	mxFree(lon);
}
示例#3
0
void mexFunction ( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
	Dbptr	db;
	int	single_row;
	long	nrows;
	int	code = 0;
	int	rc = 0;
	char	*expression;
	char	*codestr;
	Expression *expr;
	Dbvalue	exresult;
	double	*pr;

	if( nrhs != 2 && nrhs != 3 )
	{
		antelope_mexUsageMsgTxt ( USAGE );
		return;
	}
        else if( ! get_dbptr( prhs[0], &db ) )
        {
                antelope_mexUsageMsgTxt ( USAGE );
		return;
        }
        else if( ! mtlb_get_string( prhs[1], &expression ) )
        {
                antelope_mexUsageMsgTxt ( USAGE );
		return;
        }
        else if( nrhs == 3 && ! mtlb_get_string( prhs[2], &codestr ) )
        {
		mxFree( expression );
                antelope_mexUsageMsgTxt ( USAGE );
		return;
        }
	else if( nrhs == 3 )
	{
		code = xlatname( codestr, Dbxlat, NDbxlat );
		mxFree( codestr );
	}

	if( dbex_compile( db, expression, &expr, code ) < 0 )
	{
		antelope_mex_clear_register( 1 );
		mxFree( expression );
		mexErrMsgTxt( "dbeval: expression failed to compile\n" );
	}
	else
	{
		antelope_mex_clear_register( 1 );
		mxFree( expression );
	}

	rc = dbquery( db, dbRECORD_COUNT, &nrows );
	antelope_mex_clear_register( 1 );
	if( rc == dbINVALID ) 
	{
		mexErrMsgTxt( "dbgetv: query for number of records failed" );
	}

	if( db.record == dbALL ) {
		if( nrows == 1 ) {
			single_row = 1;
			db.record = 0;
		} else {
			single_row = 0;
		}
	} else {
		single_row = 1;
	}

	if( single_row ) 
	{
		rc = dbex_eval ( db, expr, 1, &exresult ) ;
		antelope_mex_clear_register( 1 );

		if( rc >= 0 )
		{
		   switch( expr->type )
		   {
			case dbBOOLEAN:
			case dbINTEGER:
			case dbYEARDAY:
				plhs[0] = CreateDouble( (double)  exresult.i );
				if( plhs[0] == NULL )
				{
					dbex_free( expr );
					mexErrMsgTxt( 
				   	"dbeval: failed to create return value" );
				}
				break;
			case dbREAL:
			case dbTIME:
				plhs[0] = CreateDouble( exresult.d );
				if( plhs[0] == NULL )
				{
					dbex_free( expr );
					mexErrMsgTxt( 
				   	"dbeval: failed to create return value" );
				}
				break;
			case dbSTRING:
				plhs[0] = mxCreateString( exresult.t );
				free( exresult.t );
				break;
			default:
				dbex_free( expr );
				mexErrMsgTxt( "Unknown type in dbeval\n" );
				break;
		   }
		   dbex_free( expr );
		}
		else
		{
			dbex_free( expr );
			mexErrMsgTxt( "dbeval: eval failed\n" );
		}
	} else {

		db.record = 0;

		rc = dbex_eval ( db, expr, 1, &exresult ) ;
		antelope_mex_clear_register( 1 );

		if( rc >= 0 )
		{
		   switch( expr->type )
		   {
			case dbBOOLEAN:
			case dbINTEGER:
			case dbYEARDAY:
				plhs[0] = mxCreateDoubleMatrix( nrows, 1, mxREAL );
				if( plhs[0] == NULL )
				{
					dbex_free( expr );
					mexErrMsgTxt( 
				   	"dbeval: failed to create return value" );
				}

				pr = mxGetPr( plhs[0] );
				pr[db.record] = (double) exresult.i;

				for( db.record = 1; db.record < nrows; db.record++ )
				{
					if( dbex_eval ( db, expr, 1, &exresult ) < 0 ) 
					{
						antelope_mex_clear_register( 1 );
						dbex_free( expr );
						mxDestroyArray( plhs[0] );
						mexErrMsgTxt( "dbeval: eval failed\n" );
					} else {
						pr[db.record] = (double) exresult.i;
					}
				}

				break;
			case dbREAL:
			case dbTIME:
				plhs[0] = mxCreateDoubleMatrix( nrows, 1, mxREAL );
				if( plhs[0] == NULL )
				{
					dbex_free( expr );
					mexErrMsgTxt( 
				   	"dbeval: failed to create return value" );
				}

				pr = mxGetPr( plhs[0] );
				pr[db.record] = exresult.d;

				for( db.record = 1; db.record < nrows; db.record++ )
				{
					if( dbex_eval ( db, expr, 1, &exresult ) < 0 ) 
					{
						antelope_mex_clear_register( 1 );
						dbex_free( expr );
						mxDestroyArray( plhs[0] );
						mexErrMsgTxt( "dbeval: eval failed\n" );
					} else {
						pr[db.record] = (double) exresult.d;
					}
				}

				break;
			case dbSTRING:
				plhs[0] = mxCreateCellMatrix( nrows, 1 );
				if( plhs[0] == NULL )
				{
					dbex_free( expr );
					mexErrMsgTxt( 
				   	"dbeval: failed to create return value" );
				}

				mxSetCell( plhs[0], db.record, mxCreateString( exresult.t ) );
				free( exresult.t );

				for( db.record = 1; db.record < nrows; db.record++ )
				{
					if( dbex_eval ( db, expr, 1, &exresult ) < 0 ) 
					{
						antelope_mex_clear_register( 1 );
						dbex_free( expr );
						mxDestroyArray( plhs[0] );
						mexErrMsgTxt( "dbeval: eval failed\n" );
					} else {
						mxSetCell( plhs[0], db.record, mxCreateString( exresult.t ) );
						free( exresult.t );
					}
				}

				break;
			default:
				dbex_free( expr );
				mexErrMsgTxt( "Unknown type in dbeval\n" );
				break;
		   }
		   dbex_free( expr );
		}
		else
		{
			dbex_free( expr );
			mexErrMsgTxt( "dbeval: eval failed\n" );
		}
	}
}