OSDN Git Service

sqlv, tailstring function.
authorvisor <visor@users.sourceforge.jp>
Sun, 29 Mar 2015 14:48:01 +0000 (23:48 +0900)
committervisor <visor@users.sourceforge.jp>
Sun, 29 Mar 2015 14:48:01 +0000 (23:48 +0900)
ext/ml-sqlite3.cc
ext/ml-sqlite3.h
modules/ml-string.cc
modules/ml-string.h

index bbf61c5..e199f69 100644 (file)
@@ -251,6 +251,50 @@ MNode*  MLSqlite3::answer_list_ary () {
     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);
 }
@@ -461,10 +505,19 @@ static MNode*  ml_sqlite3_sql_main (MNode* cell, MlEnv* mlenv, MLSqlite3::fsqlPa
        }
        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
@@ -485,12 +538,34 @@ static MNode*  ml_sqlite3_sql_main (MNode* cell, MlEnv* mlenv, MLSqlite3::fsqlPa
 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);
 }
 
index 50871bc..637f0c6 100644 (file)
@@ -45,10 +45,15 @@ class  MLSqlite3: public MLFunc {
        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 () {};
     };
@@ -92,6 +97,8 @@ class  MLSqlite3: public MLFunc {
     };
     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);
@@ -103,6 +110,8 @@ class  MLSqlite3: public MLFunc {
 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);
index 5e2d5c4..18b607f 100644 (file)
@@ -765,6 +765,48 @@ MNode*  ml_substring (MNode* cell, MlEnv* mlenv) {
 }
     
 /*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
 
index bbd16d4..380faff 100644 (file)
@@ -27,6 +27,7 @@ MNode*  ml_string_join (MNode* cell, MlEnv* mlenv);
 MNode*  ml_password_match (MNode* cell, MlEnv* mlenv);
 MNode*  ml_password_crypt (MNode* cell, MlEnv* mlenv);
 MNode*  ml_substring (MNode* cell, MlEnv* mlenv);
+MNode*  ml_tail_substring (MNode* cell, MlEnv* mlenv);
 MNode*  ml_length (MNode* cell, MlEnv* mlenv);
 MNode*  ml_pad0 (MNode* cell, MlEnv* mlenv);
 MNode*  ml_ellipsis (MNode* cell, MlEnv* mlenv);