roxen.lists.pike.general

Subject Author Date
Appendix (mysql_sp_funs.pike) to: Re: Unable to call MySQL stored procedures from Pike v7.6 release JCRM <Pike[at]quick-hacks[dot]co[dot]uk> 12-02-2009
 112
  class
  sql_resultset 
  {
    int rows;
    int field_count;
    int more_results_checked;
    array (mapping(string:mixed)) field_info;
    mapping (string : int) fields;
    array (array (string)) data;
    
    void
    create(Mysql.mysql_result results)
    {
      int count;
      int | array(string) the_row;
      string r_type;
      
      if (!(object_is_db_result(results))) {
	ERROR(sprintf("Expected a mysql_result, got %t %<O, %O\n",
		      results, objectp(results) ? indices(results) : "?"));
      }
      rows = results->num_rows();
      fields = ([ ]);
      data = ({ });
      field_count = results->num_fields();
      more_results_checked = -1;
      if (field_count)
	field_info = copy_value(results->fetch_fields());
      for (count = 0; count < field_count ; count++) {
	fields += ([ field_info[count]->name : count ]);
      }
      for (count = 0; count < rows ; count++) {
	the_row = results->fetch_row();
	VERBOSE(sprintf("resultset->create(%d/%d)=%O\n",
			count, rows, the_row));
	if (!arrayp(the_row)) {
	  FAULT(sprintf("fetch_row returned %t %<O\n", the_row));
	  data += ({ });
	} else {
	  data += ({ the_row });
	}
      }
    }
  }

string | int | object
do_sql_big_query(object the_db,
		 string query,
		 mapping (string:mixed) parameters,
		 void | int verbose_flag) {
  object catch_err;
  int|string|object result;
  int err;
  
  DEBUG(sprintf("Database Executing Query %s(%O)\n",
		query, verbose_flag ? parameters : "VERBOSE"));
  catch_err = catch {
      result = the_db->big_query(query, parameters);
    };
  if (catch_err) {
    DEBUG(sprintf("do_sql_big_query((%t)%<O, (%t)%<O caught %O\n",
		  query, parameters, catch_err));
    return catch_err[0] + " (" + query + ")";
  }
  if (intp(result) && result) {
    err = result;
    result = the_db->error();
  }
  if (intp(result) && result) {
    result = sprintf("query %s(%O) returned %d but error() returned %d",
		      query, parameters, err, result);
  }
  
  VERBOSE(sprintf("result = (%t) %<O\n", result));
  return result;
}


  void | string
  do_sql_query_no_results(Sql.mysql the_db,
			  string query,
			  mapping (string:mixed) parameters,
			  )
  {
    void|int|string|object results;
    int count;

    results = do_sql_big_query(the_db, query, parameters, verbose_flag);

    if (intp(results) && !results)
      return;			// As expected, 0 results
    if (stringp(results))
      return "DB error: " + results;
    if (intp(results))
      return sprintf("big_query error: %t %<O", results);
    
    // drain result sets
    for (count = 1; the_db->more_results(); count ++)
      results = the_db->next_result;
    
    return "DB unexepected result sets: " + count;
  }

  void | string | sql_resultset
  do_sql_sproc_single(Sql.mysql the_db,
		      string query,
		      mapping (string:mixed) parameters)
 {
    void|int|string|object results;
    int count;
    sql_resultset ret;

    results = do_sql_big_query(the_db, query, parameters, verbose_flag);

    if (intp(results))
      return results ? "big query error: " + results : "0 results";
    if (stringp(results))
      return "DB error: " + results;

    ret = sql_resultset(results);
    if (!the_db->more_results())
      return sprintf("SP_single: single resultset: %O\n%O\n ",
		     ret->field_info, ret->data);
    
    // drain result sets
    for (count = 0; the_db->more_results(); count ++)
      results = the_db->next_result();
    if (1 < count)
      return "SP_single: More than 1 resultset (" + count + ")";
    if (1 < ret->num_rows)
      return "SP_single: More than 1 row in result (" + ret->num_rows + ")";
    return ret;
  }

  string | mapping (string : int | array (sql_resultset))
  do_sql_sproc(Sql.mysql the_db,
	       string query,
	       mapping (string:mixed) parameters)
  {
    void|int|string|object results;
    int count;
    sql_resultset ret;
    array (sql_resultset) bucket;
    void | string error;

    results = do_sql_big_query(the_db, query, parameters, verbose_flag);

    if (intp(results))
      return ([ "num" : -1, "sets" : ({ }) ]);
    if (stringp(results))
      return ([ "Error" :  "DB error: " + results ]);

    ret = sql_resultset(results);
    bucket = ({ });

    // collect result sets
    for (count = 0; the_db->more_results();) {
      results = the_db->next_result();
      count++;
      if (intp(results)) {
	error
	  = sprintf("DB error (%d = %d): %s", count, results, the_db->error());
	DEBUG(error + "\n");
      } else {
	ret->more_results_checked = 1;
	bucket += ({ ret });
	ret = sql_resultset(results);
      }
    }

    ret->more_results_checked = -1;
    bucket += ({ ret });
    
    if (stringp(error)
	&& strlen(error))
      return ([ "Error" : error,
		"num": count,	// we don't count the last set
		"sets": bucket ]);
    return ([ "num": count,	// we don't count the last set
	      "sets": bucket ]);
  }