⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sqlite3odbc.c

📁 定时器for timer for ic chip
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (!q || q == p) {
	    if (*q == '\0') {
		if (i == 0) {
		    err = 1;
		}
		goto done;
	    }
	}
	if (*q == '-' || *q == '/' || *q == '\0' || i == 2) {
	    switch (i) {
	    case 0: ds->year = n; break;
	    case 1: ds->month = n; break;
	    case 2: ds->day = n; break;
	    }
	    ++i;
	    if (*q) {
		++q;
	    }
	} else {
	    i = 0;
	    while (*q && !ISDIGIT(*q)) {
		++q;
	    }
	}
	p = q;
    }
done:
    /* final check for overflow */
    if (err ||
	ds->month < 1 || ds->month > 12 ||
	ds->day < 1 || ds->day > getmdays(ds->year, ds->month)) {
	return -1;
    }
    return 0;
}

/**
 * Convert string to ODBC TIME_STRUCT.
 * @param str string to be converted
 * @param ts output TIME_STRUCT
 * @result 0 on success, -1 on error
 *
 * Strings of the format 'HHMMSS' or 'HH:MM:SS'
 * are converted to a TIME_STRUCT.
 */

static int
str2time(char *str, TIME_STRUCT *ts)
{
    int i, err = 0;
    char *p, *q;

    ts->hour = ts->minute = ts->second = 0;
    p = str;
    while (*p && !ISDIGIT(*p)) {
	++p;
    }
    q = p;
    i = 0;
    while (*q && ISDIGIT(*q)) {
	++i;
	++q;
    }
    if (i >= 6) {
	char buf[4];

	strncpy(buf, p + 0, 2); buf[2] = '\0';
	ts->hour = strtol(buf, NULL, 10);
	strncpy(buf, p + 2, 2); buf[2] = '\0';
	ts->minute = strtol(buf, NULL, 10);
	strncpy(buf, p + 4, 2); buf[2] = '\0';
	ts->second = strtol(buf, NULL, 10);
	goto done;
    }
    i = 0;
    while (i < 3) {
	int n;

	q = NULL; 
	n = strtol(p, &q, 10);
	if (!q || q == p) {
	    if (*q == '\0') {
		if (i == 0) {
		    err = 1;
		}
		goto done;
	    }
	}
	if (*q == ':' || *q == '\0' || i == 2) {
	    switch (i) {
	    case 0: ts->hour = n; break;
	    case 1: ts->minute = n; break;
	    case 2: ts->second = n; break;
	    }
	    ++i;
	    if (*q) {
		++q;
	    }
	} else {
	    i = 0;
	    while (*q && !ISDIGIT(*q)) {
		++q;
	    }
	}
	p = q;
    }
done:
    /* final check for overflow */
    if (err || ts->hour > 23 || ts->minute > 59 || ts->second > 59) {
	return -1;
    }
    return 0;
}

/**
 * Convert string to ODBC TIMESTAMP_STRUCT.
 * @param str string to be converted
 * @param tss output TIMESTAMP_STRUCT
 * @result 0 on success, -1 on error
 *
 * Strings of the format 'YYYYMMDDhhmmssff' or 'YYYY-MM-DD hh:mm:ss ff'
 * or 'YYYY/MM/DD hh:mm:ss ff' or 'hh:mm:ss ff YYYY-MM-DD' are
 * converted to a TIMESTAMP_STRUCT. The ISO8601 formats
 *    YYYY-MM-DDThh:mm:ss[.f]Z
 *    YYYY-MM-DDThh:mm:ss[.f]shh:mm
 * are also supported. In case a time zone field is present,
 * the resulting TIMESTAMP_STRUCT is expressed in UTC.
 */

static int
str2timestamp(char *str, TIMESTAMP_STRUCT *tss)
{
    int i, m, n, err = 0;
    char *p, *q, in = '\0';

    tss->year = tss->month = tss->day = 0;
    tss->hour = tss->minute = tss->second = 0;
    tss->fraction = 0;
    p = str;
    while (*p && !ISDIGIT(*p)) {
	++p;
    }
    q = p;
    i = 0;
    while (*q && ISDIGIT(*q)) {
	++i;
	++q;
    }
    if (i >= 14) {
	char buf[16];

	strncpy(buf, p + 0, 4); buf[4] = '\0';
	tss->year = strtol(buf, NULL, 10);
	strncpy(buf, p + 4, 2); buf[2] = '\0';
	tss->month = strtol(buf, NULL, 10);
	strncpy(buf, p + 6, 2); buf[2] = '\0';
	tss->day = strtol(buf, NULL, 10);
	strncpy(buf, p + 8, 2); buf[2] = '\0';
	tss->hour = strtol(buf, NULL, 10);
	strncpy(buf, p + 10, 2); buf[2] = '\0';
	tss->minute = strtol(buf, NULL, 10);
	strncpy(buf, p + 12, 2); buf[2] = '\0';
	tss->second = strtol(buf, NULL, 10);
	if (i > 14) {
	    m = i - 14;
	    strncpy(buf, p + 14, m);
	    while (m < 9) {
		buf[m] = '0';
		++m;
	    }
	    buf[m] = '\0';
	    tss->fraction = strtol(buf, NULL, 0);
	}
	m = 7;
	goto done;
    }
    m = i = 0;
    while ((m & 7) != 7) {
	q = NULL; 
	n = strtol(p, &q, 10);
	if (!q || q == p) {
	    if (*q == '\0') {
		if (m < 1) {
		    err = 1;
		}
		goto done;
	    }
	}
	if (in == '\0') {
	    switch (*q) {
	    case '-':
	    case '/':
		if ((m & 1) == 0) {
		    in = *q;
		    i = 0;
		}
		break;
	    case ':':
		if ((m & 2) == 0) {
		    in = *q;
		    i = 0;
		}
		break;
	    case ' ':
	    case '.':
		break;
	    default:
		in = '\0';
		i = 0;
		break;
	    }
	}
	switch (in) {
	case '-':
	case '/':
	    switch (i) {
	    case 0: tss->year = n; break;
	    case 1: tss->month = n; break;
	    case 2: tss->day = n; break;
	    }
	    if (++i >= 3) {
		i = 0;
		m |= 1;
		if (!(m & 2)) {
		    m |= 8;
		}
		goto skip;
	    } else {
		++q;
	    }
	    break;
	case ':':
	    switch (i) {
	    case 0: tss->hour = n; break;
	    case 1: tss->minute = n; break;
	    case 2: tss->second = n; break;
	    }
	    if (++i >= 3) {
		i = 0;
		m |= 2;
		if (*q == '.') {
		    in = '.';
		    goto skip2;
		}
		if (*q == ' ') {
		    if ((m & 1) == 0) {
			char *e = NULL;
			int dummy;

			dummy = strtol(q + 1, &e, 10);
			if (e && *e == '-') {
			    goto skip;
			}
		    }
		    in = '.';
		    goto skip2;
		}
		goto skip;
	    } else {
		++q;
	    }
	    break;
	case '.':
	    if (++i >= 1) {
		int ndig = q - p;

		if (p[0] == '+' || p[0] == '-') {
		    ndig--;
		}
		while (ndig < 9) {
		    n = n * 10;
		    ++ndig;
		}
		tss->fraction = n;
		m |= 4;
		i = 0;
	    }
	default:
	skip:
	    in = '\0';
	skip2:
	    while (*q && !ISDIGIT(*q)) {
		++q;
	    }
	}
	p = q;
    }
    if ((m & 7) > 1 && (m & 8)) {
	/* ISO8601 timezone */
	if (p > str && ISDIGIT(*p)) {
	    int nn, sign;

	    q = p - 1;
	    if (*q != '+' && *q != '-') {
		goto done;
	    }
	    sign = (*q == '+') ? -1 : 1;
	    q = NULL;
	    n = strtol(p, &q, 10);
	    if (!q || *q++ != ':' || !ISDIGIT(*q)) {
		goto done;
	    }
	    p = q;
	    q = NULL;
	    nn = strtol(p, &q, 0);
	    tss->minute += nn * sign;
	    if ((SQLSMALLINT) tss->minute < 0) {
		tss->hour -= 1;
		tss->minute += 60;
	    } else if (tss->minute >= 60) {
		tss->hour += 1;
		tss->minute -= 60;
	    }
	    tss->hour += n * sign;
	    if ((SQLSMALLINT) tss->hour < 0) {
		tss->day -= 1;
		tss->hour += 24;
	    } else if (tss->hour >= 24) {
		tss->day += 1;
		tss->hour -= 24;
	    }
	    if ((short) tss->day < 1 || tss->day >= 28) {
		int mday, pday, pmon;

		mday = getmdays(tss->year, tss->month);
		pmon = tss->month - 1;
		if (pmon < 1) {
		    pmon = 12;
		}
		pday = getmdays(tss->year, pmon);
		if ((SQLSMALLINT) tss->day < 1) {
		    tss->month -= 1;
		    tss->day = pday;
		} else if (tss->day > mday) {
		    tss->month += 1;
		    tss->day = 1;
		}
		if ((SQLSMALLINT) tss->month < 1) {
		    tss->year -= 1;
		    tss->month = 12;
		} else if (tss->month > 12) {
		    tss->year += 1;
		    tss->month = 1;
		}
	    }
	}
    }
done:
    /* final check for overflow */
    if (err ||
	tss->month < 1 || tss->month > 12 ||
	tss->day < 1 || tss->day > getmdays(tss->year, tss->month) ||
	tss->hour > 23 || tss->minute > 60 || tss->second > 60) {
	return -1;
    }
    return ((m & 7) < 1) ? -1 : 0;
}

/**
 * Get boolean flag from string.
 * @param string string to be inspected
 * @result true or false
 */

static int
getbool(char *string)
{
    if (string) {
	return string[0] && strchr("Yy123456789Tt", string[0]) != NULL;
    }
    return 0;
}

/**
 * SQLite trace callback
 * @param arg DBC pointer
 * @param msg log message, SQL text
 */

static void
dbtrace(void *arg, const char *msg)
{
    DBC *d = (DBC *) arg;

    if (msg && d->trace) {
	int len = strlen(msg);

	if (len > 0) {
	    char *end = "\n";

	    if (msg[len - 1] != ';') {
		end = ";\n";
	    }
	    fprintf(d->trace, "%s%s", msg, end);
	    fflush(d->trace);
	}
    }
}

/**
 * Trace function for SQLite API calls
 * @param d pointer to database connection handle
 * @param fn SQLite function name
 * @param sql SQL string
 */

static void
dbtraceapi(DBC *d, char *fn, const char *sql)
{
    if (fn && d->trace) {
	if (sql) {
	    fprintf(d->trace, "-- %s: %s\n", fn, sql);
	} else {
	    fprintf(d->trace, "-- %s\n", fn);
	}
	fflush(d->trace);
    }
}

/**
 * Trace function for SQLite return codes
 * @param d pointer to database connection handle
 * @param rc SQLite return code
 * @param err error string or NULL
 */

static void
dbtracerc(DBC *d, int rc, char *err)
{
    if (rc != SQLITE_OK && d->trace) {
	fprintf(d->trace, "-- SQLITE ERROR CODE %d", rc);
	fprintf(d->trace, err ? ": %s\n" : "\n", err);
	fflush(d->trace);
    }
}

/**
 * Open SQLite database file given file name and flags.
 * @param d DBC pointer
 * @param name file name
 * @param isu true/false: file name is UTF8 encoded
 * @param dsn data source name
 * @param sflag STEPAPI flag
 * @param spflag SyncPragma string
 * @param ntflag NoTransaction string
 * @param busy busy/lock timeout
 * @result ODBC error code
 */

static SQLRETURN
dbopen(DBC *d, char *name, char *pass, int isu, char *dsn, char *sflag,
       char *spflag, char *ntflag, char *busy)
{
    char *endp = NULL;
    int rc, tmp, busyto = 100000;
#if defined(HAVE_SQLITE3VFS) && HAVE_SQLITE3VFS
    int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
    char *uname = name;
    const char *vfs_name = NULL;
#endif

    if (d->sqlite) {
	if (strcmp(d->dbpass,d->dboldpass)!=0) {
	  if (strcmp(d->dbpass,"NULL")==0) {
	    sqlite3_rekey(d->sqlite, "", 0);
	  }else{
	    sqlite3_rekey(d->sqlite, d->dbpass, strlen(d->dbpass));
	  }
	    freep(&d->dboldpass);
	    d->dboldpass = xstrdup(d->dbpass);
	}
	if (d->trace) {
	    fprintf(d->trace, "-- sqlite3_close (deferred): '%s'\n",
		    d->dbname);
	    fflush(d->trace);
	}
	sqlite3_close(d->sqlite);
	d->sqlite = NULL;
    }
#if defined(HAVE_SQLITE3VFS) && HAVE_SQLITE3VFS
    if (d->nocreat) {
	flags &= ~ SQLITE_OPEN_CREATE;
    }
#ifdef _WIN32
    if (!isu) {
	uname = wmb_to_utf(name, -1);
	if (!uname) {
	    rc = SQLITE_NOMEM;
	    setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
	    return SQL_ERROR;
	}
    }
#endif
#if defined(ENABLE_NVFS) && ENABLE_NVFS
    vfs_name = nvfs_makevfs(uname);
#endif
    rc = sqlite3_open_v2(uname, &d->sqlite, flags, vfs_name);
#if defined(WINTERFACE) || defined(_WIN32)
    if (uname != name) {
	uc_free(uname);
    }
#endif
#else
#ifdef _WIN32
    if (d->nocreat) {
	char *cname = NULL;

	if (isu) {
	    cname = utf_to_wmb(name, -1);
	}
	if (GetFileAttributesA(cname ? cname : name) == 0xffffffff) {
	    uc_free(cname);
	    rc = SQLITE_CANTOPEN;
	    setstatd(d, rc, "cannot open database",
		     (*d->ov3) ? "HY000" : "S1000");
	    return SQL_ERROR;
	}
	uc_free(cname);
    }
#else
    if (d->nocreat && access(name, 004) < 0) {
	rc = SQLITE_CANTOPEN;
	setstatd(d, rc, "cannot open database", (*d->ov3) ? "HY000" : "S1000");
	return SQL_ERROR;
    }
#endif
#ifdef _WIN32
    if (!isu) {
	WCHAR *wname = wmb_to_uc(name, -1);

	if (!wname) {
	    rc = SQLITE_NOMEM;
	    setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
	    return SQL_ERROR;
	}
	rc = sqlite3_open16(wname, &d->sqlite);
	uc_free(wname);
    } else
#endif
    rc = sqlite3_open(name, &d->sqlite);
#endif /* !HAVE_SQLITE3VFS */
    if (rc != SQLITE_OK) {
connfail:
	setstatd(d, rc, "connect failed", (*d->ov3) ? "HY000" : "S1000");
	if (d->sqlite) {
	    sqlite3_close(d->sqlite);
	    d->sqlite = NULL;
	}
	return SQL_ERROR;
    }
    if (strlen(pass) > 0) sqlite3_key(d->sqlite, pass, strlen(pass));
    if (d->trace) {
	sqlite3_trace(d->sqlite, dbtrace, d);
    }
    d->step_enable = getbool(sflag);
    d->trans_disable = getbool(ntflag);
    d->curtype = d->step_enable ?
	SQL_CURSOR_FORWARD_ONLY : SQL_CURSOR_STATIC;
    tmp = strtol(busy, &endp, 0);
    if (endp && *endp == '\0' && endp != busy) {
	busyto = tmp;
    }
    if (busyto < 1 || busyto > 1000000) {
	busyto = 1000000;
    }
    d->timeout = busyto;
    if ((rc = setsqliteopts(d->sqlite, d)) != SQLITE_OK) {
	if (d->trace) {
	    fprintf(d->trace, "-- sqlite3_close: '%s'\n",
		    d->dbname);
	    fflush(d->trace);
	}
	sqlite3_close(d->sqlite);
	d->sqlite = NULL;
	goto connfail;
    }
    if (!spflag || spflag[0] == '\0') {
	spflag = "NORMAL";
    }
    if (spflag[0] != '\0') {
	char syncp[128];

	sprintf(syncp, "PRAGMA synchronous = %8.8s;", spflag);
	sqlite3_exec(d->sqlite, syncp, NULL, NULL, NULL);
    }
    freep(&d->dbname);
    d->dbname = xstrdup(name);
    freep(&d->dsn);
    d->dsn = xstrdup(dsn);
    freep(&d->dbpass)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -