static int lua_mysqld_column_get(lua_State *L) {
	network_mysqld_column *col = *(network_mysqld_column **)luaL_checkself(L);
	gsize keysize = 0;
	const char *key = luaL_checklstring(L, 2, &keysize);

	LUA_UDATA_EXPORT_CSTR(col, name);
	LUA_UDATA_EXPORT_CSTR(col, org_name);
	
	if (strleq(C("type"), key, keysize)) {
		lua_pushstring(L, network_mysqld_column_get_typestring(col));
		return 1;
	}

	if (strleq(C("is_nullable"), key, keysize)) {
		lua_pushboolean(L, (col->flags & NOT_NULL_FLAG) ? 0 : 1);
		return 1;
	}

	if (strleq(C("length"), key, keysize)) {
		lua_pushinteger(L, col->max_length);
		return 1;
	}

	return 0;
}
/*
 * FIXME: 1) remove _set_address, make this function callable with result of same
 *        2) differentiate between reasons for "we didn't add" (now -1 in all cases)
 */
int network_backends_add(network_backends_t *bs, /* const */ gchar *address, backend_type_t type) {
	network_backend_t *new_backend;
	guint i;

	new_backend = network_backend_new();
	new_backend->type = type;

	if (0 != network_address_set_address(new_backend->addr, address)) {
		network_backend_free(new_backend);
		return -1;
	}

	/* check if this backend is already known */
	g_mutex_lock(bs->backends_mutex);
	for (i = 0; i < bs->backends->len; i++) {
		network_backend_t *old_backend = bs->backends->pdata[i];

		if (strleq(S(old_backend->addr->name), S(new_backend->addr->name))) {
			network_backend_free(new_backend);

			g_mutex_unlock(bs->backends_mutex);
			g_critical("backend %s is already known!", address);
			return -1;
		}
	}


	g_ptr_array_add(bs->backends, new_backend);
	g_mutex_unlock(bs->backends_mutex);

	g_message("added %s backend: %s", (type == BACKEND_TYPE_RW) ?
			"read/write" : "read-only", address);

	return 0;
}
/**
 * set proxy.global.backends.addslave
 *
 * add slave server into mysql backends
 *
 * @return nil or the backend
 */
static int proxy_backends_set(lua_State *L) {
	network_backends_t *bs = *(network_backends_t **)luaL_checkself(L);
	gsize keysize = 0;
	const char *key = luaL_checklstring(L, 2, &keysize);

	if (strleq(key, keysize, C("addslave"))) {
        	network_backends_add(bs, g_strdup(lua_tostring(L, -1)), BACKEND_TYPE_RO);
	} else if (strleq(key, keysize, C("addmaster"))) {
        	network_backends_add(bs, g_strdup(lua_tostring(L, -1)), BACKEND_TYPE_RW);
	} else if (strleq(key, keysize, C("removebackend"))) {
        	network_backends_remove(bs, lua_tointeger(L, -1));
	} else {
		return luaL_error(L, "proxy.global.backends.%s is not writable", key);
	}
	return 1;
}
示例#4
0
int proxy_user_password_get(lua_State *L) {
	user_password *user_pwd = *(user_password **)luaL_checkself(L);
	gsize keysize = 0;
	const char *key = luaL_checklstring(L, 2, &keysize);

	if (strleq(key, keysize, C("user"))) {
              lua_pushlstring(L, user_pwd->user, strlen(user_pwd->user));
	} else if (strleq(key, keysize, C("pwd"))) {
                char* enpwds = pwds_encrypt(user_pwd->pwd);
                lua_pushlstring(L, enpwds, strlen(enpwds));
                g_free(enpwds);
	} else {
		lua_pushnil(L);
	}

	return 1;
}
示例#5
0
/*
 * FIXME: 1) remove _set_address, make this function callable with result of same
 *        2) differentiate between reasons for "we didn't add" (now -1 in all cases)
 */
int network_backends_add(network_backends_t *bs, /* const */ gchar *address, backend_type_t type) {
	network_backend_t *new_backend;
	guint i;

	new_backend = network_backend_new(bs->event_thread_count);
	new_backend->type = type;

	gchar *p = NULL;
	if (type == BACKEND_TYPE_RO) {
		guint weight = 1;
		p = strrchr(address, '@');
		if (p != NULL) {
			*p = '\0';
			weight = atoi(p+1);
		}
		new_backend->weight = weight;
	}

	if (0 != network_address_set_address(new_backend->addr, address)) {
		network_backend_free(new_backend);
		return -1;
	}

	/* check if this backend is already known */
	g_mutex_lock(bs->backends_mutex);	/*remove lock*/
	gint first_slave = -1;
	for (i = 0; i < bs->backends->len; i++) {
		network_backend_t *old_backend = bs->backends->pdata[i];

		if (first_slave == -1 && old_backend->type == BACKEND_TYPE_RO) first_slave = i;

		if (old_backend->type == type && strleq(S(old_backend->addr->name), S(new_backend->addr->name))) {
			network_backend_free(new_backend);

			g_mutex_unlock(bs->backends_mutex);	/*remove lock*/
			g_critical("backend %s is already known!", address);
			return -1;
		}
	}

	g_ptr_array_add(bs->backends, new_backend);
	if (first_slave != -1 && type == BACKEND_TYPE_RW) {
		network_backend_t *temp_backend = bs->backends->pdata[first_slave];
		bs->backends->pdata[first_slave] = bs->backends->pdata[bs->backends->len - 1];
		bs->backends->pdata[bs->backends->len - 1] = temp_backend;
	}
	g_mutex_unlock(bs->backends_mutex);	/*remove lock*/

	g_message("added %s backend: %s", (type == BACKEND_TYPE_RW) ? "read/write" : "read-only", address);

	if (p != NULL) *p = '@';

	return 0;
}
static int proxy_resultset_field_get(lua_State *L) {
	MYSQL_FIELD *field = *(MYSQL_FIELD **)luaL_checkself(L);
	gsize keysize = 0;
	const char *key = luaL_checklstring(L, 2, &keysize);
        
	if (strleq(key, keysize, C("type"))) {
		lua_pushinteger(L, field->type);
	} else if (strleq(key, keysize, C("name"))) {
		lua_pushstring(L, field->name);
	} else if (strleq(key, keysize, C("org_name"))) {
		lua_pushstring(L, field->org_name);
	} else if (strleq(key, keysize, C("org_table"))) {
		lua_pushstring(L, field->org_table);
	} else if (strleq(key, keysize, C("table"))) {
		lua_pushstring(L, field->table);
	} else {
		lua_pushnil(L);
	}
    
	return 1;
}
示例#7
0
/**
 * get the info about a backend
 *
 * proxy.backend[0].
 *   connected_clients => clients using this backend
 *   address           => ip:port or unix-path of to the backend
 *   state             => int(BACKEND_STATE_UP|BACKEND_STATE_DOWN)
 *   type              => int(BACKEND_TYPE_RW|BACKEND_TYPE_RO)
 *
 * @return nil or requested information
 * @see backend_state_t backend_type_t
 */
static int proxy_backend_get(lua_State *L) {
	network_backend_t *backend = *(network_backend_t **)luaL_checkself(L);
	gsize keysize = 0;
	const char *key = luaL_checklstring(L, 2, &keysize);

	if (strleq(key, keysize, C("connected_clients"))) {
		lua_pushinteger(L, backend->connected_clients);
	} else if (strleq(key, keysize, C("dst"))) {
		network_address_lua_push(L, backend->addr);
	} else if (strleq(key, keysize, C("state"))) {
		lua_pushinteger(L, backend->state);
	} else if (strleq(key, keysize, C("type"))) {
		lua_pushinteger(L, backend->type);
	} else if (strleq(key, keysize, C("uuid"))) {
		if (backend->uuid->len) {
			lua_pushlstring(L, S(backend->uuid));
		} else {
			lua_pushnil(L);
		}
	} else if (strleq(key, keysize, C("weight"))) {
		lua_pushinteger(L, backend->weight);
	} else {
		lua_pushnil(L);
	}

	return 1;
}
示例#8
0
static int proxy_tokenize_token_get(lua_State *L) {
	sql_token *token = *(sql_token **)luaL_checkself(L); 
	size_t keysize;
	const char *key = luaL_checklstring(L, 2, &keysize);

	if (strleq(key, keysize, C("text"))) {
		lua_pushlstring(L, S(token->text));
		return 1;
	} else if (strleq(key, keysize, C("token_id"))) {
		lua_pushinteger(L, token->token_id);
		return 1;
	} else if (strleq(key, keysize, C("token_name"))) {
		size_t token_name_len;
		const char *token_name = sql_token_get_name(token->token_id, &token_name_len);
		lua_pushlstring(L, token_name, token_name_len);
		return 1;
	} else {
		luaL_error(L, "tokens[...] has no %s field", key);
	}

	return 0;
}
示例#9
0
static int proxy_backend_set(lua_State *L) {
	network_backend_t *backend = *(network_backend_t **)luaL_checkself(L);
	gsize keysize = 0;
	const char *key = luaL_checklstring(L, 2, &keysize);

	if (strleq(key, keysize, C("state"))) {
		backend->state = lua_tointeger(L, -1);
	} else if (strleq(key, keysize, C("uuid"))) {
		if (lua_isstring(L, -1)) {
			size_t s_len = 0;
			const char *s = lua_tolstring(L, -1, &s_len);

			g_string_assign_len(backend->uuid, s, s_len);
		} else if (lua_isnil(L, -1)) {
			g_string_truncate(backend->uuid, 0);
		} else {
			return luaL_error(L, "proxy.global.backends[...].%s has to be a string", key);
		}
	} else {
		return luaL_error(L, "proxy.global.backends[...].%s is not writable", key);
	}
	return 1;
}
static int lua_mysqld_table_get(lua_State *L) {
	network_mysqld_table *tbl = *(network_mysqld_table **)luaL_checkself(L);
	gsize keysize = 0;
	const char *key = luaL_checklstring(L, 2, &keysize);

	LUA_UDATA_EXPORT_STR(tbl, db_name);
	LUA_UDATA_EXPORT_STR(tbl, table_name);

	if (strleq(C("columns"), key, keysize)) {
		/* columns is a array */
		return lua_mysqld_columns_push(L, tbl->columns);
	}
	
	return 0;
}
示例#11
0
static int proxy_backends_set(lua_State *L) {
	network_backends_t *bs = *(network_backends_t **)luaL_checkself(L);
	gsize keysize = 0;
	const char *key = luaL_checklstring(L, 2, &keysize);

	if (strleq(key, keysize, C("addslave"))) {
        	network_backends_add(bs, g_strdup(lua_tostring(L, -1)), BACKEND_TYPE_RO);
	} else if (strleq(key, keysize, C("addmaster"))) {
        	network_backends_add(bs, g_strdup(lua_tostring(L, -1)), BACKEND_TYPE_RW);
       } else if (strleq(key, keysize, C("changemaster"))) {
              //change_standby_to_master(bs);
              GThread* t = g_thread_new("change_master_thread", change_master_thread_func, srv);
//              g_thread_join(t);
	} else if (strleq(key, keysize, C("addstandby"))) {
        	network_backends_add(bs, g_strdup(lua_tostring(L, -1)), BACKEND_TYPE_SY);
	} else if (strleq(key, keysize, C("removebackend"))) {
        	network_backends_remove(bs, lua_tointeger(L, -1));
	} else if (strleq(key, keysize, C("addpwds"))) {
              gchar* pwds = g_strdup(lua_tostring(L, -1));
        	network_backends_add_pwds(srv, pwds);
              g_free(pwds);
	} else if (strleq(key, keysize, C("addenpwds"))) {
                gchar* enpwds = convert_pwds(lua_tostring(L, -1));
                network_backends_add_pwds(srv, enpwds);
                g_free(enpwds);
	} else if (strleq(key, keysize, C("removepwds"))) {
              gchar* users = g_strdup(lua_tostring(L, -1));
        	network_backends_remove_pwds(srv, users);
              g_free(users);
	} else if (strleq(key, keysize, C("saveconfig"))) {
                network_save_config(srv);
       } else {
		return luaL_error(L, "proxy.global.backends.%s is not writable", key);
	}
	return 1;
}
示例#12
0
/**
 * compare two GStrings for case-insensitive equality using UTF8
 */
gboolean g_string_equal_ci(const GString *a, const GString *b) {
	char *a_ci, *b_ci;
	gsize a_ci_len, b_ci_len;
	gboolean is_equal = FALSE;

	if (g_string_equal(a, b)) return TRUE;

	a_ci = g_utf8_casefold(S(a));
	a_ci_len = strlen(a_ci);
	
	b_ci = g_utf8_casefold(S(b));
	b_ci_len = strlen(b_ci);

	is_equal = strleq(a_ci, a_ci_len, b_ci, b_ci_len);

	g_free(a_ci);
	g_free(b_ci);

	return is_equal;
}
示例#13
0
static int proxy_injection_get(lua_State *L) {
	injection *inj = *(injection **)luaL_checkself(L);
	gsize keysize = 0;
	const char *key = luaL_checklstring(L, 2, &keysize);
    
	if (strleq(key, keysize, C("type"))) {
		lua_pushinteger(L, inj->id); /** DEPRECATED: use "inj.id" instead */
	} else if (strleq(key, keysize, C("id"))) {
		lua_pushinteger(L, inj->id);
	} else if (strleq(key, keysize, C("query"))) {
		lua_pushlstring(L, inj->query->str, inj->query->len);
	} else if (strleq(key, keysize, C("query_time"))) {
		lua_pushinteger(L, chassis_calc_rel_microseconds(inj->ts_read_query, inj->ts_read_query_result_first));
	} else if (strleq(key, keysize, C("response_time"))) {
		lua_pushinteger(L, chassis_calc_rel_microseconds(inj->ts_read_query, inj->ts_read_query_result_last));
	} else if (strleq(key, keysize, C("resultset"))) {
		/* fields, rows */
		proxy_resultset_t *res;
        
		res = proxy_resultset_new();

		/* only expose the resultset if really needed 
		   FIXME: if the resultset is encoded in binary form, we can't provide it either.
		 */
		if (inj->resultset_is_needed && !inj->qstat.binary_encoded) {	
			res->result_queue = inj->result_queue;
		}
		res->qstat = inj->qstat;
		res->rows  = inj->rows;
		res->bytes = inj->bytes;
	
		proxy_resultset_lua_push(L, res);
	} else {
		g_message("%s.%d: inj[%s] ... not found", __FILE__, __LINE__, key);
        
		lua_pushnil(L);
	}
    
	return 1;
}
示例#14
0
static int proxy_resultset_get(lua_State *L) {
	GRef *ref = *(GRef **)luaL_checkself(L);
	proxy_resultset_t *res = ref->udata;
	gsize keysize = 0;
	const char *key = luaL_checklstring(L, 2, &keysize);
    
	if (strleq(key, keysize, C("fields"))) {
		if (!res->result_queue) {
			luaL_error(L, ".resultset.fields isn't available if 'resultset_is_needed ~= true'");
		} else {
			if (0 != parse_resultset_fields(res)) {
				/* failed */
			}
		
			if (res->fields) {
				proxy_resultset_fields_lua_push_ref(L, ref);
			} else {
				lua_pushnil(L);
			}
		}
	} else if (strleq(key, keysize, C("rows"))) {
		if (!res->result_queue) {
			luaL_error(L, ".resultset.rows isn't available if 'resultset_is_needed ~= true'");
		} else if (res->qstat.binary_encoded) {
			luaL_error(L, ".resultset.rows isn't available for prepared statements");
		} else {
			parse_resultset_fields(res); /* set up the ->rows_chunk_head pointer */
		
			if (res->rows_chunk_head) {
				res->row    = res->rows_chunk_head;

				proxy_resultset_lua_push_ref(L, ref);
		    
				lua_pushcclosure(L, proxy_resultset_rows_iter, 1);
			} else {
				lua_pushnil(L);
			}
		}
	} else if (strleq(key, keysize, C("row_count"))) {
		lua_pushinteger(L, res->rows);
	} else if (strleq(key, keysize, C("bytes"))) {
		lua_pushinteger(L, res->bytes);
	} else if (strleq(key, keysize, C("raw"))) {
		if (!res->result_queue) {
			luaL_error(L, ".resultset.raw isn't available if 'resultset_is_needed ~= true'");
		} else {
			GString *s;
			s = res->result_queue->head->data;
			lua_pushlstring(L, s->str + 4, s->len - 4); /* skip the network-header */
		}
	} else if (strleq(key, keysize, C("flags"))) {
		lua_newtable(L);
		lua_pushboolean(L, (res->qstat.server_status & SERVER_STATUS_IN_TRANS) != 0);
		lua_setfield(L, -2, "in_trans");
        
		lua_pushboolean(L, (res->qstat.server_status & SERVER_STATUS_AUTOCOMMIT) != 0);
		lua_setfield(L, -2, "auto_commit");
		
		lua_pushboolean(L, (res->qstat.server_status & SERVER_QUERY_NO_GOOD_INDEX_USED) != 0);
		lua_setfield(L, -2, "no_good_index_used");
		
		lua_pushboolean(L, (res->qstat.server_status & SERVER_QUERY_NO_INDEX_USED) != 0);
		lua_setfield(L, -2, "no_index_used");
	} else if (strleq(key, keysize, C("warning_count"))) {
		lua_pushinteger(L, res->qstat.warning_count);
	} else if (strleq(key, keysize, C("affected_rows"))) {
		/**
		 * if the query had a result-set (SELECT, ...) 
		 * affected_rows and insert_id are not valid
		 */
		if (res->qstat.was_resultset) {
			lua_pushnil(L);
		} else {
			lua_pushnumber(L, res->qstat.affected_rows);
		}
	} else if (strleq(key, keysize, C("insert_id"))) {
		if (res->qstat.was_resultset) {
			lua_pushnil(L);
		} else {
			lua_pushnumber(L, res->qstat.insert_id);
		}
	} else if (strleq(key, keysize, C("query_status"))) {
		/* hmm, is there another way to figure out if this is a 'resultset' ?
		 * one that doesn't require the parse the meta-data  */

		if (res->qstat.query_status == MYSQLD_PACKET_NULL) {
			lua_pushnil(L);
		} else {
			lua_pushinteger(L, res->qstat.query_status);
		}
	} else {
		lua_pushnil(L);
	}
    
	return 1;
}
示例#15
0
static int proxy_socket_get(lua_State *L) {
    network_socket *sock = *(network_socket **)luaL_checkself(L);
    gsize keysize = 0;
    const char *key = luaL_checklstring(L, 2, &keysize);

    /**
     * we to split it in .client and .server here
     */

    if (strleq(key, keysize, C("default_db"))) {
        lua_pushlstring(L, sock->conn_attr.default_db->str, sock->conn_attr.default_db->len);
        return 1;
    }else if (strleq(key, keysize, C("charset_client"))) {
        lua_pushlstring(L, sock->conn_attr.charset_client->str, sock->conn_attr.charset_client->len);
        return 1;
    }else if (strleq(key, keysize, C("charset_connection"))) {
        lua_pushlstring(L, sock->conn_attr.charset_connection->str, sock->conn_attr.charset_connection->len);
        return 1;
    }else if (strleq(key, keysize, C("charset_results"))) {
        lua_pushlstring(L, sock->conn_attr.charset_results->str, sock->conn_attr.charset_results->len);
        return 1;
    }else if (strleq(key, keysize, C("address"))) {
        return luaL_error(L, ".address is deprecated. Use .src.name or .dst.name instead");
    } else if (strleq(key, keysize, C("src"))) {
        return network_address_lua_push(L, sock->src);
    } else if (strleq(key, keysize, C("dst"))) {
        return network_address_lua_push(L, sock->dst);
    }
      
    if (sock->response) {
        if (strleq(key, keysize, C("username"))) {
            lua_pushlstring(L, S(sock->response->username));
            return 1;
        } else if (strleq(key, keysize, C("scrambled_password"))) {
            lua_pushlstring(L, S(sock->response->response));
            return 1;
        }
    }

    if (sock->challenge) { /* only the server-side has mysqld_version set */
        if (strleq(key, keysize, C("mysqld_version"))) {
            lua_pushinteger(L, sock->challenge->server_version);
            return 1;
        } else if (strleq(key, keysize, C("thread_id"))) {
            lua_pushinteger(L, sock->challenge->thread_id);
            return 1;
        } else if (strleq(key, keysize, C("scramble_buffer"))) {
            lua_pushlstring(L, S(sock->challenge->challenge));
            return 1;
        }
    }
    g_critical("%s: sock->challenge: %p, sock->response: %p (looking for %s)", 
            G_STRLOC,
            (void *)sock->challenge,
            (void *)sock->response,
            key
            );

    lua_pushnil(L);

    return 1;
}