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); }
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" ); } } }