1 /*
    2  * WARNING: automatically generated by kwebapp 0.6.0.
    3  * DO NOT EDIT!
    4  */
    5 #include <sys/queue.h>
    6 
    7 #include <assert.h>
    8 #include <stdarg.h>
    9 #include <stdint.h>
   10 #include <stdio.h>
   11 #include <stdlib.h>
   12 #include <string.h>
   13 #include <time.h>
   14 #include <unistd.h>
   15 
   16 #include <ksql.h>
   17 #include <kcgi.h>
   18 #include <kcgijson.h>
   19 
   20 #include "db.h"
   21 
   22 static int
   23 b64_ntop(unsigned char *src, size_t srclength,
   24 	char *target, size_t targsize)
   25 {
   26 	static const char Base64[] =
   27 		"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
   28 		"abcdefghijklmnopqrstuvwxyz0123456789+/";
   29 	static const char Pad64 = '=';
   30 	size_t datalength = 0;
   31 	unsigned char input[3];
   32 	unsigned char output[4];
   33 	size_t i;
   34 
   35 	while (2 < srclength) {
   36 		input[0] = *src++;
   37 		input[1] = *src++;
   38 		input[2] = *src++;
   39 		srclength -= 3;
   40 
   41 		output[0] = input[0] >> 2;
   42 		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
   43 		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
   44 		output[3] = input[2] & 0x3f;
   45 
   46 		if (datalength + 4 > targsize)
   47 			return (-1);
   48 		target[datalength++] = Base64[output[0]];
   49 		target[datalength++] = Base64[output[1]];
   50 		target[datalength++] = Base64[output[2]];
   51 		target[datalength++] = Base64[output[3]];
   52 	}
   53 
   54 	if (0 != srclength) {
   55 		input[0] = input[1] = input[2] = '\0';
   56 		for (i = 0; i < srclength; i++)
   57 			input[i] = *src++;
   58 
   59 		output[0] = input[0] >> 2;
   60 		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
   61 		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
   62 
   63 		if (datalength + 4 > targsize)
   64 			return (-1);
   65 		target[datalength++] = Base64[output[0]];
   66 		target[datalength++] = Base64[output[1]];
   67 		if (srclength == 1)
   68 			target[datalength++] = Pad64;
   69 		else
   70 			target[datalength++] = Base64[output[2]];
   71 		target[datalength++] = Pad64;
   72 	}
   73 	if (datalength >= targsize)
   74 		return (-1);
   75 	target[datalength] = '\0';
   76 	return (datalength);
   77 }
   78 
   79 /*
   80  * All SQL statements we'll later define in "stmts".
   81  */
   82 enum	stmt {
   83 	STMT_COMPANY_BY_UNIQUE_id,
   84 	STMT_COMPANY_BY_SEARCH_0,
   85 	STMT_COMPANY_INSERT,
   86 	STMT_USER_BY_UNIQUE_email,
   87 	STMT_USER_BY_UNIQUE_uid,
   88 	STMT_USER_BY_SEARCH_0,
   89 	STMT_USER_BY_SEARCH_1,
   90 	STMT_USER_BY_SEARCH_2,
   91 	STMT_USER_INSERT,
   92 	STMT_USER_UPDATE_0,
   93 	STMT_USER_UPDATE_1,
   94 	STMT_SESSION_BY_UNIQUE_id,
   95 	STMT_SESSION_BY_SEARCH_0,
   96 	STMT_SESSION_INSERT,
   97 	STMT_SESSION_DELETE_0,
   98 	STMT__MAX
   99 };
  100 
  101 /*
  102  * Our full set of SQL statements.
  103  * We define these beforehand because that's how ksql(3) handles 
  104  * statement generation.
  105  * Notice the "AS" part: this allows for multiple inner joins without 
  106  * ambiguity.
  107  */
  108 static	const char *const stmts[STMT__MAX] = {
  109 	/* STMT_COMPANY_BY_UNIQUE_id */
  110 	"SELECT " DB_SCHEMA_COMPANY(company) " FROM company WHERE company.id = ?",
  111 	/* STMT_COMPANY_BY_SEARCH_0 */
  112 	"SELECT " DB_SCHEMA_COMPANY(company) " FROM company "
  113 		"WHERE company.somenum ISNULL",
  114 	/* STMT_COMPANY_INSERT */
  115 	"INSERT INTO company (name,somenum) VALUES (?,?)",
  116 	/* STMT_USER_BY_UNIQUE_email */
  117 	"SELECT " DB_SCHEMA_USER(user) "," DB_SCHEMA_COMPANY(_a) " FROM user "
  118 		"INNER JOIN company AS _a ON _a.id=user.cid "
  119 		"WHERE user.email = ?",
  120 	/* STMT_USER_BY_UNIQUE_uid */
  121 	"SELECT " DB_SCHEMA_USER(user) "," DB_SCHEMA_COMPANY(_a) " FROM user "
  122 		"INNER JOIN company AS _a ON _a.id=user.cid "
  123 		"WHERE user.uid = ?",
  124 	/* STMT_USER_BY_SEARCH_0 */
  125 	"SELECT " DB_SCHEMA_USER(user) "," DB_SCHEMA_COMPANY(_a) " FROM user "
  126 		"INNER JOIN company AS _a ON _a.id=user.cid "
  127 		"WHERE user.name = ? LIMIT 5",
  128 	/* STMT_USER_BY_SEARCH_1 */
  129 	"SELECT " DB_SCHEMA_USER(user) "," DB_SCHEMA_COMPANY(_a) " FROM user "
  130 		"INNER JOIN company AS _a ON _a.id=user.cid "
  131 		"WHERE user.email = ?",
  132 	/* STMT_USER_BY_SEARCH_2 */
  133 	"SELECT " DB_SCHEMA_USER(user) "," DB_SCHEMA_COMPANY(_a) " FROM user "
  134 		"INNER JOIN company AS _a ON _a.id=user.cid "
  135 		"WHERE user.uid = ? ORDER BY _a.name ASC",
  136 	/* STMT_USER_INSERT */
  137 	"INSERT INTO user (cid,sex,hash,email,image,name) VALUES (?,?,?,?,?,?)",
  138 	/* STMT_USER_UPDATE_0 */
  139 	"UPDATE user SET hash = ? WHERE uid = ?",
  140 	/* STMT_USER_UPDATE_1 */
  141 	"UPDATE user SET email = ? WHERE uid = ?",
  142 	/* STMT_SESSION_BY_UNIQUE_id */
  143 	"SELECT " DB_SCHEMA_SESSION(session) "," DB_SCHEMA_USER(_b) "," DB_SCHEMA_COMPANY(_c) " FROM session "
  144 		"INNER JOIN user AS _b ON _b.uid=session.userid "
  145 		"INNER JOIN company AS _c ON _c.id=_b.cid "
  146 		"WHERE session.id = ?",
  147 	/* STMT_SESSION_BY_SEARCH_0 */
  148 	"SELECT " DB_SCHEMA_SESSION(session) "," DB_SCHEMA_USER(_b) "," DB_SCHEMA_COMPANY(_c) " FROM session "
  149 		"INNER JOIN user AS _b ON _b.uid=session.userid "
  150 		"INNER JOIN company AS _c ON _c.id=_b.cid "
  151 		"WHERE _c.name = ? AND session.mtime = ?",
  152 	/* STMT_SESSION_INSERT */
  153 	"INSERT INTO session (userid,token,mtime) VALUES (?,?,?)",
  154 	/* STMT_SESSION_DELETE_0 */
  155 	"DELETE FROM session WHERE id = ?",
  156 };
  157 
  158 const struct kvalid valid_keys[VALID__MAX] = {
  159 	{ valid_company_name, "company-name" },
  160 	{ valid_company_id, "company-id" },
  161 	{ valid_company_somenum, "company-somenum" },
  162 	{ valid_user_cid, "user-cid" },
  163 	{ valid_user_sex, "user-sex" },
  164 	{ valid_user_hash, "user-hash" },
  165 	{ valid_user_email, "user-email" },
  166 	{ valid_user_image, "user-image" },
  167 	{ valid_user_name, "user-name" },
  168 	{ valid_user_uid, "user-uid" },
  169 	{ valid_session_userid, "session-userid" },
  170 	{ valid_session_token, "session-token" },
  171 	{ valid_session_mtime, "session-mtime" },
  172 	{ valid_session_id, "session-id" },
  173 };
  174 
  175 /*
  176  * Finally, all of the functions we'll use.
  177  */
  178 
  179 void
  180 db_trans_open(struct ksql *p, size_t id, int mode)
  181 {
  182 	if (mode < 0)
  183 		ksql_trans_exclopen(p, id);
  184 	else if (mode > 0)
  185 		ksql_trans_singleopen(p, id);
  186 	else
  187 		ksql_trans_open(p, id);
  188 }
  189 
  190 void
  191 db_trans_rollback(struct ksql *p, size_t id)
  192 {
  193 	ksql_trans_rollback(p, id);
  194 }
  195 
  196 void
  197 db_trans_commit(struct ksql *p, size_t id)
  198 {
  199 	ksql_trans_commit(p, id);
  200 }
  201 
  202 struct ksql *
  203 db_open(const char *file)
  204 {
  205 	struct ksqlcfg cfg;
  206 	struct ksql *db;
  207 
  208 	ksql_cfg_defaults(&cfg);
  209 
  210 	db = ksql_alloc_child(&cfg, NULL, NULL);
  211 	if (NULL == db)
  212 		return(NULL);
  213 	ksql_open(db, file);
  214 	return(db);
  215 }
  216 
  217 void
  218 db_close(struct ksql *p)
  219 {
  220 	if (NULL == p)
  221 		return;
  222 	ksql_close(p);
  223 	ksql_free(p);
  224 }
  225 
  226 void
  227 db_company_fill(struct company *p, struct ksqlstmt *stmt, size_t *pos)
  228 {
  229 	size_t i = 0;
  230 	enum ksqlc c;
  231 
  232 	if (NULL == pos)
  233 		pos = &i;
  234 	memset(p, 0, sizeof(*p));
  235 	c = ksql_result_str_alloc(stmt, &p->name, (*pos)++);
  236 	if (KSQL_OK != c)
  237 		exit(EXIT_FAILURE);
  238 	c = ksql_result_int(stmt, &p->id, (*pos)++);
  239 	if (KSQL_OK != c)
  240 		exit(EXIT_FAILURE);
  241 	p->has_somenum = ! ksql_stmt_isnull(stmt, *pos);
  242 	if (p->has_somenum) {
  243 		c = ksql_result_int(stmt, &p->somenum, (*pos)++);
  244 		if (KSQL_OK != c)
  245 			exit(EXIT_FAILURE);
  246 	} else
  247 		(*pos)++;
  248 }
  249 
  250 static void
  251 db_company_fill_r(struct company *p, struct ksqlstmt *stmt, size_t *pos)
  252 {
  253 	size_t i = 0;
  254 
  255 	if (NULL == pos)
  256 		pos = &i;
  257 	db_company_fill(p, stmt, pos);
  258 }
  259 
  260 void
  261 db_company_unfill(struct company *p)
  262 {
  263 	if (NULL == p)
  264 		return;
  265 	free(p->name);
  266 }
  267 
  268 static void
  269 db_company_unfill_r(struct company *p)
  270 {
  271 	if (NULL == p)
  272 		return;
  273 
  274 	db_company_unfill(p);
  275 }
  276 
  277 void
  278 db_company_free(struct company *p)
  279 {
  280 	db_company_unfill_r(p);
  281 	free(p);
  282 }
  283 
  284 void
  285 db_company_freeq(struct company_q *q)
  286 {
  287 	struct company *p;
  288 
  289 	if (NULL == q)
  290 		return;
  291 	while (NULL != (p = TAILQ_FIRST(q))) {
  292 		TAILQ_REMOVE(q, p, _entries);
  293 		db_company_free(p);
  294 	}
  295 
  296 	free(q);
  297 }
  298 
  299 int64_t
  300 db_company_insert(struct ksql *db, const char *v1, int64_t *v2)
  301 {
  302 	struct ksqlstmt *stmt;
  303 	int64_t id = -1;
  304 
  305 	ksql_stmt_alloc(db, &stmt,
  306 		stmts[STMT_COMPANY_INSERT],
  307 		STMT_COMPANY_INSERT);
  308 	ksql_bind_str(stmt, 0, v1);
  309 	if (NULL == v2)
  310 		ksql_bind_null(stmt, 1);
  311 	else
  312 		ksql_bind_int(stmt, 1, *v2);
  313 	if (KSQL_DONE == ksql_stmt_cstep(stmt))
  314 		ksql_lastid(db, &id);
  315 	ksql_stmt_free(stmt);
  316 	return(id);
  317 }
  318 
  319 void
  320 json_company_data(struct kjsonreq *r, const struct company *p)
  321 {
  322 	kjson_putstringp(r, "name", p->name);
  323 	kjson_putintp(r, "id", p->id);
  324 
  325 	if ( ! p->has_somenum)
  326 		kjson_putnullp(r, "somenum");
  327 	else
  328 		kjson_putintp(r, "somenum", p->somenum);
  329 
  330 }
  331 
  332 void
  333 json_company_obj(struct kjsonreq *r, const struct company *p)
  334 {
  335 	kjson_objp_open(r, "company");
  336 	json_company_data(r, p);
  337 	kjson_obj_close(r);
  338 }
  339 
  340 void
  341 json_company_array(struct kjsonreq *r, const struct company_q *q)
  342 {
  343 	struct company *p;
  344 
  345 	kjson_arrayp_open(r, "company_q");
  346 	TAILQ_FOREACH(p, q, _entries) {
  347 		kjson_obj_open(r);
  348 		json_company_data(r, p);
  349 		kjson_obj_close(r);
  350 	}
  351 	kjson_array_close(r);
  352 }
  353 
  354 int
  355 valid_company_name(struct kpair *p)
  356 {
  357 	if ( ! kvalid_string(p))
  358 		return 0;
  359 	if (p->valsz <= 0)
  360 		return 0;
  361 	return 1;
  362 }
  363 
  364 int
  365 valid_company_id(struct kpair *p)
  366 {
  367 	if ( ! kvalid_int(p))
  368 		return 0;
  369 	return 1;
  370 }
  371 
  372 int
  373 valid_company_somenum(struct kpair *p)
  374 {
  375 	if ( ! kvalid_int(p))
  376 		return 0;
  377 	return 1;
  378 }
  379 
  380 struct company_q *
  381 db_company_list_by_somenum_isnull(struct ksql *db)
  382 {
  383 	struct ksqlstmt *stmt;
  384 	struct company_q *q;
  385 	struct company *p;
  386 
  387 	q = malloc(sizeof(struct company_q));
  388 	if (NULL == q) {
  389 		perror(NULL);
  390 		exit(EXIT_FAILURE);
  391 	}
  392 	TAILQ_INIT(q);
  393 
  394 	ksql_stmt_alloc(db, &stmt,
  395 		stmts[STMT_COMPANY_BY_SEARCH_0],
  396 		STMT_COMPANY_BY_SEARCH_0);
  397 	while (KSQL_ROW == ksql_stmt_step(stmt)) {
  398 		p = malloc(sizeof(struct company));
  399 		if (NULL == p) {
  400 			perror(NULL);
  401 			exit(EXIT_FAILURE);
  402 		}
  403 		db_company_fill_r(p, stmt, NULL);
  404 		TAILQ_INSERT_TAIL(q, p, _entries);
  405 	}
  406 	ksql_stmt_free(stmt);
  407 	return(q);
  408 }
  409 
  410 void
  411 db_user_fill(struct user *p, struct ksqlstmt *stmt, size_t *pos)
  412 {
  413 	size_t i = 0;
  414 	enum ksqlc c;
  415 	int64_t tmpint;
  416 
  417 	if (NULL == pos)
  418 		pos = &i;
  419 	memset(p, 0, sizeof(*p));
  420 	c = ksql_result_int(stmt, &p->cid, (*pos)++);
  421 	if (KSQL_OK != c)
  422 		exit(EXIT_FAILURE);
  423 	c = ksql_result_int(stmt, &tmpint, (*pos)++);
  424 	if (KSQL_OK != c)
  425 		exit(EXIT_FAILURE);
  426 	p->sex = tmpint;
  427 	c = ksql_result_str_alloc(stmt, &p->hash, (*pos)++);
  428 	if (KSQL_OK != c)
  429 		exit(EXIT_FAILURE);
  430 	c = ksql_result_str_alloc(stmt, &p->email, (*pos)++);
  431 	if (KSQL_OK != c)
  432 		exit(EXIT_FAILURE);
  433 	p->has_image = ! ksql_stmt_isnull(stmt, *pos);
  434 	if (p->has_image) {
  435 		c = ksql_result_blob_alloc(stmt, &p->image, &p->image_sz, (*pos)++);
  436 		if (KSQL_OK != c)
  437 			exit(EXIT_FAILURE);
  438 	} else
  439 		(*pos)++;
  440 	c = ksql_result_str_alloc(stmt, &p->name, (*pos)++);
  441 	if (KSQL_OK != c)
  442 		exit(EXIT_FAILURE);
  443 	c = ksql_result_int(stmt, &p->uid, (*pos)++);
  444 	if (KSQL_OK != c)
  445 		exit(EXIT_FAILURE);
  446 }
  447 
  448 static void
  449 db_user_fill_r(struct user *p, struct ksqlstmt *stmt, size_t *pos)
  450 {
  451 	size_t i = 0;
  452 
  453 	if (NULL == pos)
  454 		pos = &i;
  455 	db_user_fill(p, stmt, pos);
  456 	db_company_fill_r(&p->company, stmt, pos);
  457 }
  458 
  459 void
  460 db_user_unfill(struct user *p)
  461 {
  462 	if (NULL == p)
  463 		return;
  464 	free(p->hash);
  465 	free(p->email);
  466 	free(p->image);
  467 	free(p->name);
  468 }
  469 
  470 static void
  471 db_user_unfill_r(struct user *p)
  472 {
  473 	if (NULL == p)
  474 		return;
  475 
  476 	db_user_unfill(p);
  477 	db_company_unfill_r(&p->company);
  478 }
  479 
  480 void
  481 db_user_free(struct user *p)
  482 {
  483 	db_user_unfill_r(p);
  484 	free(p);
  485 }
  486 
  487 int64_t
  488 db_user_insert(struct ksql *db, int64_t v1, enum sex v2, const char *v3,
  489 	const char *v4, size_t v5_sz, const void **v5, const char *v6)
  490 {
  491 	struct ksqlstmt *stmt;
  492 	int64_t id = -1;
  493 	char hash1[64];
  494 
  495 	crypt_newhash(v3, "blowfish,a", hash1, sizeof(hash1));
  496 
  497 	ksql_stmt_alloc(db, &stmt,
  498 		stmts[STMT_USER_INSERT],
  499 		STMT_USER_INSERT);
  500 	ksql_bind_int(stmt, 0, v1);
  501 	ksql_bind_int(stmt, 1, v2);
  502 	ksql_bind_str(stmt, 2, hash1);
  503 	ksql_bind_str(stmt, 3, v4);
  504 	if (NULL == v5)
  505 		ksql_bind_null(stmt, 4);
  506 	else
  507 		ksql_bind_blob(stmt, 4, *v5, v5_sz);
  508 	ksql_bind_str(stmt, 5, v6);
  509 	if (KSQL_DONE == ksql_stmt_cstep(stmt))
  510 		ksql_lastid(db, &id);
  511 	ksql_stmt_free(stmt);
  512 	return(id);
  513 }
  514 
  515 void
  516 json_user_data(struct kjsonreq *r, const struct user *p)
  517 {
  518 	char *buf1;
  519 	size_t sz;
  520 
  521 	/*
  522 	 * We need to base64 encode the binary buffers prior to 
  523 	 * serialisation.
  524 	 * Allocate space for these buffers and do so now.
  525 	 * We'll free the buffers at the epilogue of the function.
  526 	 */
  527 
  528 	sz = (p->image_sz + 2) / 3 * 4 + 1;
  529 	buf1 = malloc(sz);
  530 	if (NULL == buf1) {
  531 		perror(NULL);
  532 		exit(EXIT_FAILURE);
  533 	}
  534 	if (p->has_image)
  535 		b64_ntop(p->image, p->image_sz, buf1, sz);
  536 
  537 	kjson_objp_open(r, "company");
  538 	json_company_data(r, &p->company);
  539 	kjson_obj_close(r);
  540 	kjson_putintp(r, "cid", p->cid);
  541 	kjson_putintp(r, "sex", p->sex);
  542 
  543 	/* Omitting hash: is a password hash. */
  544 
  545 	kjson_putstringp(r, "email", p->email);
  546 
  547 	if ( ! p->has_image)
  548 		kjson_putnullp(r, "image");
  549 	else
  550 		kjson_putstringp(r, "image", buf1);
  551 
  552 	kjson_putstringp(r, "name", p->name);
  553 	kjson_putintp(r, "uid", p->uid);
  554 
  555 	free(buf1);
  556 }
  557 
  558 void
  559 json_user_obj(struct kjsonreq *r, const struct user *p)
  560 {
  561 	kjson_objp_open(r, "user");
  562 	json_user_data(r, p);
  563 	kjson_obj_close(r);
  564 }
  565 
  566 void
  567 json_user_iterate(const struct user *p, void *arg)
  568 {
  569 	struct kjsonreq *r = arg;
  570 
  571 	kjson_obj_open(r);
  572 	json_user_data(r, p);
  573 	kjson_obj_close(r);
  574 }
  575 
  576 int
  577 valid_user_cid(struct kpair *p)
  578 {
  579 	if ( ! kvalid_int(p))
  580 		return 0;
  581 	return 1;
  582 }
  583 
  584 int
  585 valid_user_sex(struct kpair *p)
  586 {
  587 	if ( ! kvalid_int(p))
  588 		return 0;
  589 	switch(p->parsed.i) {
  590 	case 0:
  591 	case 1:
  592 	case 2:
  593 		break;
  594 	default:
  595 		return 0;
  596 	}
  597 	return 1;
  598 }
  599 
  600 int
  601 valid_user_hash(struct kpair *p)
  602 {
  603 	if ( ! kvalid_string(p))
  604 		return 0;
  605 	if (p->valsz <= 0)
  606 		return 0;
  607 	return 1;
  608 }
  609 
  610 int
  611 valid_user_email(struct kpair *p)
  612 {
  613 	if ( ! kvalid_email(p))
  614 		return 0;
  615 	return 1;
  616 }
  617 
  618 int
  619 valid_user_image(struct kpair *p)
  620 {
  621 	return 1;
  622 }
  623 
  624 int
  625 valid_user_name(struct kpair *p)
  626 {
  627 	if ( ! kvalid_string(p))
  628 		return 0;
  629 	return 1;
  630 }
  631 
  632 int
  633 valid_user_uid(struct kpair *p)
  634 {
  635 	if ( ! kvalid_int(p))
  636 		return 0;
  637 	return 1;
  638 }
  639 
  640 void
  641 db_user_iterate_by_name_eq(struct ksql *db, user_cb cb, void *arg, const char *v1)
  642 {
  643 	struct ksqlstmt *stmt;
  644 	struct user p;
  645 
  646 	ksql_stmt_alloc(db, &stmt,
  647 		stmts[STMT_USER_BY_SEARCH_0],
  648 		STMT_USER_BY_SEARCH_0);
  649 	ksql_bind_str(stmt, 0, v1);
  650 	while (KSQL_ROW == ksql_stmt_step(stmt)) {
  651 		db_user_fill_r(&p, stmt, NULL);
  652 		(*cb)(&p, arg);
  653 		db_user_unfill_r(&p);
  654 	}
  655 	ksql_stmt_free(stmt);
  656 }
  657 
  658 struct user *
  659 db_user_get_creds(struct ksql *db, const char *v1, const char *v2)
  660 {
  661 	struct ksqlstmt *stmt;
  662 	struct user *p = NULL;
  663 
  664 	ksql_stmt_alloc(db, &stmt,
  665 		stmts[STMT_USER_BY_SEARCH_1],
  666 		STMT_USER_BY_SEARCH_1);
  667 	ksql_bind_str(stmt, 0, v1);
  668 	if (KSQL_ROW == ksql_stmt_step(stmt)) {
  669 		p = malloc(sizeof(struct user));
  670 		if (NULL == p) {
  671 			perror(NULL);
  672 			exit(EXIT_FAILURE);
  673 		}
  674 		db_user_fill_r(p, stmt, NULL);
  675 		if (NULL != p && (crypt_checkpass(v2, p->hash) < 0)) {
  676 			db_user_free(p);
  677 			p = NULL;
  678 		}
  679 	}
  680 	ksql_stmt_free(stmt);
  681 	return p;
  682 }
  683 
  684 struct user *
  685 db_user_get_by_uid_eq(struct ksql *db, int64_t v1)
  686 {
  687 	struct ksqlstmt *stmt;
  688 	struct user *p = NULL;
  689 
  690 	ksql_stmt_alloc(db, &stmt,
  691 		stmts[STMT_USER_BY_SEARCH_2],
  692 		STMT_USER_BY_SEARCH_2);
  693 	ksql_bind_int(stmt, 0, v1);
  694 	if (KSQL_ROW == ksql_stmt_step(stmt)) {
  695 		p = malloc(sizeof(struct user));
  696 		if (NULL == p) {
  697 			perror(NULL);
  698 			exit(EXIT_FAILURE);
  699 		}
  700 		db_user_fill_r(p, stmt, NULL);
  701 	}
  702 	ksql_stmt_free(stmt);
  703 	return p;
  704 }
  705 
  706 int
  707 db_user_update_hash_by_uid_eq(struct ksql *db, const char *v1, int64_t v2)
  708 {
  709 	struct ksqlstmt *stmt;
  710 	enum ksqlc c;
  711 	char hash1[64];
  712 
  713 	crypt_newhash(v1, "blowfish,a", hash1, sizeof(hash1));
  714 
  715 	ksql_stmt_alloc(db, &stmt,
  716 		stmts[STMT_USER_UPDATE_0],
  717 		STMT_USER_UPDATE_0);
  718 	ksql_bind_str(stmt, 0, hash1);
  719 	ksql_bind_int(stmt, 1, v2);
  720 	c = ksql_stmt_cstep(stmt);
  721 	ksql_stmt_free(stmt);
  722 	return(KSQL_CONSTRAINT != c);
  723 }
  724 
  725 int
  726 db_user_update_email_by_uid_eq(struct ksql *db, const char *v1, int64_t v2)
  727 {
  728 	struct ksqlstmt *stmt;
  729 	enum ksqlc c;
  730 
  731 	ksql_stmt_alloc(db, &stmt,
  732 		stmts[STMT_USER_UPDATE_1],
  733 		STMT_USER_UPDATE_1);
  734 	ksql_bind_str(stmt, 0, v1);
  735 	ksql_bind_int(stmt, 1, v2);
  736 	c = ksql_stmt_cstep(stmt);
  737 	ksql_stmt_free(stmt);
  738 	return(KSQL_CONSTRAINT != c);
  739 }
  740 
  741 void
  742 db_session_fill(struct session *p, struct ksqlstmt *stmt, size_t *pos)
  743 {
  744 	size_t i = 0;
  745 	enum ksqlc c;
  746 
  747 	if (NULL == pos)
  748 		pos = &i;
  749 	memset(p, 0, sizeof(*p));
  750 	c = ksql_result_int(stmt, &p->userid, (*pos)++);
  751 	if (KSQL_OK != c)
  752 		exit(EXIT_FAILURE);
  753 	c = ksql_result_int(stmt, &p->token, (*pos)++);
  754 	if (KSQL_OK != c)
  755 		exit(EXIT_FAILURE);
  756 	c = ksql_result_int(stmt, &p->mtime, (*pos)++);
  757 	if (KSQL_OK != c)
  758 		exit(EXIT_FAILURE);
  759 	c = ksql_result_int(stmt, &p->id, (*pos)++);
  760 	if (KSQL_OK != c)
  761 		exit(EXIT_FAILURE);
  762 }
  763 
  764 static void
  765 db_session_fill_r(struct session *p, struct ksqlstmt *stmt, size_t *pos)
  766 {
  767 	size_t i = 0;
  768 
  769 	if (NULL == pos)
  770 		pos = &i;
  771 	db_session_fill(p, stmt, pos);
  772 	db_user_fill_r(&p->user, stmt, pos);
  773 }
  774 
  775 void
  776 db_session_unfill(struct session *p)
  777 {
  778 	if (NULL == p)
  779 		return;
  780 }
  781 
  782 static void
  783 db_session_unfill_r(struct session *p)
  784 {
  785 	if (NULL == p)
  786 		return;
  787 
  788 	db_session_unfill(p);
  789 	db_user_unfill_r(&p->user);
  790 }
  791 
  792 void
  793 db_session_free(struct session *p)
  794 {
  795 	db_session_unfill_r(p);
  796 	free(p);
  797 }
  798 
  799 int64_t
  800 db_session_insert(struct ksql *db, int64_t v1, int64_t v2, time_t v3)
  801 {
  802 	struct ksqlstmt *stmt;
  803 	int64_t id = -1;
  804 
  805 	ksql_stmt_alloc(db, &stmt,
  806 		stmts[STMT_SESSION_INSERT],
  807 		STMT_SESSION_INSERT);
  808 	ksql_bind_int(stmt, 0, v1);
  809 	ksql_bind_int(stmt, 1, v2);
  810 	ksql_bind_int(stmt, 2, v3);
  811 	if (KSQL_DONE == ksql_stmt_cstep(stmt))
  812 		ksql_lastid(db, &id);
  813 	ksql_stmt_free(stmt);
  814 	return(id);
  815 }
  816 
  817 void
  818 json_session_data(struct kjsonreq *r, const struct session *p)
  819 {
  820 	kjson_objp_open(r, "user");
  821 	json_user_data(r, &p->user);
  822 	kjson_obj_close(r);
  823 	kjson_putintp(r, "userid", p->userid);
  824 	kjson_putintp(r, "token", p->token);
  825 	kjson_putintp(r, "mtime", p->mtime);
  826 	kjson_putintp(r, "id", p->id);
  827 }
  828 
  829 void
  830 json_session_obj(struct kjsonreq *r, const struct session *p)
  831 {
  832 	kjson_objp_open(r, "session");
  833 	json_session_data(r, p);
  834 	kjson_obj_close(r);
  835 }
  836 
  837 void
  838 json_session_iterate(const struct session *p, void *arg)
  839 {
  840 	struct kjsonreq *r = arg;
  841 
  842 	kjson_obj_open(r);
  843 	json_session_data(r, p);
  844 	kjson_obj_close(r);
  845 }
  846 
  847 int
  848 valid_session_userid(struct kpair *p)
  849 {
  850 	if ( ! kvalid_int(p))
  851 		return 0;
  852 	return 1;
  853 }
  854 
  855 int
  856 valid_session_token(struct kpair *p)
  857 {
  858 	if ( ! kvalid_int(p))
  859 		return 0;
  860 	return 1;
  861 }
  862 
  863 int
  864 valid_session_mtime(struct kpair *p)
  865 {
  866 	if ( ! kvalid_int(p))
  867 		return 0;
  868 	return 1;
  869 }
  870 
  871 int
  872 valid_session_id(struct kpair *p)
  873 {
  874 	if ( ! kvalid_int(p))
  875 		return 0;
  876 	return 1;
  877 }
  878 
  879 void
  880 db_session_iterate_foo(struct ksql *db, session_cb cb, void *arg, const char *v1,
  881 	time_t v2)
  882 {
  883 	struct ksqlstmt *stmt;
  884 	struct session p;
  885 
  886 	ksql_stmt_alloc(db, &stmt,
  887 		stmts[STMT_SESSION_BY_SEARCH_0],
  888 		STMT_SESSION_BY_SEARCH_0);
  889 	ksql_bind_str(stmt, 0, v1);
  890 	ksql_bind_int(stmt, 1, v2);
  891 	while (KSQL_ROW == ksql_stmt_step(stmt)) {
  892 		db_session_fill_r(&p, stmt, NULL);
  893 		(*cb)(&p, arg);
  894 		db_session_unfill_r(&p);
  895 	}
  896 	ksql_stmt_free(stmt);
  897 }
  898 
  899 int
  900 db_session_delete_by_id_eq(struct ksql *db, int64_t v1)
  901 {
  902 	struct ksqlstmt *stmt;
  903 	enum ksqlc c;
  904 
  905 	ksql_stmt_alloc(db, &stmt,
  906 		stmts[STMT_SESSION_DELETE_0],
  907 		STMT_SESSION_DELETE_0);
  908 	ksql_bind_int(stmt, 0, v1);
  909 	c = ksql_stmt_cstep(stmt);
  910 	ksql_stmt_free(stmt);
  911 	return(KSQL_CONSTRAINT != c);
  912 }
  913