گیک آزاد

Free/Geek/Life.sh

چطور دیتایی از نوع دیتاتایپ CLOB را از دیتابیس بازخوانی کنیم؟

نویسنده:
۱۷ آذر ۹۶

همیشه یکی از سخت‌ترین قسمت‌های کار کردن با دیتابیس‌های Relational سروکله زدن با دیتا تایپ‌های LOB یا همون Large Objectها است مثل دیتا تایپ CLOB که برای ذخیره کردن بیش از چهارگیگابایت text استفاده میشه. همونطور که از اسمش هم بر میاد این نوع دیتا تایپ، Object هست پس نمیشه مثل یک استرینگ با اون رفتار کرد و مثلا اون رو به راحتی داخل یک آرایه در کنار سایر ستون‌های با دیتا تایپ‌ دیگر ریخت و نمایش داد. بازخوانی اطلاعات از نوع این دیتا تایپ کار زیاد ساده‌ای نیست و به ترفندهایی نیاز دارد. متاسفانه در جستجوهایی که انجام دادم راه حل غیر پیچیده و خوب کمتر دیدم و اکثر روشهای موجود نتونست مشکل من رو حل کنه و تصمیم گرفتم با پستی در همین رابطه این تجربه رو در اینجا به اشتراک بگذارم تا شاید روزی به درد کسی بخوره.

فرض کنید که نیاز داشته باشید مثلا با PHP از روی یک دیتابیس اوراکل ستونی از نوع CLOB یا همون Character Large Object رو در کنار سایر ستونها فراخوانی کرده و در یک صفجه نمایش بدید. چیزی مثل نمونه کد PLSQL زیر که در اون سعی داریم پنچ ستون رو از دیتابیس بازیابی کنیم که ستون آخر اون از نوع CLOB هست:

 

 

clob

 

محتوای ستون آخر که از نوع CLOB هست چیزی شبیه به تصویر زیر هست. یعنی یک Object که کلی دیتا داخل اون insert شده:

 

clob4

حالا اگر قصد داشته باشید از محتوای این ستون CLOB قسمت‌هاییش رو بیرون بکشید و بر اساس اون شرط های مختلفی بنویسید و در نهایت مثلا به کمک OCI در PHP از روی دیتابیس اوراکل اون رو بازیابی کنید و در یک صفحه وب نمایش بدید، با مشکل مواجه میشید و پیام خطای زیر رو دریافت میکنید که بهتون میگه این ستون Object هست.

نمونه ای از کد PHP برای بازیابی اطلاعات از دیتابیس اوراکل با OCI و پیغام خطایی که با اجرا کردنش مواجه میشیم رو در زیر میبینید:

و پیعام خطا پس از اجرای کد:

اگر هم بخواید با print_r() دیتاتایپ CLOB رو بخونید با این پیغام خطا مواجه میشید:

که به این خاطر است که بجای محتوای CLOB یک Object به شما برگردونده میشه.

روش‌هایی وجود داره برای اینکه مثلا با PHP بشه این نوع دیتا تایپ رو هندل کرد. مثلا یکی از راه‌ها استفاده از متد load() or read()  به شکل قطعه کد زیر هست ولی در مواردی مثل null بودن یک row این روشها درست نخواهند کرد.

هندل کردن این نوع دیتا تایپ در این سطح کمی پیچیده‌ست. پس من ترجیح میدم بجای هندل کردنش با زبان برنامه نویسی و سروکله زدن با محدودیت های هر کدومش، اون رو در سطخ PLSQL هندل کنم تا بتونم بعدا از اون در هر زبان دیگری استفاده کنم. پس با کمی صبر و حوصله تغییرات مورد نیاز رو در سطح کد PLSQL پیاده سازی میکنم.

برای این کار میتونیم در کد PLSQL تابعی بنویسیم که بتونه محتوای CLOB رو برای ما تبدیل به نوع VARCHAR کنه. پس به جای اینکه به این صورت ستون CLOB رو فراخوانی کنم:

 

clob2

 

اون رو با استفاده از تابع CAST اوراکل تبدیل به VARCHAR میکنیم. چیزی شبیه به این:

 

clob5

 

حالا همونطور که در تصویر بالا میبینید دیتای CLOB داخل این ستون به نوع VARCHAR تبدیل شده و قابل نمایش میشه. حالا کافیه قسمت دلخواه رو با کمی دستکاری در کد PLSQL بیرون کشیده و بر اساس اون شروط دلخواهمون رو بنویسیم.

تصویر اول رو یادتونه؟ حالا من با کمی دستکاری PLSQL به چیزی شبیه به این رسیدم که در ستون سوم همه ردیفها قابل خوندن هستن:

 

clob6

 

حالا کافیه از این کوئری در لابلای کد PHP خودم استفاده کنیم و مثل یک استرینگ این مقدار رو هم داخل یک آرایه بریزیم و در نهایت به درستی اون رو در یک صفحه نمایش بدیم. به همین راحتی 🙂

راستی شما راه دیگری برای هندل کردن این نوع دیتاتایپ که قبلا امتحانش کردید و درست هم کار میکنه سراغ دارید؟ ممنون میشم اگر در قسمت نظرات تجربیاتتون رو به اشتراک بگذارین 🙂

چطور روی دبیان جسی بوت سیستم sysvinit داشته باشیم؟

نویسنده:
۵ آذر ۹۳

پس از مدت‌ها بحث در لیست پستی دبیان از اکتبر ۲۰۱۳ تا فوریه ۲۰۱۴، تصمیم کمیته فنی بر این شد که در انتشار نسخه پایدار بعدی دبیان یعنی دبیان ۸ با نام جسی، به بوت سیستم جدید systemd مهاجرت کنند. دبیان شاخه تستینگ (jessie در حال حاضر تا زمان انتشار نسخه پایدار) هم دیگر از sysvinit بعنوان بوت سیستم پیشفرض استفاده نمیکند. هر کدام از این بوت سیستم‌ها هم موافقان و مخالفان خاص خودش رو داره. بعضی‌ها از اون استقبال میکنن و بعضی‌ها هم به علت اینکه systemd پیچیدگی‌های زیادی رو ایجاد میکنه و این پیچیدگی برخلاف فلسفه یونیکس یعنی سادگی است (Keep it simple, stupid) با اون مخالفت میکنن. عده‌ای هم که از طرفداران فلسفه “یک کار را انجام بده ولی درست انجامش بده” هستن، با systemd از در مخالفت وارد شدن.

حالا سوالی که برای طرفداران sysvinit ممکنه مطرح باشه اینه که آیا راهی وجود داره که بتونیم همچنان از بوت سیستم قدیمی sysvinit روی دبیان جسی استفاده کنیم یا نه؟

systemd
جواب بله هست. این کار بسیار هم راحته. اگر در حال حاضر از دبیان ۷ (Wheezy) استفاده میکنید و میخواهید به جسی آپگرید کنید ولی sysvinit رو به عنوان بوت سیستم همچنان حفظ کنید، میتونید یک فایل با محتوای زیر در مسیر /etc/apt/preferences.d/use-sysvinit ایجاد کنید.

 این فایل به پکیج منیجر apt یا aptitude میگه که نصب systemd-sysv رو بعنوان بخشی از فرآیند نصب و آپگرید نادیده بگیره و از پیشفرض شدن systemd بعنوان boot system جلوگیری میکنه. در نتیجه شما یک سیستم آپگرید شده به جسی خواهید داشت که همچنان از sysvinit استفاده خواهد کرد.
اما اگر دبیان جسی را برای بار اول نصب کرده‌اید راهی برای اینکه sysviniit رو به عنوان پیشفرض دریافت و نصب کنید ندارید (debootstrap که بوسیله نصاب دبیان استفاده میشه همچین آپشنی نداره) اما میشه به اینستالر گفت که قبل از اولین بوت به sysvinit سوئیچ کنه.
روش اول: با استفاده از یک آرگومان خط فرمان کرنل به نصاب بگیم:

و روش دوم با فرمان زیر:

 روش اول بعد از نخستین بوت و با نصب بسته sysvinit-core نیز میتونه استفاده بشه. پیشنهاد میشه که اگر واقعا به sysvinit نیاز دارید و با systemd کنار نمیاید اون رو نگه دارید. در غیر این صورت خودتون رو آماده مهاجرت به systemd کنید و با کمی انعطاف پذیری باهاش کنار بیاید.

systemd

ترمینال Guake با دو مانیتور

نویسنده:
۱۶ آبان ۹۳

از بین ترمینال امولاتورهایی پایین افتادنی یا Drop-down Terminal Emulatorها (که از بالای صفحه به پایین باز میشه)، من guake رو به بقیه ترجیح میدم و باهاش راحت‌ترم. البته Tilda رو هم دوست دارم ولی Yakuake رو بخاطر ظاهرش نمی‌پسندم. اما قضیه از اینجا شروع شد که من تصمیم گرفتم دوال مانیتور کنم به این صورت که یک مانیتور بزرگ دیگه به لپ‌تاپم وصل کنم. همه چیز به خوبی انجام شد و فقط ترمینال guake بود که با وجود primary output کردن مانیتور جانبی همچنان اصرار داشت که روی ال‌سی‌دی لپ‌تاپ اجرا بشه. وقتی درباره این مشکل در اینترنت جستجو کردم پست‌های زیادی پیدا کردم که خیلی کار رو پیچیده کرده بودن مثلا اینکه برو guake رو دوباره به این شکل کامپایل کن و یکسری جفنگیات دیگه. خودم دست به کار شدم و رفتم سراغ تنظیمات guake. از قضا این ترمینال امولاتور با پایتون هم نوشته شده و قسمت‌هاییش هم با C. با سر و کله زدن‌های زیاد و سعی و خطا بالاخره با طی کردن قدم‌های زیر این مشکل رو حل کردم.

guake terminal emulator

و اما مراحل انجام کار:

۱-با ادیتور دلخواه خودتون فایل تنطیمات guake رو که در مسیر زیر قرار داره باز کنید(حتما با روت):

۲-  عبارت Find the function “get_final_window_rect(self)” رو جستجو و پیدا کنید(خط اول در پایین):

۳- عبارت “screen.get_monitor_geomentry(0)“ رو که پارامتری است برای پیدا کردن رزولوشن native مانیتور ۰ یعنی جایی که ترمینال guake در اون اجرا میشه رو جستجو و پیدا کنید. شما باید این مقدار را به تعداد مانیتورهایی که دارید تغییر دهید. اگر دو مانیتور دارید باید بجای ۰ اون رو به ۱ تغییر بدید و اگر ۳ مانیتور دارید باید این مقدار رو ۲ تنظیم کنید و … . من چون ۲ مانیتور داشتم، این مقدار رو از ۰ به ۱ تغییر دادم.

۴- پارامتر “window_rect.y = 0″ رو هم جستجو و پیدا کنید. این پارامتر رو باید به این شکل اصلاح کنید:

  • کلمه y را بهx تغییر دهید.
  • بجای مقدار ۰ باید جمع رزولوشن‌های مانیتورها رو بنویسید. یعنی اگر از دو مانیتور استفاده میکنید باید رزولوشن مانیتور اول رو با رزولوشن مانیتور دوم جمع بزنید و حاصل رو بجای ۰ برای این این پارامتر تنظیم کنید. مثلا من یک مانیتور با زرولوشن ۱۹۲۰×۱۰۸۰ داشتم و رزولوشن ال‌سی‌دی لپ‌تاپ هم ۱۳۶۶×۷۶۸ بود. جمع دو مقدار اول یعنی ۱۳۶۶+۱۹۲۰ که مساوی با ۳۲۸۶ میشه رو بجای ۰ در پارامتر بالا ست کردم.

۵- تغییرات رو ذخیره کنید و خارج شوید. کافیه یکبار guake رو کاملا ببندید و دوباره اجرا کنید. guake به خوبی و خوشی در مانیتور دوم اجرا میشه. (:

من در خونه و محل کار از دو مانیتوری که رزولوشن‌های اون باهم فرق دارن استفاده میکنم. پس بهتره یک اسکریپت کوچک بنویسم تا بتونه مقدار رزولوشن مانیتوری که الان وصل شده رو پیدا کنه و بعد مقدار مناسب رو در پارامتری که در قدم ۴ گفته شده تنظیم کنه تا من مجبور نباشم هر بار بصورت دستی این مقدار رو تنظیم کنم و بجاش میتونم به کارهای دیگه‌ام برسم. هنوز این کار رو نکردم ولی وقتی اسکریپت آماده شد، اینجا لینکش میکنم.