return ans.release ();
}
+MNode* MLSqlite3::answer_vector () {
+ MNodePtr ans;
+ int i;
+
+ ans = newMNode_vector ();
+ if (isReady ()) {
+ for (i = 0; i < ncols; i ++) {
+ if (sqlite3_column_type (dbst, i) == SQLITE_NULL) {
+ ans ()->vectorPush (NULL);
+ } else {
+ ans ()->vectorPush (newMNode_str (new ustring (char_type (sqlite3_column_text (dbst, i)), sqlite3_column_bytes (dbst, i))));
+ }
+ }
+ }
+ finalize ();
+ return ans.release ();
+}
+
+MNode* MLSqlite3::answer_vector_ary () {
+ MNodePtr ans;
+ int i, n;
+ MNodePtr list;
+
+ ans = newMNode_vector ();
+ n = 0;
+ while (isReady ()) {
+ list = newMNode_vector ();
+ n ++;
+ for (i = 0; i < ncols; i ++) {
+ if (sqlite3_column_type (dbst, i) == SQLITE_NULL) {
+ list ()->vectorPush (NULL);
+ } else {
+ list ()->vectorPush (newMNode_str (new ustring (char_type (sqlite3_column_text (dbst, i)), sqlite3_column_bytes (dbst, i))));
+ }
+ }
+ ans ()->vectorPush (list.release ());
+ if (n >= limit && limit > 0)
+ break;
+ step ();
+ }
+
+ return ans.release ();
+}
+
sqlite3_int64 MLSqlite3::rowid () {
return sqlite3_last_insert_rowid (dbh);
}
}
obj->exec ();
if (obj->isReady ()) {
- if (par.answerisary) {
- ans = obj->answer_list_ary ();
- } else {
+ switch (par.answertype) {
+ case MLSqlite3::fsqlParam::COL_LIST:
ans = obj->answer_list ();
+ break;
+ case MLSqlite3::fsqlParam::COL_LIST_LIST:
+ ans = obj->answer_list_ary ();
+ break;
+ case MLSqlite3::fsqlParam::COL_VECTOR:
+ ans = obj->answer_vector ();
+ break;
+ case MLSqlite3::fsqlParam::COL_VECTOR_VECTOR:
+ ans = obj->answer_vector_ary ();
+ break;
}
}
} else { // ! SQLITE_OK
MNode* ml_sqlite3_sql (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
MLSqlite3::fsqlParam par;
+ par.answertype = MLSqlite3::fsqlParam::COL_LIST;
return ml_sqlite3_sql_main (cell, mlenv, par, mobj);
}
MNode* ml_sqlite3_sql_ary (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
MLSqlite3::fsqlParam par;
- par.answerisary = 1;
+ par.answertype = MLSqlite3::fsqlParam::COL_LIST_LIST;
+ return ml_sqlite3_sql_main (cell, mlenv, par, mobj);
+}
+
+/*DOC:
+====sqlv====
+ (sqlv QUERY [:bind '((NAME . VALUE)...)]) -> VECTOR
+ (sqlv@ QUERY [:bind '((NAME . VALUE)...)]) -> VECTOR_OF_VECTOR
+
+*/
+//#SFUNC sqlv ml_sqlite3_sqlv
+//#SFUNC sqlv@ ml_sqlite3_sqlv_ary
+MNode* ml_sqlite3_sqlv (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
+ MLSqlite3::fsqlParam par;
+
+ par.answertype = MLSqlite3::fsqlParam::COL_VECTOR;
+ return ml_sqlite3_sql_main (cell, mlenv, par, mobj);
+}
+MNode* ml_sqlite3_sqlv_ary (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
+ MLSqlite3::fsqlParam par;
+
+ par.answertype = MLSqlite3::fsqlParam::COL_VECTOR_VECTOR;
return ml_sqlite3_sql_main (cell, mlenv, par, mobj);
}
ustring sql;
MLSqlite3::namearray bindName;
MLSqlite3::namearray bindValue;
- bool answerisary;
+ enum {
+ COL_LIST,
+ COL_LIST_LIST,
+ COL_VECTOR,
+ COL_VECTOR_VECTOR,
+ } answertype;
fsqlParam () {
- answerisary = false;
+ answertype = COL_LIST;
};
virtual ~fsqlParam () {};
};
};
virtual MNode* answer_list ();
virtual MNode* answer_list_ary ();
+ virtual MNode* answer_vector ();
+ virtual MNode* answer_vector_ary ();
virtual sqlite3_int64 rowid ();
virtual void postError (ustring msg);
// virtual int sql (ustring query);
MNode* ml_sqlite3 (MNode* cell, MlEnv* mlenv);
MNode* ml_sqlite3_sql (MNode* cell, MlEnv* mlenv, MLFunc* mobj);
MNode* ml_sqlite3_sql_ary (MNode* cell, MlEnv* mlenv, MLFunc* mobj);
+MNode* ml_sqlite3_sqlv (MNode* cell, MlEnv* mlenv, MLFunc* mobj);
+MNode* ml_sqlite3_sqlv_ary (MNode* cell, MlEnv* mlenv, MLFunc* mobj);
MNode* ml_sqlite3_rowid (MNode* cell, MlEnv* mlenv, MLFunc* mobj);
MNode* ml_sqlite3_escape_like (MNode* cell, MlEnv* mlenv, MLFunc* mobj);
MNode* ml_sqlite3_begin_transaction (MNode* cell, MlEnv* mlenv, MLFunc* mobj);
}
/*DOC:
+===tail-substring===
+ (tail-substring STR INDEX LENGTH) -> STRING
+ (tail-substring STR INDEX) -> STRING
+
+INDEX number of the last character of STR is 0.
+
+*/
+//#AFUNC tail-substring ml_tail_substring
+//#WIKIFUNC tail-substring
+MNode* ml_tail_substring (MNode* cell, MlEnv* mlenv) {
+ MNode* arg = cell->cdr ();
+ ustring str;
+ size_t index;
+ size_t length;
+ int mode;
+ ustring ans;
+
+ if (! arg)
+ throw (uErrorWrongNumber);
+ str = eval_str (arg->car (), mlenv);
+ nextNodeNonNil (arg);
+ index = eval_int (arg->car (), mlenv);
+ nextNode (arg);
+ if (arg) {
+ mode = 3;
+ length = eval_int (arg->car (), mlenv);
+ nextNode (arg);
+ } else {
+ mode = 2;
+ }
+ if (arg)
+ throw (uErrorWrongNumber);
+
+ size_t s = strLength (str);
+ if (mode == 3)
+ substring (str, s - index - 1, length, 1, ans);
+ else
+ substring (str, s - index - 1, 0, 0, ans);
+ return newMNode_str (new ustring (ans));
+}
+
+/*DOC:
===length===
(length STRING) -> NUMBER