:: Visual Foxpro, Foxpro for DOS
Re: Эксперименты с FLUSH в VFP9
Sergey Fadeev
Автор

Сообщений: 106
Откуда: Чебоксары
Дата регистрации: 07.02.2005
Igor Korolyov
Это исторически сложилось - на самом деле в FPD всё было точно так-же.
Я не спорю - может быть FPD и делает сброс буферов на диск перед выполнением SELECT-SQL. Но назвать это "всё было точно так же" ну никак нельзя. Посуди сам: если в FPD ты получал один результат, а в VFP точно такими же командами получаешь СОВЕРШЕННО ДРУГОЙ, то о каком "точно так же" и "исторически сложилось" может идти речь? Если ты в VFP для получения такого же результата, как в VFP, должен поставить перед своим старым кодом некие дополнительные команды или явно включить некие опции, то "точно так же" здесь не пахнет. Как и исторической преемственностью...

Igor Korolyov
1) Должен - это его прямая обязанность.
2) Я неправильно выразился - не FLUSH вызывает снятие блокировки, а наоборот - снятие блокировки с записи вызывает её запись на диск (это не совсем FLUSH т.к. записывается только текущая запись). Явно наложенные блокировки FLUSH не трогает, так что повода для беспокойства нету!
Прочитав эти 2 пункта, я не совсем понял, что ты хотел сказать в ответ на мое утверждение:
Sergey Fadeev
Если я хочу сбросить буфера, то я должен иметь такую возможность без всяких побочных эффектов типа снятия блокировок.
Пока у меня сложилось ощущение, что ты говоришь, что FLUSH этим напрямую не занимается (твой пункт 2), но по твоему мнению он этим должен заниматься (твой пункт 1). Насчет пункта 1 я как раз и спорил. И не согласен, что сброс буферов ДОЛЖЕН обязательно снимать блокировки...

Igor Korolyov
Ты не прав - единственное видимое отличие - SELECT в FPD вызывает перед своим исполнением неявный FLUSH.
Неявный, т.е. невидимый FLUSH - видимое отличие, а то, что мы в результате видим СОВСЕМ ДРУГИЕ данные - вообще за видимое отличие не считается, так что ли? Игорь, где же логика?

Igor Korolyov
Сложно сказать - поведение SELECT SQL было таковым ещё в FPD (происходило чтение с диска, даже мимо файлового кэша фокса) - сделать "по умолчанию" отличающееся поведение в VFP - значит нарушить принцип обратной совместимости. Поэтому и было оставлено старое поведение.
В дополнение к вышесказанному. Да, если поведение SELECT SQL определять не по результатам выполнения, а по внутренней процедуре чтения данных, то так оно и есть. Только вот лежащий на выходе результат-то разный! И это намного важнее, чем внутренняя логика работы. С таким же успехом можно сказать, что самолет и пароход одинаково себя ведут, т.к. внутри них есть двигатели, хотя для внешнего наблюдателя результаты их работы - совершенно разные...
Кстати, большинству программистов без разницы, каким алгоритмом и с помощью каких команд внутри Fox'а достигается тот или иной результат. А вот результат работы той или иной команды (внутреннее устройство которой для подавляющего большинства остается "черным ящиком") - очень даже важен. Поэтому есть или нет чтение с диска внутри SELECT-SQL в FPD не так важно. Важно, что результаты - разные...

Igor Korolyov
Это не обходные манёвры - насколько я понимаю так работают все среды - пока что-то "набивается" в поле - ни о каком сохранении данных речи не идёт - и лишь при выходе из поля, или нажатии каких-то специальных клавиш происходит "сброс" данных из буфера контрола куда-то дальше...
Что-то я сильно сомневаюсь, что во всех средах для подстраховки с целью получения корректного результата создают специальный "пустой" текстбокс. И что везде принципиально нельзя обойтись без создания таких специальных текстбоксов. Если меня переубедят, то, конечно же, возьму назад свои слова об обходных маневрах...

Владимир Максимов
В FPD не было такого понятия как "буфер таблиц" (точнее, были, но не явные и практически неуправляемые пользователем). Т.е. говорить о какой-то совместимости в этом плане не имеет смысла. Не с чем "совмещать".
Ну что вы все к буферам прицепились? Ну не об этом шла речь - неужели не видно? Мне без разницы, сколько будет буферов у той или иной таблицы - ни одного, один или сто тысяч. Не интересна мне совместимость по неявным буферам таблиц внутри "черного ящика" - мне важна совместимость по выходным результатам. Прочитайте внимательно мои предыдущие сообщения - если там и шла речь о буферах, так только в качестве попытки объяснить, из-за чего у SELECT-SQL могли получиться разные результаты.
Я уже начинаю жалеть, что заикнулся о буферах - теперь за листьями (буферами) уже не видят леса (разные результаты)...

Владимир Максимов
Если же в VFP не использовать буфер таблиц, т.е. работать "как в FPD", то совместимость налицо. Все работает также как и в FPD.
Ну и где ты видишь в тестовом примере, что я какие-то специальные команды для буферов включаю? Если не видишь, то значит по умолчанию совместимость не работает, раз результаты разные. Если можно добиться совместимости, только явно включив какой-то режим или поставив перед нужными командами какие-то дополнительные команды, то, IMHO, это не совсем неправильный подход с точки зрения совместимости. Именно это я имел в виду, когда оценивал значение по умолчанию WITH (BUFFERING=lExp) и/или необходимость FLUSH перед SELECT-SQL. Будешь спорить с неправильностью такого подхода к значениям по умолчанию?

Владимир Максимов
Есть на форме TextBox. Ты начинаешь модифицировать его данные. В какой момент, то, что ты внес должно быть сброшено в поле таблицы? После каждого символа? Не думаю. Логично завершить ввод поля целиком и только потом сбросить то, что ввели.
Владимир Максимов
Как определить тот момент, когда ввод данных в TextBox завершен?
Нет, определенно наблюдается тенденция в приводимом коде не читать внимательно комментарии, а в сообщениях читать через строчку и даже через сообщение. Игорь уже все понял и переключил внимание куда нужно. Теперь придется объяснить тебе.
Вопросы на наблюдательность: где ты видишь мое недовольство тем, что значение Textbox.Value проигнорировано? Да мне в данном случае вообще без разницы, записалось оно или нет. Вопрос касался игнорирования команды REPLACE, которая не имеет таких понятий, как вход в поле (кстати, в том примере специально были исключены такие действия, как получение фокуса, редактирование поля и потеря фокуса - для наглядности), выход из поля, начало и конец редактирования. Тем более, что команда REPLACE работает с полем, которое вообще никак не представлено на форме...

Владимир Максимов
Чтобы описать все "подводные камни" и возможные "рабочие ситуации", которые могут возникнуть при определении момента завершения ввода в поле и запись надо написать огромную "простыню". Разработчики FoxPro проделали огромную работу по их обработке. Но всего учесть не смогли. Даже не потому, что не заметили, а потому, что не всегда ситуация однозначна. Т.е. не всегда можно однозначно сказать, что вот он момент завершения ввода. Поэтому "правило хорошего тона" - это дать FoxPro понять, что процесс ввода был завершен. Таким индикатором и является явный переход на другой объект ввода.
Да не об этом речь...

Теперь, когда мнение знатоков по поводу тестового примера выслушано и принято к сведению, и вопрос для меня более-менее прояснился, выскажу свое мнение.
Чтобы не отвлекаться от сути - забудьте про буфера, их реализацию, методы опустошения и заполнения и все, что с ними связано (я о них тоже говорить не буду). Так вот, мое мнения - очень строгая, ясная и легко понятная для программистов картина возможна, если использовать понятие адресного пространства.
В FPD было единое адресное пространство - команды ? <fieldname>, REPLACE <fieldname>, SELECT-SQL <fieldname> и любые другие всегда были согласованы по значениям <fieldname>. Как это внутри достигалось - не столь важно. Важно, что программист всегда знал, где, что и в каком состоянии лежит.
В VFP за счет буферизации были введены дополнительные адресные пространства (обращение к <fieldname> может давать разные результаты в завимости от местонахождения). Например, в форме стало возможно работать со своим внутренним адресным пространством, которое может отличаться от внешнего адресного пространства до тех пор, пока не произойдет сброс буферов внутреннего адресного пространства во внешнее. Это здорово, это замечательно. Удобная и полезная вещь для программистов. Не надо предварительно копировать поля таблицы во временные переменные или временный объект, а потом назад в таблицу. Работаешь с таблицей как ни в чем ни бывало - обычными командами и знаешь, что эти значения на самом деле только твои, внутренние, невидимые снаружи. Т.е. доступ к СВОЕМУ адресному пространству такой же простой, легкий и прозрачный, как и в едином адресном пространстве FPD. А вот доступ НАРУЖУ, к ЧУЖОМУ адресному пространству уже требует специальных инструментов. Оно понятно - иначе можно запутаться и чего-нибудь не так сделать.
Пример такого подхода - функция OLDVAL(). К новому значению поля (во внутреннем адресном пространстве) доступ получить легко и просто (так же легко и просто как и едином адресном пространстве) - обратись только по имени. А вот чтобы получить доступ к старому значению приходится прибегать к помощи специальной функции.
Мне кажется, что так должно быть и везде внутри формы. Если мы не включили специальный режим, то работаем во внешнем по отношению к форме адресном пространстве. Если включили - то в своем собственном, внутреннем. Что может быть проще и понятнее? А если хотим получить значения извне - начинаем использовать специальные инструменты.
Игорь и Владимир, вы согласны, что это действительно простая и понятная концепция? И максимально совместимая по исходному коду с любым кодом, начиная с dBASE II? И что она должна быть активной по умолчанию?

Теперь еще раз сформулирую, что же мне не нравится, с чем я не согласен. В тестовом примере мне не нравится, что команды ? <fieldname> и REPLACE <fieldname> работают во внутреннем адресном пространстве, а SELECT-SQL <fieldname> - уже во внешнем. Поэтому я и не согласен со значением по умолчанию для WITH (BUFFERING=lExp) - оно открывает дыру во внешнее пространство. Неявно, легко и без всяких дополнительных инструментов, опций или команд. Старый код SELECT-SQL начинает работать по-новому. Это разве хорошо? Разве такой подход удобен? Назовите преимущества, в чем этот подход выигрывает у подхода, описанного мной.
Когда я столкнулся с этим, то для меня в первую очередь было удивительно, что SELECT-SQL <fieldname> игнорирует результаты выполнения предшествующей REPLACE <fieldname>. Так не должно быть - по-крайней мере по умолчанию...
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Владимир Максимов

Сообщений: 14100
Откуда: Москва
Дата регистрации: 02.09.2000
Цитата:
Игорь и Владимир, вы согласны, что это действительно простая и понятная концепция? И максимально совместимая по исходному коду с любым кодом, начиная с dBASE II?
Да, согласен.

Цитата:
И что она должна быть активной по умолчанию?
Да, согласен, но с оговорками.

Если бы речь шла о версии VFP3, то согласился бы безоговорочно. Но поскольку этого НЕ БЫЛО сделано в версиях с VFP3 по VFP8 включительно, то ввод этого режима, как режима "по умолчанию" означает отказ от принципа обратной совместимости с этими версиями.

Повторюсь, о совместимости с FPD речи вообще не идет. В примере ты использовал структуры, которых в принципе не было в FPD.

Цитата:
Поэтому я и не согласен со значением по умолчанию для WITH (BUFFERING=lExp)
На здоровье. А от нас то, ты что хочешь? Мы при всем желании не можем изменить этот режим по умолчанию. Так есть. С этим остается только смириться.

Цитата:
Когда я столкнулся с этим, то для меня в первую очередь было удивительно, что SELECT-SQL <fieldname> игнорирует результаты выполнения предшествующей REPLACE <fieldname>. Так не должно быть - по-крайней мере по умолчанию...
Да, я тоже был этим удивлен. Но так было сделано. Теперь именно это является режимом по умолчанию.

Опять отойду чуть в сторону. Лично меня сильно удивляет такая горячая "привязанность" к команде Select-SQL. Какой глубокий смысл изменить одну (несколько) запись и тут же делать выборку по ВСЕЙ таблице? Лично мне это кажется неправильным. Почему нельзя один раз получить выборку, а потом заниматься только ее модификацией? Тем не менее, так поступают. Вот как в данном примере.
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Hi Sergey!

Цитата:
если в FPD ты получал один результат, а в VFP точно такими же
командами получаешь СОВЕРШЕННО ДРУГОЙ, то о каком "точно так же" и
"исторически сложилось" может идти речь
У тебя в FPD был объект Form с вложенным объектом Textbox привязанным к
этому полю, да ещё и с выполнением Textbox.Value = '' ? Естественно что нет!
GET поля и READ CYCLE ну никак не могут служить аналогом того что есть у
тебя сейчас в VFP. Тогда какие претензии?
Цитата:
Прочитав эти 2 пункта, я не совсем понял
FLUSH сбрасывает буфера и НЕ снимает блокировки. Т.е. то что нужно.
Цитата:
Важно, что результаты - разные...
У тебя как минимум стартовые условия разные...
Цитата:
Что-то я сильно сомневаюсь, что во всех средах для подстраховки с
целью получения корректного результата создают специальный "пустой"
текстбокс.
Не обязательно есть масса других вариантов - главное вынудить контрол
выполнить сброс данных - т.е. по сути ЗАВЕРШИТЬ процесс редактирования
значения. Перевод фокуса просто вызывает корректное срабатывание ВСЕХ
методов которые ты мог прописать - решение от MS (есть в FFC) работает без
перевода фокуса, зато если у тебя есть проверка в Valid/LostFocus, то она
идёт боком... Кстати говоря, если ты пользуешься кнопкой на ФОРМЕ, то ничего
и не надо делать - она заберёт фокус и всё. Критично лишь при инициации с
меню или тулбара. Конечно я про "обычную" программу - если у тебя вдруг в
реальной программе проводятся подобные действия с невидимой формой и
невидимым текстбоксом - то даже не знаю чего и посоветовать...
Цитата:
где ты видишь мое недовольство тем, что значение Textbox.Value
проигнорировано? Да мне в данном случае вообще без разницы, записалось оно
или нет
Однако ты НЕ учитываешь последствий! У тебя из-за этого возникла неявная
блокировка, которая и мешает работе! Т.е. грубо говоря, это как если бы ты
срубил сук на котором сидишь, а потом заявлял что "ну топор затупился
слегка, но меня же это не волнует - меня волнует что я с дерева упал".
Цитата:
Вопрос касался игнорирования команды REPLACE
Ещё раз - она НЕ игнорируется!
Цитата:
в том примере специально были исключены такие действия ... начало и
конец редактирования
.Value = '' это оно и есть.
Цитата:
команда REPLACE работает с полем, которое вообще никак не
представлено на форме
В фоксе блокируется ЗАПИСЬ а не одно поле. Кэшируется также ЗАПИСЬ целиком
(возможно исключением является memo)...
Цитата:
В FPD было единое адресное пространство ...
Не было там этого. Я уже написал как можно проверить работу кэша и SELECT
SQL в FPD... И получить именно то что тебя так напрягает - РАЗНЫЙ результат
"прямого" обращения к полю, и SELECT SQL.
Цитата:
игнорирует результаты выполнения предшествующей REPLACE <fieldname>.
Так не должно быть - по-крайней мере по умолчанию...
- У меня кошка вчера сдохла...
- А что ты с ней такого делал?
- Да ничего, как обычно накормил, напоил... А она сдохла, ничего не
понимаю...
- Ну а ДО того что ты делал?
- Ну до того я ей хвост отрезал - но какое это имеет значение?

Так что не надо ломать причинно-следственную связь. Проблема не в REPLACE и
не в SELECT, и даже не в .Value = '' а в том что ты не понимаешь (пока)
всей совокупности данных действий.




------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Sergey Fadeev
Автор

Сообщений: 106
Откуда: Чебоксары
Дата регистрации: 07.02.2005
Владимир Максимов
А от нас то, ты что хочешь? Мы при всем желании не можем изменить этот режим по умолчанию. Так есть. С этим остается только смириться.

Да не хотел я вас с Игорем просить, чтобы вы изменили этот режим по умолчанию. Просто когда я поделился своими впечатлениями, то в ответ услышал что-то вроде "ты неправ, это на самом деле правильно, так и должно быть". Ладно, если бы это прозвучало от каких-либо "чайников". Но ты и Игорь - в форуме уважаемые авторитеты, и когда такие специалисты говорят, что то или иное хорошо и правильно, то поневоле начинаешь проверять свои мысли и задумываться - а может действительно в таком подходе заложен более глубокий смысл, чем видится мне на поверхности.

Владимир Максимов
Лично меня сильно удивляет такая горячая "привязанность" к команде Select-SQL. Какой глубокий смысл изменить одну (несколько) запись и тут же делать выборку по ВСЕЙ таблице? Лично мне это кажется неправильным. Почему нельзя один раз получить выборку, а потом заниматься только ее модификацией? Тем не менее, так поступают. Вот как в данном примере.
Напомню, что это был искусственно созданный тестовый пример с соответствующей искусственной логикой, специально адаптированной для демонстрации эффекта. В реальном жизни, конечно же, смысла в такой выхолощенной последовательности действий мало. Но это не значит, что она не встретится в реальном коде - например, размазанной по большому кол-ву команд и процедур.
Пример: форма вносит изменения в уже существующую таблицу и эта таблица передается в специальную процедуру, которая в зависимости от содержимого таблицы начинает выполнять какие-то действия. Если эта специальная процедура будет вызываться прямо из формы, то получится неприятный эффект. Конечно, можно вынести эту специальную процедуру за пределы формы и тогда неприятного эффекта не будет. Но внутри формы это смотрелось бы более логично - форма внесла изменения в существующий мир и сама же урегулировала возникшие вопросы путем вызова соответствующей универсальной процедуры. Как насчет применимости такого примера?

Igor Korolyov
У тебя в FPD был объект Form с вложенным объектом Textbox привязанным к этому полю, да ещё и с выполнением Textbox.Value = '' ? Естественно что нет!
GET поля и READ CYCLE ну никак не могут служить аналогом того что есть у тебя сейчас в VFP. Тогда какие претензии?
Igor Korolyov
У тебя как минимум стартовые условия разные...
Игорь, ты опять уходишь от основной мысли. У меня нет и не было претензий к Form, Textbox и Value. У меня вызвало неудомение то, что REPLACE и SELECT-SQL работают в разных адресных пространствах. А эти команды в FPD были (это по поводу разных стартовых условий) и работали в одном адресном пространстве. А вот в VFP - нет (вернее, не всегда). Это раз.
Более того, описанный мною неприятный эффект в VFP встречается не всегда и не везде. Как я уже писал в комментариях к тестовому примеру, если указанный код писать не в форме, а в процедуре, то неприятный эффект отсутствует. Хотя, предполагаю, что кое-какая буферизация у VFP все же присутствует и SELECT-SQL по умолчанию тоже должен читать с диска. Т.е. поведение совершенно одинаковых последовательностей команд REPLACE и SELECT-SQL различается в зависимости от ситуации. Это два.

Igor Korolyov
Конечно я про "обычную" программу - если у тебя вдруг в реальной программе проводятся подобные действия с невидимой формой и невидимым текстбоксом - то даже не знаю чего и посоветовать...
Конечно же, нет.

Igor Korolyov
Не было там этого. Я уже написал как можно проверить работу кэша и SELECT SQL в FPD... И получить именно то что тебя так напрягает - РАЗНЫЙ результат "прямого" обращения к полю, и SELECT SQL.
Нет в данный момент под рукой FPD. Проверю при случае. Но ситуация несколько отличается от моей, хотя и очень близка.
В моем примере обращение к полю и SELECT-SQL находятся в одном процессе, в одном методе и никто снаружи в их работу не вмешивается. В твоем примере работают два разных процесса и один из них успевает извне вмешаться в работу другого, подменив данные. А можешь ты привести пример, когда в FPD делается REPLACE, а после него SELECT-SQL не видит измененных данных, причем в это дело никто не вмешивается?

Igor Korolyov
- У меня кошка вчера сдохла...
- А что ты с ней такого делал?
- Да ничего, как обычно накормил, напоил... А она сдохла, ничего не понимаю...
- Ну а ДО того что ты делал?
- Ну до того я ей хвост отрезал - но какое это имеет значение?

Так что не надо ломать причинно-следственную связь. Проблема не в REPLACE и не в SELECT, и даже не в .Value = '' а в том что ты не понимаешь (пока) всей совокупности данных действий.
Да прекрасно я все понял из ваших с Владимиром объяснений.
Но ты не понял смысл моего предыдущего сообщения по поводу всего вышесказанного. Я, прочитав ваши объяснения, высказал свое ОТНОШЕНИЕ к этому эффекту. Владимир согласился, что да, если бы это было изначально так, то было бы логичнее и понятнее.

А по поводу твоей аналогии с кошкой скажу, что не подходит она к нашему обсуждению. Давай я ее переделаю в нужном направлении!

- У меня кошка вчера сдохла...
- А что ты с ней такого делал?
- Да ничего, как обычно накормил, напоил... А она сдохла, ничего не понимаю...
- А ты ее чем кормил?
- Вон из той упаковки Вискас! Я всегда ее раньше кормил Вискас!
- Э, неправильно ты делаешь! Теперь из зеленой упаковки нельзя напрямую кормить - могут получиться совершенно неожиданные результаты, как, например, в твоем случае. А вот из желтой упаковки можешь кормить, как раньше. Так задумано изготовителем!
- А нельзя было оставить все по умолчанию как прежде - если я кормлю из упаковки Вискас, то результат будет как прежде?
- Не надо ломать причинно-следственную связь. Проблема не в Вискас, а в том, что ты не понимаешь последствий!



P.S. Жаль, что в моем сильно упрощенном примере исчезла разница между работой VFP8SP1 и VFP9. Видимо, я где-то что-то упустил. Начинать копать по-новой?... Я подумаю...
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Hi Sergey!

Чес слово, это уже начинает утомлять
Цитата:
У меня вызвало неудомение то, что REPLACE и SELECT-SQL работают в разных адресных пространствах. А эти команды в FPD были (это по поводу разных стартовых условий) и работали в одном адресном пространстве
Эти команды работают в FPD и VFP одинаково. Никаких "адресных пространств" нету. SELECT (в FPD всегда, в VFP по умолчанию) читает данные с диска, REPLACE же МОЖЕТ помещать их в фоксовый "файловый кэш" - т.е НЕ доводить до диска. Твой пример лишь один из случаев, когда данные НЕ ДОШЛИ. Другой пример - вызов из BROWSE скажем по ON KEY LABEL - тогда ТОЖЕ данные не успевают дойти до диска - т.е. то что было "набрано" в текущем поле (если из него не выходить конечно!) в SQL запросе не будет видно. Кстати тут отчётливо видна разница VFP и FPD контролов! GUI (BROWSE в частности) в FPD и в VFP работает по разному - впрочем это и не удивительно...
Цитата:
если указанный код писать не в форме, а в процедуре, то неприятный эффект отсутствует
Не замечал такого - если просто перенести кусок кода с REPLACE и SELECT в процедуру и её вызывать из той-же точки, то НИЧЕГО не изменится.
Цитата:
поведение совершенно одинаковых последовательностей команд REPLACE и SELECT-SQL различается в зависимости от ситуации
Как по твоему отработает вот этот код:
SELECT table1
REPLACE str4base WITH '1234'
? str4base
100% что ты ответишь неправильно, поскольку я не указал что выполнялось ДО этих строк, а не зная этого ответить правильно НЕВОЗМОЖНО.
Почему же ты считаешь возможным в предыдущем примере оторвать команды от контекста (причём НЕВОСПРОИЗВОДИМОГО в FPD контекста!) и заявлять что что-то работает "не так"?
Цитата:
А можешь ты привести пример, когда в FPD делается REPLACE, а после него SELECT-SQL не видит измененных данных, причем в это дело никто не вмешивается
Понятия не имею, может и есть какие-то ситуации когда среда так себя ведёт, может нету... Хотя привести пример когда вот эти 3 строчки с одной и той-же таблицей приведут к РАЗНОМУ результату конечно могу
SELECT table1
REPLACE str4base WITH '1234'
SELECT * FROM table1 WHERE !EMPTY(str4base)
Цитата:
Я, прочитав ваши объяснения, высказал свое ОТНОШЕНИЕ к этому эффекту
Ты всё ещё не понял в чём суть наблюдаемых результатов, и по прежнему твердишь что "в FPD REPLACE и/или SELECT работал иначе", тогда как это совсем не так.
Цитата:
P.S. Жаль, что в моем сильно упрощенном примере исчезла разница между работой VFP8SP1 и VFP9. Видимо, я где-то что-то упустил
Если учесть что даже на эти 2 несчастные команды влияет такое множество настроек и прочих условий, то думаю не мудрено запутаться... А искать причину - это порой очень сложно... Для того я и говорил про всякие "житейские правила" - это ЗАМЕТНО упрощает жизнь - т.е. отсекается целый пласт сложных/нестабильных состояний системы, когда трудно сказать к чему приведёт банальнейший REPLACE...




------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Sergey Fadeev
Автор

Сообщений: 106
Откуда: Чебоксары
Дата регистрации: 07.02.2005
Igor Korolyov
Эти команды работают в FPD и VFP одинаково.
Сегодня удалось проверить твой пример о том, как два процесса FPD корректируют одну и ту же запись. И твое утверждение, что и в FPD REPLACE и SELECT-SQL работают точно так же, как в VFP. Так вот - ты неправ. Пример показал, что дело там обстоит совершенно не так.

Как работает FPD:
Если я в одном из процессов поменял с помощью REPLACE содержимое поля fieldname, то другой процесс командой ? fieldname прочитает старое содержимое. Если после этого выполнить SELECT-SQL, то он прочитает уже новое содержимое. Но это не говорит о том, что ? fieldname и SELECT-SQL работают в разных адресных пространствах. Ты попробуй после SELECT-SQL прочитать содержимое поля командой ? fieldname. Оно будет новым! Такой же эффект будет, если выполнить сначала SELECT-SQL, а уж за ним - ? fieldname. Тогда ты вообще никогда не обнаружишь расхождения.
Вывод: в FPD команды ? fieldname и SELECT-SQL работают в одном адресном пространстве. Просто SELECT-SQL перед чтением обновляет это адресное пространство, а ? fieldname - нет. Только и всего.

Как работает VFP:
Если слегка модифицировать мой пример, поставив не только перед, но и после SELECT-SQL команду ? fieldname, то можно обнаружить, что ? fieldname и до, и после SELECT-SQL показывает совершенно другое содержимое записи, нежели SELECT-SQL.
Вывод: в VFP команды ? fieldname и SELECT-SQL работают в разных адресных пространствах.

Так что не надо тут говорить, что эти команды в FPD и VFP работают одинаково...

Igor Korolyov
Никаких "адресных пространств" нету.
Если ты имеешь в виду, что такое понятие не существет, то согласен - да, не существует. Его никто не вводил, в документации не описывал и т.д. Но я и не утверждал, что оно есть. Я ввел это понятие, чтобы показать, как просто и удобно было бы, если бы идея адресных пространств всегда соблюдалась бы.
Идея тебе была понятна? Кстати, ты так ничего по этому поводу и не сказал. Согласен ли ты, что это было бы намного проще и понятнее, чем то, что получилось сейчас? Если не согласен, то хотелось бы услышать аргументы - например, в чем проще и понятнее текущая ситуация, или, например, где эта идея приведет к еще большей путанице. А то кроме голословных утверждений типа "да и это правильно!" я пока ничего не услышал...

Если же ты имел в виду, что не существует эффекта адресных пространств, то только что выше я объяснил, что существует.

Igor Korolyov
SELECT (в FPD всегда, в VFP по умолчанию) читает данные с диска, REPLACE же МОЖЕТ помещать их в фоксовый "файловый кэш" - т.е НЕ доводить до диска. Твой пример лишь один из случаев, когда данные НЕ ДОШЛИ.
Для FPD фоксовый "файловый кэш" обновляется (синхронизируется) при чтениях SELECT-SQL, обеспечивая для программиста соблюдение эффекта единого адресного пространства. Для VFP - не обновляется.

Igor Korolyov
Другой пример - вызов из BROWSE скажем по ON KEY LABEL - тогда ТОЖЕ данные не успевают дойти до диска - т.е. то что было "набрано" в текущем поле (если из него не выходить конечно!) в SQL запросе не будет видно.
Это ты специально уводишь разговор в сторону? Я, по-моему, достаточно четко сказал, что здесь вопрос не поднимается о неоконченном вводе в поле. Зачем опять и опять возвращаться к этому вопросу? Для меня он не то, что закрыт - он не был открытым изначально. Поэтому давай оставим неоконченный ввод в покое...

Igor Korolyov
Не замечал такого - если просто перенести кусок кода с REPLACE и SELECT в процедуру и её вызывать из той-же точки, то НИЧЕГО не изменится.
Я имел в виду проделать эти же операции не в форме, а в процедуре (т.е. когда формы нет вообще). Понятно, что процедура, вызванная ИЗ формы, приведет к такому же эффекту, как в форме, т.к. работает в адресном пространстве формы.

Igor Korolyov
Как по твоему отработает вот этот код:
SELECT table1
REPLACE str4base WITH '1234'
? str4base
100% что ты ответишь неправильно, поскольку я не указал что выполнялось ДО этих строк, а не зная этого ответить правильно НЕВОЗМОЖНО.
Покажет 1234.
Если он в зависимости от каких-то предусловий покажет что-то другое, то это ПЛОХО! Именно эту мысль я уже который раз пытаюсь донести до тебя, а в ответ натыкаюсь только на неаргументированное несогласие. Ты хоть раз скажи, почему такое поведение ХОРОШО?
Кстати, хотелось бы увидеть код, который бы в VFP показал что-то отличное от '1234'. Очень любопытно - я с подобным расхождением REPLACE и ? fieldname еще не встречался. Только, надеюсь, это будет реальный код, а не шутка типа eof('table1')=.t. или read-only table1 и т.п.

Igor Korolyov
Почему же ты считаешь возможным в предыдущем примере оторвать команды от контекста (причём НЕВОСПРОИЗВОДИМОГО в FPD контекста!) и заявлять что что-то работает "не так"?
Для тебя что главнее - конкретный контекст или ясная и удобная общая концепция?
Давай посмотрим, что получится, если один из этих параметров развить, а другой задавить - обычный прием технарей (конструкторов, исследователей и т.п.).

Ставя во главу угла контексты и пренебрегая концепциями, можно таких уродливые языки напридумывать, что программировать на них станет невозможно. Программист будет перед каждой командой проверять сотни предусловий и в конце концов махнет на все рукой.

Ставя во главу угла ясную и удобную общую концепцию такого эффекта, как в предыдущем абзаце, ты никогда не получишь. Это будет просто невозможно! И присутствие контекста здесь тоже не исключается - главное, чтобы он был ясным и удобным.

Вот почему я не делаю идола из контекста. Вот почему если он, на мой взгляд, противоречит ясной и удобной концепции, то я считаю возможным дать оценку такому явлению. Но это мое личное мнение - думаю, что я сейчас достаточно понятно, объяснил, почему я так считаю, и на этом твой вопрос "Почему ты считаешь?" будем считать закрытым, т.к. его обсуждение к теме не относится...

Igor Korolyov
Ты всё ещё не понял в чём суть наблюдаемых результатов, и по прежнему твердишь что "в FPD REPLACE и/или SELECT работал иначе", тогда как это совсем не так.
Суть наблюдаемых результатов я понял, выслушав твое и Владимира мнения. И предположение, что это ошибка, после этого было закрыто. Владимир мне доступно объяснил, что это уже давно так в VFP повелось, а раз такое дело, то теперь нет смысла говорить, что это ошибка. Просто так изначально получилось в VFP, такая вот идея была заложена. С ним я полностью согласен и вопрос об ошибке отпал сам собою. (Единственное, что мне осталось - это получить все-таки тестовый пример, когда VFP8SP1 и VFP9 ведут себя по-разному. Только после того, как это удастся, можно будет говорить о том, что в VFP9 возможно закралась ошибка...).
Если ты внимательно читаешь мои последние сообщения, то увидишь, что в них я не говорю об ошибке, а высказываю мнение по поводу того, удобно или неудобно получилось в VFP. Я сказал, что удобнее было бы изначально сделать по-другому. И объяснил почему. Владимир со мной согласился. Ты - нет. Может ты все-таки скажешь почему?
А насчет SELECT и REPLACE в FPD и VFP я сказал выше. Буду ждать твоих доводов о том, что они одинаково работают...

Igor Korolyov
Для того я и говорил про всякие "житейские правила" - это ЗАМЕТНО упрощает жизнь - т.е. отсекается целый пласт сложных/нестабильных состояний системы, когда трудно сказать к чему приведёт банальнейший REPLACE...
Ну вот видишь - ты вроде бы тоже за простые и удобные концепци...
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Hi Sergey!

Да уж, неверно поставленный эксперимент приводит к неадекватным выводам
1) Создаём таблицу с одной записью (для простоты)
CREATE TABLE T1 (C1 C(10))
APPEND BLANK
USE
2) Запускаем в одной копии фокса программу "записи"
lc1 = "Q:\test\"
CLEAR
SET TALK OFF
IF !USED("t1")
USE (m.lc1 + "t1") SHARED IN 0
ENDIF
DO WHILE LASTKEY() # 27
REPLACE c1 WITH STR(SECONDS())
FLUSH
=INKEY(0.5)
ENDDO
3) Запускаем во второй копию фокса программу чтения.
lc1 = "Q:\test\"
CLEAR
SET TALK OFF
* Чтобы не томится, поставим на 2 секунды
SET REFRESH TO 0, 2
IF !USED("t1")
USE (m.lc1 + "t1") SHARED IN 0
ENDIF
IF !USED("t3")
USE (m.lc1 + "t1") SHARED IN 0 AGAIN ALIAS t3
ENDIF
DO WHILE LASTKEY() # 27
GO 1 IN t1
SELECT *, 33 FROM (m.lc1 + "t1") INTO CURSOR t2
@ 1,1 SAY t1.c1 + " , " + t2.c1 + " , " + t3.c1
ENDDO
Наблюдаем, делаем выводы... Особенно обрати внимание на 2 якобы "одинаковых" курсора t1 и t3 Как это согласуется с твоей концепцией "адресных пространств которых не было в FPD"?

Цитата:
Цитата:
Как по твоему отработает вот этот код:
SELECT table1
REPLACE str4base WITH '1234'
? str4base
100% что ты ответишь неправильно
Покажет 1234
Ну вот видишь, ты практически попался А теперь скажи что будет
1) Если стоим на EOF() или если в таблице НЕТ записей (что равноценно)
2) Если тип поля C(1)
3) Если такого поля вообще нету или оно несовместимого типа
4) Если поле/таблица заблокированы другим пользователем
5) Если прописан триггер, или хитрый Rule меняющий значение поля при вводе
И так долго можно продолжать
Цитата:
это ПЛОХО!
Это замечательно! Это так и должно быть! И это не шутка - я лишь хочу показать, что "оторванный" от контекста код никак не может работать "одинаково" везде и всегда!
Давай даже проще - ты считаешь что по команде QUIT ВСЕГДА происходит закрытие приложения? Я же утверждаю что не всегда, и это ПРАВИЛЬНО!
Цитата:
Для тебя что главнее - конкретный контекст или ясная и удобная общая концепция
Концепция описана в хелпе - SQL НЕ берёт данные из открытых алиасов, а делает внутри себя нечто типа USE AGAIN. От того и описанное поведение, и многое другое - например игнорирование SET FILTER/ORDER/RELATION/несохранённых значений (буфера и как оказывается даже иногда кэша!)
Возможно она не "ясная" (насчёт удобства спорить не стану - мне удобно так как ЕСТЬ, а не так как оно было-бы, если бы брались данные из какого-то из имеющихся курсоров - с учётом тамошних FILTER/ORDER и т.п.)
Цитата:
Программист будет перед каждой командой проверять сотни предусловий и в конце концов махнет на все рукой
Ты же пишешь цельную программу, а не бездумный набор команд! Ты должен знать в каком состоянии может оказаться среда исполнения в каждый конкретный момент - и если тебя это состояние почему-то не устраивает - изменить его!




------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Sergey Fadeev
Автор

Сообщений: 106
Откуда: Чебоксары
Дата регистрации: 07.02.2005
Привет, Игорь!

Igor Korolyov
Да уж, неверно поставленный эксперимент приводит к неадекватным выводам
Совершенно верно!

Ты, конечно, молодец, что не веришь на слово, начинаешь проверять информацию и продолжил исследование адресных пространств, но есть одно существенное замечание. Посмотри код моего примера и заметь, что команды работают в ОДНОЙ РАБОЧЕЙ ОБЛАСТИ. Прочитай еще раз все мои сообщения по обсуждению этого примера и заметь, что я нигде не переходил на обсуждение работы в РАЗНЫХ РАБОЧИХ ОБЛАСТЯХ. А вот твой пример демонстрирует работу именно в разных рабочих областях. А это, как говорит реклама, уже "совсем другая тема"!

А вот в одной рабочей области он только еще раз подтверждает, что правило единого адресного пространства соблюдается: t1 и t2 изменяются абсолютно так же, как я написал для FPD в предыдущем сообщении. Я так и не дождался, чтобы t1 и t2 изменялись бы несинхронно. А вот в VFP это возможно...

И еще одно существенное замечание. В VFP команды ? fieldname и SELECT-SQL могут давать разные результаты даже когда:
- эти команды расположены в одной рабочей области (об этом я уже сказал)
- корректировка идет в этой же области!
- таблица никем больше не корректируется и даже не открывается!
Согласись, что это сильно отличается от твоего примера.

Так что, как видишь, действительно "неверно поставленный эксперимент приводит к неадекватным выводам".

Igor Korolyov
Ну вот видишь, ты практически попался А теперь скажи что будет
1) Если стоим на EOF() или если в таблице НЕТ записей (что равноценно)
2) Если тип поля C(1)
3) Если такого поля вообще нету или оно несовместимого типа
4) Если поле/таблица заблокированы другим пользователем
5) Если прописан триггер, или хитрый Rule меняющий значение поля при вводе
И так долго можно продолжать
Ага, еще можно добавить "Если фокса вообще на компьютере нет" и "Если и компьютера тоже нет". Детский сад, да и только...

А если серьезно:
Во-первых, ты хоть чувствуешь разницу между НОРМАЛЬНОЙ работой команды и ЕЕ РЕАКЦИЕЙ НА СИТУАЦИИ, МЕШАЮЩИЕ нормальной работе? В моем тестовом примере была хоть одна нестандартная ситуация, мешающая нормальной работе? Ну и зачем нужно было так откровенно передергивать?
Во-вторых, ты читать умеешь? А как насчет этого?
Sergey Fadeev
Только, надеюсь, это будет реальный код, а не шутка типа eof('table1')=.t. или read-only table1 и т.п.
Некрасиво, знаешь ли...
Igor Korolyov
Это замечательно! Это так и должно быть! И это не шутка - я лишь хочу показать, что "оторванный" от контекста код никак не может работать "одинаково" везде и всегда!
Увы и ах! Попытка у тебя не удалась - пример не подходит.
Жду следующих попыток...

Igor Korolyov
Давай даже проще - ты считаешь что по команде QUIT ВСЕГДА происходит закрытие приложения? Я же утверждаю что не всегда, и это ПРАВИЛЬНО!
Давай я сейчас тебе покажу в твоей же манере, как можно здесь передернуть?
С твоим подходом я готов про любую команду сказать "Ребята! Я вам про эту команду вот что скажу - результат сильно зависит от того, запустите ли вы эту команду на выполнение или не запустите, а так же от того, зависнет ли компьютер при ее выполнении или не зависнет!"

Sergey Fadeev
Для тебя что главнее - конкретный контекст или ясная и удобная общая концепция?
И все-таки - ты не уходи от этого вопроса, ответь на него. А то тут агитировал за его величество контекст, а после моего аргумента тихо замял это дело. Что, контекст, оказывается, уже не главнее концепции?

Igor Korolyov
Концепция описана в хелпе - SQL НЕ берёт данные из открытых алиасов, а делает внутри себя нечто типа USE AGAIN.
Специально заглянул в help VFP9, просмотрел топик "SELECT - SQL Command" и, как более детальный, "SELECT - SQL Command - FROM Clause". Нет там ничего подобного. Нигде не упоминается, что учтите, мол, что данная команда, даже если вы укажите какой-либо алиас, на самом деле будет использовать не его, а создаcт еще один алиас с помощью USE AGAIN со всеми вытекающими эффектами.

Igor Korolyov
Возможно она не "ясная" (насчёт удобства спорить не стану - мне удобно так как ЕСТЬ, а не так как оно было-бы, если бы брались данные из какого-то из имеющихся курсоров - с учётом тамошних FILTER/ORDER и т.п.)
А кто у нас тут хоть раз заикался о FILTER/ORDER и т.п.? О том, что как хорошо было бы, если данные брались с учетом FILTER/ORDER? Я - нет. Тогда давай не будем опять отвлекаться и уходить в сторону. И, отбросив в сторону отговорки типа FILTER/ORDER, теперь попробуй оценить удобство, т.е. все тоже самое, что и сейчас, но работа идет в одном адресном пространстве, как в FPD. Ну как?

Igor Korolyov
Ты же пишешь цельную программу, а не бездумный набор команд! Ты должен знать в каком состоянии может оказаться среда исполнения в каждый конкретный момент - и если тебя это состояние почему-то не устраивает - изменить его!
А кто тут у нас заводил разговор, что контекст не следует изучать? Я? Ты? Так я не пойму - с кем ты сейчас споришь? Кому и что доказываешь?
Опять отвлекаешься? Нить-то разговора была совсем другая:
- Твоим аргументом против моей концепции был его величество контекст.
- Я показал, что контекст по важности даже близко с концепцией не лежит.
- Ты почему-то, ни с того ни с сего начинаешь доказывать, что контекст тоже надо знать.
Я что, где-то утверждал, что его знать не надо? Что за манера уводить разговор в сторону, доказывать то, что никто не опровергает и на этом основании считать, что и в других вопросах ты автоматически становишься прав?
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
MichaelD

Сообщений: 7578
Дата регистрации: 14.05.2005
Hi, Sergey & All!

Изменение REPLACE на SQL-UPDATE приводит к желаемому... т.е. попробуй заменить кусок твоего кода:

** Сейчас сделаем изменение в таблице,
** которое будет видимым только частично:
** при прямом обращении к полю таблицы оно видно,
** а вот SQL-выборка его не увидит.
sele table1
replace str4base with ''
на
UPDATE table1 SET str4base = ''

Мои объяснения? Хм... железных нет , только догадки... ;)



Отредактировано (02.09.05 11:31)


------------------
С уважением,
Михаил Дроздов, Пермь, Россия
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Hi Sergey!

Цитата:
Посмотри код моего примера и заметь, что команды работают в ОДНОЙ РАБОЧЕЙ ОБЛАСТИ
Из хелпа:
SELECT doesn't use your work areas; it performs the equivalent of USE ... AGAIN
Так что ты не прав.
Цитата:
t1 и t2 изменяются абсолютно так же, как я написал для FPD
Ну поменяй на GO RECNO("t3") IN t3 или вообще закомментируй эту команду! Если смущает задание пути в SELECT - убери его, оставь свой "алиас" НИЧЕГО не изменится.
Цитата:
В VFP команды ? fieldname и SELECT-SQL могут давать разные результаты даже когда: - эти команды расположены в одной рабочей области
Читай выше - они НЕ работают "в одной рабочей области" - даже в хелпе к FPD это чётко написано. Вот в VFP9 с его "надстройкой" WITH (BUFFERING=.T.) это УЖЕ возможно - до того - нет! И кстати именно их хелпа VFP9 была убрана процитированная ремарка - т.к. она стала неактуальна.
Цитата:
чувствуешь разницу между НОРМАЛЬНОЙ работой команды и ЕЕ РЕАКЦИЕЙ НА СИТУАЦИИ, МЕШАЮЩИЕ нормальной работе?
Да.
Цитата:
В моем тестовом примере была хоть одна нестандартная ситуация, мешающая нормальной
работе?
Да.
При этом КОМАНДЫ все работают так как им и положено - REPLACE проводит обновление в одном курсоре (НЕ записывая данные на диск из-за предварительных манипуляций с текстбоксом), SELECT выбирает данные "проводя эквивалент USE ... AGAIN" из совсем другого курсора. Ситуация аналогична тому что в моём примере наблюдается между курсорами t3 и t2 (и БУДЕТ наблюдаться между t1 и t2 если убрать GO).
Цитата:
пример не подходит
Надо было подумать и поэкспериментировать. В частности подумать ЗАЧЕМ в примере стоит GO, убрать его, сделать GO в t3 и т.п.
Цитата:
работа идет в одном адресном пространстве, как в FPD
Почитай хелп к FPD. После этого говори в одном или не в одном. И поменяй термин - "адресное пространство" имеет своё чётко определённое значение. Тут можно применить термин курсор - понимая под ним у совокупность внутренних структур среды исполнения, которые обеспечивают доступ к какому-то источнику данных.
Цитата:
- Твоим аргументом против моей концепции был его величество контекст
- Я показал, что контекст по важности даже близко с концепцией не лежит
- Ты почему-то, ни с того ни с сего начинаешь доказывать, что контекст тоже
надо знать. Я что, где-то утверждал, что его знать не надо?
1) С негативным оттенком - типа "фи, какая гадость, так быть не должно и в FPD так не было"
Цитата:
Цитата:
У тебя как минимум стартовые условия разные...
Т.е. поведение совершенно одинаковых последовательностей команд REPLACE и SELECT-SQL различается в зависимости от ситуации
2) На мои возражения - прямое и безаппеляционное
Цитата:
Если он в зависимости от каких-то предусловий покажет что-то другое, то это ПЛОХО!
IMHO это и есть игнорирование контекста и это неправильно.




------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Sergey Fadeev
Автор

Сообщений: 106
Откуда: Чебоксары
Дата регистрации: 07.02.2005
Привет, Игорь!

За тестовый пример - спасибо. Это без шуток. Он помог мне уточнить границы применимости моего вывода насчет неодинакового поведения команд в FPD и VFP. Раньше мой вывод ошибочно был слишком обширным и касался всех ситуаций, то теперь из этого множества исключены ситуации, когда корректировка идет в другом процессе.

А по поводу
Цитата:
Надо было подумать и поэкспериментировать. В частности подумать ЗАЧЕМ в примере стоит GO, убрать его, сделать GO в t3 и т.п.
скажу, что обычно если приводят пример, опровергающий чью-то мысль, то стараются подобрать такое сочетание команд, где наглядно видны противоложные результаты. Ты же привел пример, который в первоначальном варианте не опровергал, а подтверждал мою мысль. Согласись, что мне не было никакого смысла искать, что же в этом примере надо переделать, чтобы он подтвердил твою, а не мою мысль. Я так и не понял, какой был смысл изначально в тот пример включать команду GO и вводить дополнительную таблицу t3 - именно без них твой пример был самым наглядным...
Igor Korolyov
И поменяй термин - "адресное пространство" имеет своё чётко определённое значение. Тут можно применить термин курсор - понимая под ним у совокупность внутренних структур среды исполнения, которые обеспечивают доступ к какому-то источнику данных.
Если подходить с той же меркой, то курсор тоже не подходит, т.к. тоже имеет свое четко определенное значение.
Все-таки адресное пространство, IMHO, подходит больше. Имя поля, подобно адресу, позволяет обратиться к некоему конкретному содержимому, хранящемуся под этим адресом. Передав имя поля одним командам (например, ? fieldname), мы указываем ОТКУДА получить содержимое. Передав имя поля другим командам (например, REPLACE), мы указываем ГДЕ поменять значение. Поэтому совокупность имен полей очень похожа на совокупность адресов, ссылающихся на некоторое адресуемое пространство.
Адресное пространство - более широкое, более абстрактное понятие, чем курсор, и позволяет оперировать, не отвлекаясь на некоторые детали, которые обязательно возникнут, если мы начнем вместо него подставлять слово "курсор".

Но вернемся к примеру.
Итак, благодаря тебе найден случай, когда ? fieldname и SELECT-SQL fieldname могут работать в разных адресных пространствах. Это случай, когда команда REPLACE работает в другом процессе. В итоге из приведенных мною условий
Цитата:
В VFP команды ? fieldname и SELECT-SQL могут давать разные результаты даже когда:
- эти команды расположены в одной рабочей области (об этом я уже сказал)
- корректировка идет в этой же области!
- таблица никем больше не корректируется и даже не открывается!
первое условие следует исключить, т.к. в FPD такое тоже возможно при определенных ситуациях. Но остальные два все же остались. И по ним FPD и VFP работают по-разному!
Взяв твой пример за основу (как наиболее удачный в плане демонстрации), я сделал тестовые примеры для FPD и VFP. Чтобы пример был максимально наглядным и разница в поведении VFP и FPD была сразу видна, я вынес спорный код в отдельную процедуру cycle.prg - единую для VFP и FPD. Кроме того, чтобы не надо было наблюдать за экраном, я на него вывожу только итоги.

Порядок применения:
1. Запустить create.prg.
2. Если проверяем VFP, то запустить процедуру vfp.prg. А если FPD, то fpd.prg.

** create.prg - Процедура создания тестовой таблицы
set safe off
create table t1 (c1 c(10), c2 c(1))
append blank
use in t1
** fpd.prg - запуск теста из FPD
set echo off
set talk off
set esca on
clear all
close all
clear
set refresh to 0,2
use t1 in 0 share
do cycle.prg
** vfp.prg - запуск теста из VFP
set echo off
set esca on
clear all
close all
clear
set refresh to 0,2
_myForm=NewObject("myForm")
define class myform as form
proc Init()
use t1 share
This.NewObject('tb2','textbox')
with This.tb2
.ControlSource = "t1.c2"
.Value=''
endwith
do cycle.prg
endproc
enddefine
** cycle.prg - процедура тестирования поведения команд
priv _plSame, _plDiff, _lnCount
store 0 to _plSame, _plDiff, _lnCount
do while .t.
_lnCount=_lnCount+1
sele t1
replace c1 with str(_lnCount,10)
select *, 33 from t1 into cursor t2
if t1.c1==t2.c1
_plSame=_plSame+1
else
_plDiff=_plDiff+1
endif
@ 1,1 say 'Same='+str(_plSame)+', Different='+str(_plDiff)
enddo
Я честно прождал более 2.3 млн.циклов для FPD, ожидая, когда же он выдаст хотя бы один результат в стиле VFP. Не дождался. Росли одни Same, а Different был все время равен 0.
Но ради справедливости надо отметить, что VFP все же один раз сработал в стиле FPD. Я тоже стал ждать до 2.3 млн. циклов, надеясь, что может будет еще одно срабатывание. Не дождался. Итог: Same=1, Different>2.3 млн.

Глядя на полученные результаты, я все же остаюсь при своем мнении: FPD и VFP со старыми командами работают по-разному.
Думаю, что после приведенного мною примера следует прекратить дискуссию, одинаково или нет работают старые команды в разных фоксах. Даже если будет найден еще один пример, опровергающий еще одно из двух моих оставшихся условий - это нисколько не повлияет на вывод. Т.к. пока существует хотя бы один пример, когда оба фокса работают по-разному, нельзя утверждать, что старые команды работают одинаково.
Свое мнение по поводу того, хорошо это или плохо, я уже высказал. И еще раз скажу, что ПО УМОЛЧАНИЮ желательно было бы оставить как прежде. Но делать это надо было, как справедливо заметил Владимир, еще в VFP3. Теперь уже поздно...

Теперь забудем о FPD и вернемся чисто к VFP.
Еще раз сформулирую оставшееся мое недовольство с учетом полученной новой информации. Чем мне не нравится сложившаяся ситуация? Процедура cycle.prg ведет себя по-разному, будучи вызванной из формы и из обычной процедуры. Будучи вызванной из обычной процедуры, она ведет себя по одному варианту (как в FPD), а будучи вызванной из формы (причем не любой, а с определенными условиями) может вести себя совершенно противоположно.
Чем это, на мой взгляд, плохо? Тем, что я при написании универсальной процедуры всегда должен помнить, откуда я ее вызываю. Есть ли в стеке вызовов форма? Если есть, то сложились ли в ней условия для измененного поведения команд, т.к. разные формы будут вести себя по-разному (достаточно одной лишь команды типа .Value=<something>)?
Особенно прикольно искать ответ на последний вопрос, если ранее встречались команды if, приводящие к ветвлению алгоритма. Да и список этих команд (меняющих поведение других команд) нигде не обнародован...
И твоя мысль по поводу того, что контекст здесь разный и его надо учитывать, меня здесь совершенно не греет. Ну на кой черт мне здесь проблемы на ровном месте? Которых могло бы не быть. И главное - во имя чего? Я так и не услышал, ЧЕМ такой вариант поведения полезен. Пока я вижу один лишь геморрой.
Пока мы тут спорили, я уже попытался решить проблему наскоком - не переделывая кучу строк проекта. Поставил SET SQLBUFFERING ON. И понял, что это не решение - появилось множество глюков в совершенно неожиданных местах. Пришлось срочно переключать обратно на OFF (по умолчанию).
Теперь у меня закрались подозрения, что и WITH (BUFFERING=.t.), как одномоментный вариант SET SQLBUFFERING ON, надо еще проверять и проверять на побочные эффекты. Это не считая того, что команд SELECT-SQL у меня в проекте раскидано ой как много!
Спасибо Михаилу - он привел вариант замены REPLACE на UPDATE, как выход из положения. Но это опять-таки переделывать кучу кода...
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Hi Sergey!

Мне наша дискуссия стала напоминать старый анекдот:
ГАИшник останавливает машину и спрашивает водителя:
- Если лобовое стекло разбить, колёса сдуются?
А водила ему в ответ:
- А если я тебе монтировкой по голове дам, шнурки развяжутся?

Мой пример показывает банальный факт - то что даже при обращении к ОДНОЙ
таблице из РАЗНЫХ курсоров мы получаем РАЗНЫЕ результаты. Ну возможно для
наглядности надо было сразу в t3 GO делать... Чтобы не возникало неверной
иллюзии, что SELECT выбирает данные из уже открытого курсора t1...

Я не стану комментировать весь твой код, просто укажу на ОДНУ ГЛАВНУЮ вещь -
ты делаешь REPLACE в ОДНОМ курсоре, а SELECT выбирает данные их ДРУГОГО
курсора (и про это ясно написано в хелпе). Да, в FPD я не знаю как можно
создать такую конфликтную ситуацию, чтобы REPLACE в одном курсоре не повлиял
на остальные курсоры открытые (или "якобы открываемые автоматически", как в
случае с SELECT SQL) на базе этой-же таблицы (именно в рамках одного
процесса) - но и утверждать что такого состояния в FPD невозможно достигнуть
тоже не стану. В VFP ты один способ нашёл...

Насчёт "что делать" я уже неоднократно писал - нужно нестабильное состояние
перевести в стабильное и предсказуемое. В частности сделать FLUSH в
процедуре с REPLACE, ну и/или выполнять увод фокуса с "привязанного" к полю
текстбокса в форме - при условии что намечается какая-либо работа с данным
курсором.
UPDATE как и SELECT будут работать банально в ДРУГОМ курсоре (якобы
автоматически открываемом на время работы команды) - и более чем вероятно,
что ты получишь ровно ту-же самую ситуацию, но с точностью до наоборот.




------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Sergey Fadeev
Автор

Сообщений: 106
Откуда: Чебоксары
Дата регистрации: 07.02.2005
Igor Korolyov
Да, в FPD я не знаю как можно создать такую конфликтную ситуацию, чтобы REPLACE в одном курсоре не повлиял на остальные курсоры открытые (или "якобы открываемые автоматически", как в случае с SELECT SQL) на базе этой-же таблицы (именно в рамках одного процесса) - но и утверждать что такого состояния в FPD невозможно достигнуть тоже не стану.
Я тоже не буду это утверждать. Возможно, что и существует в FPD такая последовательность команд, когда ? fieldname, REPLACE и SELECT-SQL в рамках одного процесса работают не в одном адресном пространстве, но я с такой ситуацией не сталкивался. И хотел бы не сталкиваться и в VFP, но не получилось...

В VFP можно увидеть оба варианта поведения:
- в разных адресных пространствах (если в стеке вызовов есть форма, где есть привязка к любому из полей нашей таблицы и есть хотя бы одно присвоение значения такому полю - неважно, ручное или через .Value).
- в одном адресном пространстве (в всех остальных случаях; хотя не исключаю, что это вариант может быть сужен за счет нахождения других вариантов работы в разных адресных пространствах).

За неимением в данный момент серьезных доводов против, я все же остаюсь при своем мнении, что разумнее было бы изначально оставить только один вариант поведения. Но "поезд ушел" и теперь придется учитывать оба варианта поведения...

Igor Korolyov
В частности сделать FLUSH в процедуре с REPLACE, ну и/или выполнять увод фокуса с "привязанного" к полю текстбокса в форме - при условии что намечается какая-либо работа с данным курсором.
Вариант с FLUSH мне не очень нравится. Получается, что для того чтобы получить адекватные результаты в отдельных случаях, я везде должен перестраховочно ставить FLUSH до команды SELECT-SQL. Иначе рискую получить не то, что хотел, т.к. мои процедуры в общем случае могут быть вызваны откуда угодно, в т.ч. и из формы...
Насчет увода фокуса попробую разобраться, хотя есть некоторые сомнения. Дело в том, что код с REPLACE и SELECT-SQL у меня в реальном проекте выполняется в процедуре, вызванной из метода Click() кнопки CommandButton "Записать", к которой никакие поля не прикручены и в тот момент, когда все LostFocus() у всех прикрученных текстбоксов уже отработали. Но эффект остается...

Хочу подвести итоги разговора:
В процессе обсуждения выяснилось, что в VFP команды REPLACE и SELECT-SQL в рамках одного процесса в некоторых случаях работают не в одном адресном пространстве. При более детальном рассмотрении оказалось, что виновницей является не команда SELECT-SQL, как ранее мною предполагалось, а команда REPLACE.

Такой вариант итога устраивает?
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Hi Sergey!

Нет не устраивает!
Цитата:
когда ? fieldname, REPLACE и SELECT-SQL в рамках одного процесса работают не в одном адресном пространстве
Ещё раз - SELECT SQL и REPLACE ВСЕГДА работают в РАЗНЫХ курсорах (или "адресных пространствах" если тебе так угодно) REPLACE и ? в твоем примере работают в ОДНОМ курсоре. Поведение одинаково что в FPD что в VFP.
Есть отличия в "распространении" изменений вносимых REPLACE. Если они не доходят до ОС (грубо говоря не записываются на диск), то и внутри фокса в РАЗНЫХ курсорах мы увидим РАЗНЫЙ результат. Т.е. получим "несинхронизированные" курсоры.
И тут дело не в "виновности" REPLACE, а в том что она ДОЛЖНА учитывать разные "внешние условия" - в т.ч. и "подвисшую" блокировку получившуюся в результате того самого "незаконченного ввода".




------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Sergey Fadeev
Автор

Сообщений: 106
Откуда: Чебоксары
Дата регистрации: 07.02.2005
Igor Korolyov
Ещё раз - SELECT SQL и REPLACE ВСЕГДА работают в РАЗНЫХ курсорах (или "адресных пространствах" если тебе так угодно)
Насчет ВСЕГДА в отношении курсоров я согласен. А насчет адресных пространств - нет. Приведи пример, когда SELECT-SQL и REPLACE в рамках одного процесса FPD работают в РАЗНЫХ адресных пространствах. Чтобы программист смог увидеть эту разницу. Пока нет ни одного примера считать, что они работают в разных адресных пространствах (а доводов считать, что они работают в одном адресном пространстве, - хоть пруд пруди), я останусь при своем мнении.
Кстати, именно поэтому я не согласился на предлагаемую тобой замену понятия "адресного пространство" на "курсор". Как видишь, твой вывод насчет курсоров звучит верно. А насчет адресных пространств - пока неверно.

Igor Korolyov
Есть отличия в "распространении" изменений вносимых REPLACE. Если они не доходят до ОС (грубо говоря не записываются на диск), то и внутри фокса в РАЗНЫХ курсорах мы увидим РАЗНЫЙ результат. Т.е. получим "несинхронизированные" курсоры.
И тут дело не в "виновности" REPLACE, а в том что она ДОЛЖНА учитывать разные "внешние условия" - в т.ч. и "подвисшую" блокировку получившуюся в результате того самого "незаконченного ввода".
Можно сколь угодно глубоко и детально описывать, как внутри ведет себя REPLACE в тех или иных ситуациях, что она там учитывает или не учитывает, вносит или не вносит. На поверхности же вывод останется все тем же: в VFP команды REPLACE и SELECT-SQL в рамках одного процесса в некоторых случаях работают не в одном адресном пространстве. Дальше спорить будешь?
Как ты уже показал, дело тут не в SELECT-SQL (и я согласился с твоим выводом). Остается только REPLACE.
Ты же сам только что написал, что
Цитата:
Есть отличия в "распространении" изменений вносимых REPLACE
так чем же тебя не устраивает мой вывод, что причиной является REPLACE? Что там на внутреннем уровне происходит, где и куда там внутри команды REPLACE не пропихиваются данные, и чего она там не учитывает - на внешнем уровне (уровне программиста) не имеет значения. Если раньше программист мог доверять совместной работе REPLACE с другими командами, то теперь он должен делать это с осторожностью, т.к. не везде и не всегда он получит ожидаемые результаты.
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Hi Sergey!

Низзя быть таким упёртым в своих заблуждениях
На, держи пример для FPD.
CREATE TABLE test (c1 C(10))
INSERT INTO test (c1) VALUES ("test")
CLOSE ALL
USE test SHARED IN 0 ALIAS t1
USE test SHARED IN 0 ALIAS t2 AGAIN
SELECT t2
REPLACE c1 WITH "t2"
SELECT *, 'new' FROM t1 INTO CURSOR t3
? t1.c1, t2.c1, t3.c1

Нету тут никаких "адресных пространств", а вот разные курсоры/алиасы есть, и
отчётливо видно что SELECT НЕ БЕРЁТ данные из курсора t1, а берёт их с
диска - куда их кстати в данном случае таки записал тот-же процесс, но через
ДРУГОЙ курсор/алиас...
Только не надо говорить о "коренном отличии" - да, этот пример показывает не
то что REPLACE якобы не сработал, а только банальнейший факт в t1 мы видим
одно, а в SELECT ... FROM t1 - совсем другое.
Можешь потом прописать GO RECNO("t1") IN t1 и посмотреть что теперь даёт
"прямой" доступ и доступ "через SELECT".
Кстати говоря в VFP ЭТОЙ "аномалии" не наблюдается - курсоры обновляются все
сразу - без лишних движений.
Цитата:
Если раньше программист мог доверять совместной работе REPLACE с
другими командами, то теперь он должен делать это с осторожностью, т.к. не
везде и не всегда он получит ожидаемые результаты
И раньше и сейчас программист ДОЛЖЕН учитывать особенности работы SQL
команд - а именно то, что они берут данные не из того курсора который
прописан во FROM, а из "подлежащей" под ним таблицы. Главное, что весьма
ВОЗМОЖНЫ (даже можно сказать вполне ОБЫДЕННЫ) ситуации, когда xBase команды
(да тот-же банальный ? t1.Field) показывают одно, а SELECT "якобы" из
этого-же курсора показывает совсем другое.




------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Beginner
По поводу того, что, откуда и, главное, КАК берет SELECT:

Неделю назад возникла ситуация, когда пришлось на двух машинах вручную синхронизировать два справочника (сбой механизма репликации чисто из-за моей спешки при модификации структуры). Пишу обе таблицы на флэшку, приезжаю, делаю (поскольку конструкция типа INSERT INTO неполная_таблица SELECT * FROM полная_таблица WHERE key_field NOT IN и т.д. в 8-ке не пошла) что-то вроде:

SELECT * FROM полная_таблица WHERE key_field NOT IN (SELECT key_field FROM неполная_таблица)
SELECT неполная_таблица
APPEND FROM DBF('Query')

Структура таблиц-справочников практически идентична, отличия только в размерности полей.
Первая проходит на ура, на второй я тихо выпадаю в осадок: Primary key not unique.
Смотрю курсор, там 3 записи, в поле с UID - ничего похожего на то, что есть в "неполная_таблица".
Через пару минут ступора случайно утыкаюсь взглядом в статус бар и окончательно ....ю, поскольку вижу что-то типа "Record: 21/175" находясь на ВТОРОЙ строчке курсора из ТРЕХ записей.
Меняю названия таблиц на первую пару - получаю две "честных" записи, возвращаюсь к этим - та же хрень. В итоге, только SELECT * FROM сбрендивший_курсор вернул те 3 записи, которые я и хотел от первого запроса.
Повторить эффект на другой железке не удалось, на "боевой" экспериментировать что-то больше не тянет...
Во-о-от, а вы тут "Таити, Таити..." I'm sorry, "Adress space", of cource...
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Hi Beginner!

Первый раз слышу чтобы WHERE ... NOT IN (SELECT ...) создавала "фильтрованный алиас". Хотя при ДРУГИХ условиях WHERE это происходит сплошь и рядом - для чего и был придуман модификатор NOFILTER.
Отличить "правильный" курсор от "фильтрованной таблицы" легко - DBF("Query") в первом случае даст нечто типа "C:\DOCUME~1\USERNAME\LOCALS~1\TEMP\00003IFD000P.TMP" а во втором "правильный" путь к самой исходной таблице - если не баловаться с расширениями, то по JUSTEXT(DBF("Query")) == "TMP" можно смело проверять тип курсора.
В общем никакой мистики




------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Эксперименты с FLUSH в VFP9
Beginner
To Igor Korolyov:

Ну так и я в первый раз... Причем, начав эксперименты с dbf даже не с FPх 2.0, а с FoxBase и "Карата"... (Это - для понимания отношения к нику... )
А мистика - наверное всё же есть: напоминаю, структура таблиц - без вывертов, практически одинаковая, отличия лишь в длине полей, а вот результат выполнения одной и той же команды различается в зависимости от того, отрабатывает она по паре таблиц с именами "Table7" или "Table9"...
Я ж ленивый, только одну цифру в имени таблиц менял...
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 24 (Гостей: 24)

© 2000-2024 Fox Club 
Яндекс.Метрика