PDA

Просмотр полной версии : [Вопрос] Грузится только первый биз, хелп(



StevenH
03.06.2017, 21:50
Здравствуйте. Делаю систему загрузки бизнесов, ВРОДЕ как все хорошо, но грузится только 1 бизнес, не могу понять почему...

Код загрузки:


publics: LoadBusiness()
{
new rows, time = GetTickCount();
cache_get_row_count(rows);
if(gBusinessCount >= MAX_BUSINESS_COUNT) print("[MySQL] Кол-во бизнесов в базе превышает предопределнное количество");
if(!rows) return print("[MySQL] Бизнесы не были загружены!");
gBusinessCount = rows;
printf("rows - %d", rows);
for(new i; i < rows; i++)
{
print("===================");
printf("i - %d", i);
cache_get_value_name_int(i, "id", gBusiness[i][busiID]);
cache_get_value_name_int(i, "ownerid", gBusiness[i][busiOwnerID]);
cache_get_value_name(i, "name", gBusiness[i][busiName], 32);
cache_get_value_name_int(i, "type", gBusiness[i][busiType]);
cache_get_value_name_int(i, "bint", gBusiness[i][busiBint]);
cache_get_value_name_int(i, "price", gBusiness[i][busiPrice]);
cache_get_value_name_int(i, "status", gBusiness[i][busiStatus]);
cache_get_value_name_int(i, "enterprice", gBusiness[i][busiEnterPrice]);
cache_get_value_name_int(i, "bank", gBusiness[i][busiBank]);
cache_get_value_name_int(i, "product", gBusiness[i][busiProduct]);
cache_get_value_name_int(i, "mafia", gBusiness[i][busiMafia]);
cache_get_value_name_float(i, "x", gBusiness[i][busiX]);
cache_get_value_name_float(i, "y", gBusiness[i][busiY]);
cache_get_value_name_float(i, "z", gBusiness[i][busiZ]);
cache_get_value_name_float(i, "r", gBusiness[i][busiR]);

printf("id - %d, ownerid - %d, name - %s", gBusiness[i][busiID], gBusiness[i][busiOwnerID], gBusiness[i][busiName]);

printf("CreateDynamicPickup");
CreateDynamicPickup(19132, 1, gBusiness[i][busiX],gBusiness[i][busiY],gBusiness[i][busiZ]);
printf("CreateBusinessText");
gBusinessText[i] = CreateDynamic3DTextLabel("_", CWHITE, gBusiness[i][busiX], gBusiness[i][busiY], gBusiness[i][busiZ]+1.0, 20.0);
printf("UpdateBusinessText");
UpdateBusinessText(i);
print("===================");
}
printf("[MySQL]: Загружено %d бизнесов за %d м.с.", gBusinessCount, GetTickCount()-time);
return true;
}


Сделал маленькое логирование, вот что в логах:


[20:47:01] rows - 2
[20:47:01] ===================
[20:47:01] i - 0
[20:47:01] id - 1, ownerid - 1, name - Railway Shop 24/7
[20:47:01] CreateDynamicPickup
[20:47:01] CreateBusinessText
[20:47:01] UpdateBusinessText
[20:47:01] ===================
[20:47:01] ===================
[20:47:01] i - 1
[20:47:01] id - 0, ownerid - 0, name -
[20:47:01] CreateDynamicPickup
[20:47:01] CreateBusinessText
[20:47:01] UpdateBusinessText
[20:47:01] ===================


Скриншот таблицы:
http://i.imgur.com/UcITuKS.png

- - - Добавлено - - -

Все по коду нормально, не могу понять почему выбирает только 1 бизнес

DeimoS
03.06.2017, 21:56
Запрос покажи и crashdetect включен?

StevenH
03.06.2017, 22:09
Запрос покажи и crashdetect включен?

Crashdetect включен, соответственно в логах ничего связанного с крашдетектом нету...

Запрос:
mysql_tquery(mysql_connect_ID, "SELECT * FROM `business` ORDER BY `id`", "LoadBusiness","");

Если ввести его в SQL-запрос в PHPMyAdmin, то выводятся все 2 бизнесы...

- - - Добавлено - - -

Нашел ошибку, но не без помощи.

В UpdateBusinessText у меня есть функция, которая узнает имя игрока по его ID аккаунта (ID аккаунта записан в бизнесе), код как вызывается:



format(nickname, sizeof(nickname), "%s", GetPlayerNameByID(ownerid));


Сама функция:


stock GetPlayerNameByID(id)
{
new query[64], nickname[24];
format(query, sizeof(query), "SELECT `nickname` FROM `accounts` WHERE `id` = '%d'", id);
new Cache:result = mysql_query(mysql_connect_ID, query, true);
cache_get_value_name(0, "nickname", nickname, 24);
cache_delete(result);
return nickname;
}


Где ошибка? Если убрать это, тогда все бизнесы грузятся...

DeimoS
03.06.2017, 22:30
Ошибка в том, что ты отправляешь ещё один запрос, из-за чего старый кэш удаляется.
Либо сохраняй кэш перед вызовом началом цикла и потом каждую итерацию переключайся на него, либо запросы нужно переписывать

StevenH
03.06.2017, 22:32
Ошибка в том, что ты отправляешь ещё один запрос, из-за чего старый кэш удаляется.
Либо сохраняй кэш перед вызовом началом цикла и потом каждую итерацию переключайся на него, либо запросы нужно переписывать

Да, почему так и подумал.. Как сохранить можно кэш? Не сталкивался с таким..

Или лучше будет переписать запросы? Но тоже, не знаю в каком плане это сделать...

DeimoS
03.06.2017, 22:35
native Cache:cache_save(connectionHandle = 1);
native cache_delete(Cache:cache_id, connectionHandle = 1);
native cache_set_active(Cache:cache_id, connectionHandle = 1);
native cache_is_valid(Cache:cache_id, connectionHandle = 1);


Если нужен пример - скажи

StevenH
03.06.2017, 22:39
native Cache:cache_save(connectionHandle = 1);
native cache_delete(Cache:cache_id, connectionHandle = 1);
native cache_set_active(Cache:cache_id, connectionHandle = 1);
native cache_is_valid(Cache:cache_id, connectionHandle = 1);


Если нужен пример - скажи

Да, желательно бы с примером, ибо с кэшем в MySQL сталкивался очень мало :hang1:

DeimoS
03.06.2017, 22:51
Когда ты отправляешь запрос, который возвращает кэш, ты можешь его сохранить, использовав функцию cache_save, которая возвратит ID кэша так же, как возвращает mysql_query. То бишь

new Cache:result = cache_save(mysql_connect_ID); // Кэш записан
Ты так же можешь записать ID кэша в глобальную переменную и потом обратиться к нему в любой момент времени. Но, соответственно, он будет забивать память сервера, посему следует обязательно удалять его после того, как он уже не нужен, если не хочешь получить краш сервера из-за переполнения памяти.

Удаляется кэш при помощи функции cache_delete.

cache_delete(result, mysql_connect_ID);

Переключаться на нужный кэш можно при помощи функции cache_set_active.

cache_set_active(result, mysql_connect_ID);

Ну а cache_is_valid проверяет, существует ли кэш

Вообще в комплекте с исходниками плагина MySQL имеется пример системы регистрации (https://github.com/pBlueG/SA-MP-MySQL/blob/master/example_scripts/login_system-cache.pwn), в котором как раз и идёт работа с кэшем (по идее, регистрацию так и нужно писать). Советую подробнее изучить код этой системы.

А твоя загрузка должна выглядеть как-то так:

publics: LoadBusiness()
{
new rows,
time = GetTickCount();
cache_get_row_count(rows);

if(gBusinessCount >= MAX_BUSINESS_COUNT)
print("[MySQL] Кол-во бизнесов в базе превышает предопределнное количество");
if(!rows)
return print("[MySQL] Бизнесы не были загружены!");

new Cache:result = cache_save(mysql_connect_ID);

gBusinessCount = rows;
printf("rows - %d", rows);
for(new i; i < rows; i++)
{
print("===================");
printf("i - %d", i);
cache_get_value_name_int(i, "id", gBusiness[i][busiID]);
cache_get_value_name_int(i, "ownerid", gBusiness[i][busiOwnerID]);
cache_get_value_name(i, "name", gBusiness[i][busiName], 32);
cache_get_value_name_int(i, "type", gBusiness[i][busiType]);
cache_get_value_name_int(i, "bint", gBusiness[i][busiBint]);
cache_get_value_name_int(i, "price", gBusiness[i][busiPrice]);
cache_get_value_name_int(i, "status", gBusiness[i][busiStatus]);
cache_get_value_name_int(i, "enterprice", gBusiness[i][busiEnterPrice]);
cache_get_value_name_int(i, "bank", gBusiness[i][busiBank]);
cache_get_value_name_int(i, "product", gBusiness[i][busiProduct]);
cache_get_value_name_int(i, "mafia", gBusiness[i][busiMafia]);
cache_get_value_name_float(i, "x", gBusiness[i][busiX]);
cache_get_value_name_float(i, "y", gBusiness[i][busiY]);
cache_get_value_name_float(i, "z", gBusiness[i][busiZ]);
cache_get_value_name_float(i, "r", gBusiness[i][busiR]);

printf("id - %d, ownerid - %d, name - %s", gBusiness[i][busiID], gBusiness[i][busiOwnerID], gBusiness[i][busiName]);

printf("CreateDynamicPickup");
CreateDynamicPickup(19132, 1, gBusiness[i][busiX],gBusiness[i][busiY],gBusiness[i][busiZ]);
printf("CreateBusinessText");
gBusinessText[i] = CreateDynamic3DTextLabel("_", CWHITE, gBusiness[i][busiX], gBusiness[i][busiY], gBusiness[i][busiZ]+1.0, 20.0);
printf("UpdateBusinessText");
UpdateBusinessText(i);
cache_set_active(result, mysql_connect_ID);
print("===================");
}
cache_delete(result, mysql_connect_ID);
printf("[MySQL]: Загружено %d бизнесов за %d м.с.", gBusinessCount, GetTickCount()-time);
return true;
}

StevenH
03.06.2017, 22:56
Когда ты отправляешь запрос, который возвращает кэш, ты можешь его сохранить, использовав функцию cache_save, которая возвратит ID кэша так же, как возвращает mysql_query. То бишь

new Cache:result = cache_save(mysql_connect_ID); // Кэш записан
Ты так же можешь записать ID кэша в глобальную переменную и потом обратиться к нему в любой момент времени. Но, соответственно, он будет забивать память сервера, посему следует обязательно удалять его после того, как он уже не нужен, если не хочешь получить краш сервера из-за переполнения памяти.

Удаляется кэш при помощи функции cache_delete.

cache_delete(result, mysql_connect_ID);

Переключаться на нужный кэш можно при помощи функции cache_set_active.

cache_set_active(result, mysql_connect_ID);

Ну а cache_is_valid проверяет, существует ли кэш

Вообще в комплекте с исходниками плагина MySQL имеется пример системы регистрации (https://github.com/pBlueG/SA-MP-MySQL/blob/master/example_scripts/login_system-cache.pwn), в котором как раз и идёт работа с кэшем (по идее, регистрацию так и нужно писать). Советую подробнее изучить код этой системы.

А твоя загрузка должна выглядеть как-то так:

publics: LoadBusiness()
{
new rows,
time = GetTickCount();
cache_get_row_count(rows);

if(gBusinessCount >= MAX_BUSINESS_COUNT)
print("[MySQL] Кол-во бизнесов в базе превышает предопределнное количество");
if(!rows)
return print("[MySQL] Бизнесы не были загружены!");

new Cache:result = cache_save(mysql_connect_ID);

gBusinessCount = rows;
printf("rows - %d", rows);
for(new i; i < rows; i++)
{
print("===================");
printf("i - %d", i);
cache_get_value_name_int(i, "id", gBusiness[i][busiID]);
cache_get_value_name_int(i, "ownerid", gBusiness[i][busiOwnerID]);
cache_get_value_name(i, "name", gBusiness[i][busiName], 32);
cache_get_value_name_int(i, "type", gBusiness[i][busiType]);
cache_get_value_name_int(i, "bint", gBusiness[i][busiBint]);
cache_get_value_name_int(i, "price", gBusiness[i][busiPrice]);
cache_get_value_name_int(i, "status", gBusiness[i][busiStatus]);
cache_get_value_name_int(i, "enterprice", gBusiness[i][busiEnterPrice]);
cache_get_value_name_int(i, "bank", gBusiness[i][busiBank]);
cache_get_value_name_int(i, "product", gBusiness[i][busiProduct]);
cache_get_value_name_int(i, "mafia", gBusiness[i][busiMafia]);
cache_get_value_name_float(i, "x", gBusiness[i][busiX]);
cache_get_value_name_float(i, "y", gBusiness[i][busiY]);
cache_get_value_name_float(i, "z", gBusiness[i][busiZ]);
cache_get_value_name_float(i, "r", gBusiness[i][busiR]);

printf("id - %d, ownerid - %d, name - %s", gBusiness[i][busiID], gBusiness[i][busiOwnerID], gBusiness[i][busiName]);

printf("CreateDynamicPickup");
CreateDynamicPickup(19132, 1, gBusiness[i][busiX],gBusiness[i][busiY],gBusiness[i][busiZ]);
printf("CreateBusinessText");
gBusinessText[i] = CreateDynamic3DTextLabel("_", CWHITE, gBusiness[i][busiX], gBusiness[i][busiY], gBusiness[i][busiZ]+1.0, 20.0);
printf("UpdateBusinessText");
UpdateBusinessText(i);
cache_set_active(result, mysql_connect_ID);
print("===================");
}
cache_delete(result, mysql_connect_ID);
printf("[MySQL]: Загружено %d бизнесов за %d м.с.", gBusinessCount, GetTickCount()-time);
return true;
}

Спасибо за код.

Но у меня вопрос, зачем тут
new Cache:result = cache_save(mysql_connect_ID); передавать mysql_connect_ID? Компилятор ругнулся на 202 варнинг). Открыл a_mysql.inc, нашел cache_save, а там:

native Cache:cache_save();

Или это было обязательным в более ранних версиях? (Сейчас использую R41-2)

Long-
03.06.2017, 22:57
Спасибо за исходники и код. Перепишу регистрацию на днях, с использование кэшев.

Но у меня вопрос, зачем тут
new Cache:result = cache_save(mysql_connect_ID); передавать mysql_connect_ID? Компилятор ругнулся на 202 варнинг). Открыл a_mysql.inc, нашел cache_save, а там:

native Cache:cache_save();

Или это было обязательным в более ранних версиях? (Сейчас использую R41-2)

Ты хочешь все запросы на однопоточные сменить? Зачем?

StevenH
03.06.2017, 23:00
Ты хочешь все запросы на однопоточные сменить? Зачем?

Затупил, ладно. Тему можно закрыть

DeimoS
03.06.2017, 23:00
Спасибо за исходники и код. Перепишу регистрацию на днях, с использование кэшев.

Это не обязательно и даже вредно, если опыта в работе с кэшем мало. Ибо могут появиться проблемы, которые дадут о себе знать только при длительной работе сервера с онлайном


Или это было обязательным в более ранних версиях? (Сейчас использую R41-2)

Да. До R40 во многих функциях был обязателен параметр с ID подключения

- - - Добавлено - - -


Ты хочешь все запросы на однопоточные сменить? Зачем?

Кэш используется не только в однопоточных запросах, если ты про это

StevenH
03.06.2017, 23:02
Это не обязательно и даже вредно, если опыта в работе с кэшем мало. Ибо могут появиться проблемы, которые дадут о себе знать только при длительной работе сервера с онлайном



Да. До R40 во многих функциях был обязателен параметр с ID подключения

- - - Добавлено - - -



Кэш используется не только в однопоточных запросах, если ты про это

Спасибо, проблема решена, тему можно закрыть

Long-
03.06.2017, 23:06
Это не обязательно и даже вредно, если опыта в работе с кэшем мало. Ибо могут появиться проблемы, которые дадут о себе знать только при длительной работе сервера с онлайном



Да. До R40 во многих функциях был обязателен параметр с ID подключения

- - - Добавлено - - -



Кэш используется не только в однопоточных запросах, если ты про это

Я не про это, была его тема , то что он спрашивал про однопоточные запросы, и смотрю он все под них переделывает...
Вот решил спросить - Зачем??? !!)

DeimoS
03.06.2017, 23:19
Я не про это, была его тема , то что он спрашивал про однопоточные запросы, и смотрю он все под них переделывает...
Вот решил спросить - Зачем??? !!)

При старте сервера они очень даже в тему, ибо если ты сделаешь рестарт и игроки начнут подключаться к серверу когда он ещё не загрузил все данные из бд - будет так себе