زمان اجرای راینو از تاریخ ۳۱ ژانویه ۲۰۲۶ یا بعد از آن غیرفعال میشود. اگر اسکریپتی دارید که از زمان اجرای راینو استفاده میکند، باید اسکریپت را به V8 منتقل کنید.
اغلب تنها پیشنیاز برای افزودن سینتکس و ویژگیهای V8 به یک اسکریپت، فعال کردن زمان اجرای V8 است. با این حال، مجموعهای کوچک از ناسازگاریها و تفاوتهای دیگر وجود دارد که میتواند منجر به عدم موفقیت یا رفتار غیرمنتظره اسکریپت در زمان اجرای V8 شود. هنگام مهاجرت یک اسکریپت برای استفاده از V8، باید پروژه اسکریپت را برای یافتن این مشکلات جستجو کرده و هر موردی را که یافتید، اصلاح کنید.
رویه مهاجرت V8
برای مهاجرت یک اسکریپت به V8، این روش را دنبال کنید:
- زمان اجرای V8 را برای اسکریپت فعال کنید .
runtimeVersionمیتوان با استفاده از مانیفست برای پروژه Apps Script بررسی کرد. - ناسازگاریهای زیر را با دقت بررسی کنید. اسکریپت خود را بررسی کنید تا مشخص شود که آیا ناسازگاریهایی وجود دارد یا خیر؛ اگر یک یا چند ناسازگاری وجود دارد، کد اسکریپت خود را تنظیم کنید تا مشکل را حذف یا از آن جلوگیری کنید.
- تفاوتهای دیگر زیر را با دقت بررسی کنید. اسکریپت خود را بررسی کنید تا مشخص شود که آیا هر یک از تفاوتهای ذکر شده بر رفتار کد شما تأثیر میگذارد یا خیر. اسکریپت خود را برای اصلاح رفتار تنظیم کنید.
- پس از اینکه هرگونه ناسازگاری یا تفاوتهای کشفشده را اصلاح کردید، میتوانید بهروزرسانی کد خود را برای استفاده از سینتکس V8 و سایر ویژگیها آغاز کنید.
- پس از اتمام تنظیمات کد، اسکریپت خود را کاملاً آزمایش کنید تا مطمئن شوید که مطابق انتظار عمل میکند.
- اگر اسکریپت شما یک برنامه وب یا افزونه منتشر شده است، باید نسخه جدیدی از اسکریپت را با تنظیمات V8 ایجاد کنید و استقرار را به نسخه تازه ایجاد شده هدایت کنید. برای اینکه نسخه V8 در دسترس کاربران قرار گیرد، باید اسکریپت را با این نسخه دوباره منتشر کنید.
- اگر اسکریپت شما به عنوان یک کتابخانه استفاده میشود، یک نسخه جدید از اسکریپت خود ایجاد کنید. این نسخه جدید را به تمام اسکریپتها و کاربرانی که از کتابخانه شما استفاده میکنند، اطلاع دهید و به آنها دستور دهید که به نسخه V8 ارتقا یابند. تأیید کنید که نسخههای قدیمیتر مبتنی بر راینو کتابخانه شما دیگر فعال یا قابل دسترسی نیستند.
- تأیید کنید که هیچ نمونهای از اسکریپت شما هنوز روی محیط اجرایی قدیمی راینو (Rhino) اجرا نمیشود. تأیید کنید که تمام پیادهسازیها با نسخهای که روی V8 است مرتبط هستند. پیادهسازیهای قدیمی را بایگانی کنید. تمام نسخهها را بررسی کنید و نسخههایی را که از محیط اجرایی V8 استفاده نمیکنند، حذف کنید.
ناسازگاریها
متأسفانه، محیط اجرای اصلی Apps Script مبتنی بر Rhino، چندین رفتار غیراستاندارد ECMAScript را مجاز میدانست. از آنجایی که V8 با استانداردها سازگار است، این رفتارها پس از مهاجرت پشتیبانی نمیشوند. عدم اصلاح این مشکلات منجر به خطا یا اختلال در رفتار اسکریپت پس از فعال شدن محیط اجرای V8 میشود.
بخشهای بعدی هر یک از این رفتارها و مراحلی را که باید برای اصلاح کد اسکریپت خود در حین مهاجرت به V8 انجام دهید، شرح میدهند.
for each(variable in object) اجتناب کنید
عبارت for each (variable in object) به جاوا اسکریپت ۱.۶ اضافه شد و به نفع for...of حذف شد.
هنگام مهاجرت اسکریپت خود به V8، از استفاده از دستور for each (variable in object) خودداری کنید .
در عوض، از for (variable in object) استفاده کنید:
// Rhino runtime var obj = {a: 1, b: 2, c: 3}; // Don't use 'for each' in V8 for each (var value in obj) { Logger.log("value = %s", value); } | // V8 runtime var obj = {a: 1, b: 2, c: 3}; for (var key in obj) { // OK in V8 var value = obj[key]; Logger.log("value = %s", value); } |
از Date.prototype.getYear() اجتناب کنید.
در زمان اجرای اصلی Rhino، Date.prototype.getYear() برای سالهای بین ۱۹۰۰ تا ۱۹۹۹، سالهای دو رقمی و برای سایر تاریخها، سالهای چهار رقمی را برمیگرداند، که این رفتار در جاوا اسکریپت ۱.۲ و قبل از آن وجود داشت.
در زمان اجرای V8، Date.prototype.getYear() سال منهای ۱۹۰۰ را برمیگرداند، همانطور که توسط استانداردهای ECMAScript الزامی است.
هنگام مهاجرت اسکریپت خود به V8، همیشه از Date.prototype.getFullYear() استفاده کنید که صرف نظر از تاریخ، یک سال چهار رقمی را برمیگرداند.
از استفاده از کلمات کلیدی رزرو شده به عنوان نام خودداری کنید
ECMAScript استفاده از برخی کلمات کلیدی رزرو شده را در نام توابع و متغیرها ممنوع میکند. محیط اجرایی Rhino بسیاری از این کلمات را مجاز میدانست، بنابراین اگر کد شما از آنها استفاده میکند، باید نام توابع یا متغیرهای خود را تغییر دهید.
هنگام مهاجرت اسکریپت خود به V8، از نامگذاری متغیرها یا توابع با استفاده از یکی از کلمات کلیدی رزرو شده خودداری کنید . نام هر متغیر یا تابعی را تغییر دهید تا از استفاده از کلمه کلیدی name خودداری کنید. کاربردهای رایج کلمات کلیدی به عنوان نام، class ، import و export هستند.
از اختصاص مجدد متغیرهای const خودداری کنید
در محیط اجرای اصلی راینو، شما میتوانستید یک متغیر را با استفاده از const تعریف کنید، به این معنی که مقدار نماد هرگز تغییر نمیکند و انتسابهای بعدی به نماد نادیده گرفته میشوند.
در محیط اجرای جدید V8، کلمه کلیدی const مطابق با استاندارد است و اختصاص دادن به متغیری که به صورت const تعریف شده است، منجر به خطای TypeError: Assignment to constant variable runtime میشود.
هنگام مهاجرت اسکریپت خود به V8، سعی نکنید مقدار یک متغیر const را دوباره اختصاص دهید :
// Rhino runtime const x = 1; x = 2; // No error console.log(x); // Outputs 1 | // V8 runtime const x = 1; x = 2; // Throws TypeError console.log(x); // Never executed |
از استفاده از حروف XML و شیء XML خودداری کنید
این افزونهی غیراستاندارد برای ECMAScript به پروژههای Apps Script اجازه میدهد تا مستقیماً از سینتکس XML استفاده کنند.
هنگام مهاجرت اسکریپت خود به V8، از استفاده مستقیم از عبارات XML یا شیء XML خودداری کنید .
در عوض، از XmlService برای تجزیه XML استفاده کنید:
// V8 runtime var incompatibleXml1 = <container><item/></container>; // Don't use var incompatibleXml2 = new XML('<container><item/></container>'); // Don't use var xml3 = XmlService.parse('<container><item/></container>'); // OK |
با استفاده از __iterator__ توابع تکرارکننده سفارشی نسازید.
جاوا اسکریپت ۱.۷ قابلیتی را اضافه کرد که با تعریف یک تابع __iterator__ در نمونه اولیه آن کلاس، امکان اضافه کردن یک تکرارکننده سفارشی به هر کلاسی را فراهم میکرد؛ این قابلیت همچنین به عنوان یک قابلیت کمکی برای توسعهدهندگان، به محیط زمان اجرای Rhino در Apps Script اضافه شد. با این حال، این قابلیت هرگز بخشی از استاندارد ECMA-262 نبود و در موتورهای جاوا اسکریپت سازگار با ECMAScript حذف شد. اسکریپتهایی که از V8 استفاده میکنند، نمیتوانند از این ساختار تکرارکننده استفاده کنند.
هنگام مهاجرت اسکریپت خود به V8، از تابع __iterator__ برای ساخت تکرارکنندههای سفارشی خودداری کنید . در عوض، از تکرارکنندههای ECMAScript 6 استفاده کنید.
ساختار آرایه زیر را در نظر بگیرید:
// Create a sample array var myArray = ['a', 'b', 'c']; // Add a property to the array myArray.foo = 'bar'; // The default behavior for an array is to return keys of all properties, // including 'foo'. Logger.log("Normal for...in loop:"); for (var item in myArray) { Logger.log(item); // Logs 0, 1, 2, foo } // To only log the array values with `for..in`, a custom iterator can be used. |
نمونههای کد زیر نشان میدهند که چگونه میتوان یک تکرارکننده (iterator) را در زمان اجرای Rhino ساخت، و چگونه میتوان یک تکرارکننده جایگزین را در زمان اجرای V8 ساخت:
// Rhino runtime custom iterator function ArrayIterator(array) { this.array = array; this.currentIndex = 0; } ArrayIterator.prototype.next = function() { if (this.currentIndex >= this.array.length) { throw StopIteration; } return "[" + this.currentIndex + "]=" + this.array[this.currentIndex++]; }; // Direct myArray to use the custom iterator myArray.__iterator__ = function() { return new ArrayIterator(this); } Logger.log("With custom Rhino iterator:"); for (var item in myArray) { // Logs [0]=a, [1]=b, [2]=c Logger.log(item); } | // V8 runtime (ECMAScript 6) custom iterator myArray[Symbol.iterator] = function() { var currentIndex = 0; var array = this; return { next: function() { if (currentIndex < array.length) { return { value: "[${currentIndex}]=" + array[currentIndex++], done: false}; } else { return {done: true}; } } }; } Logger.log("With V8 custom iterator:"); // Must use for...of since // for...in doesn't expect an iterable. for (var item of myArray) { // Logs [0]=a, [1]=b, [2]=c Logger.log(item); } |
از عبارات شرطی catch اجتناب کنید
محیط اجرای V8 از عبارات شرطی catch..if پشتیبانی نمیکند، زیرا با استانداردها سازگار نیستند.
هنگام مهاجرت اسکریپت خود به V8، هرگونه شرط catch را درون بدنه catch قرار دهید :
// Rhino runtime try { doSomething(); } catch (e if e instanceof TypeError) { // Don't use // Handle exception } | // V8 runtime try { doSomething(); } catch (e) { if (e instanceof TypeError) { // Handle exception } } |
از استفاده از Object.prototype.toSource() خودداری کنید
جاوا اسکریپت ۱.۳ شامل یک متد Object.prototype.toSource() بود که هرگز بخشی از هیچ استاندارد ECMAScript نبود. این متد در زمان اجرای V8 پشتیبانی نمیشود.
هنگام مهاجرت اسکریپت خود به V8، هرگونه استفاده از Object.prototype.toSource() را از کد خود حذف کنید .
تفاوتهای دیگر
علاوه بر ناسازگاریهای قبلی که میتوانند باعث خرابی اسکریپت شوند، چند تفاوت دیگر نیز وجود دارد که در صورت عدم اصلاح، ممکن است منجر به رفتار غیرمنتظره اسکریپت در زمان اجرای V8 شوند.
بخشهای بعدی نحوه بهروزرسانی کد اسکریپت شما را برای جلوگیری از این غافلگیریهای غیرمنتظره توضیح میدهند.
قالببندی تاریخ و زمان مختص هر منطقه را تنظیم کنید
متدهای Date toLocaleString() ، toLocaleDateString() و toLocaleTimeString() در زمان اجرای V8 در مقایسه با Rhino رفتار متفاوتی دارند.
در راینو، فرمت پیشفرض، فرمت طولانی (long format) است و هر پارامتری که ارسال شود، نادیده گرفته میشود.
در زمان اجرای V8، فرمت پیشفرض، فرمت کوتاه (short format) است و پارامترهای ارسالی مطابق با استاندارد ECMA مدیریت میشوند (برای جزئیات بیشتر به مستندات toLocaleDateString() مراجعه کنید).
هنگام مهاجرت اسکریپت خود به V8، انتظارات کد خود را در مورد خروجی متدهای تاریخ و زمان مختص به منطقه، آزمایش و تنظیم کنید :
// Rhino runtime var event = new Date( Date.UTC(2012, 11, 21, 12)); // Outputs "December 21, 2012" in Rhino console.log(event.toLocaleDateString()); // Also outputs "December 21, 2012", // ignoring the parameters passed in. console.log(event.toLocaleDateString( 'de-DE', { year: 'numeric', month: 'long', day: 'numeric' })); | // V8 runtime var event = new Date( Date.UTC(2012, 11, 21, 12)); // Outputs "12/21/2012" in V8 console.log(event.toLocaleDateString()); // Outputs "21. Dezember 2012" console.log(event.toLocaleDateString( 'de-DE', { year: 'numeric', month: 'long', day: 'numeric' })); |
از استفاده از Error.fileName و Error.lineNumber خودداری کنید
در زمان اجرای V8، شیء استاندارد Error جاوا اسکریپت fileName یا lineNumber به عنوان پارامترهای سازنده یا ویژگیهای شیء پشتیبانی نمیکند.
هنگام مهاجرت اسکریپت خود به V8، هرگونه وابستگی به Error.fileName و Error.lineNumber حذف کنید .
یک راه جایگزین استفاده از Error.prototype.stack است. این پشته نیز غیر استاندارد است، اما در V8 پشتیبانی میشود. قالب ردیابی پشته تولید شده توسط دو پلتفرم کمی متفاوت است:
// Rhino runtime Error.prototype.stack // stack trace format at filename:92 (innerFunction) at filename:97 (outerFunction) | // V8 runtime Error.prototype.stack // stack trace format Error: error message at innerFunction (filename:92:11) at outerFunction (filename:97:5) |
تنظیم نحوهی مدیریت اشیاء enum رشتهای
در زمان اجرای اصلی راینو، استفاده از متد JSON.stringify() جاوا اسکریپت روی یک شیء enum فقط {} را برمیگرداند.
در V8، استفاده از همین روش روی یک شیء enum، نام enum را دوباره تنظیم میکند.
هنگام مهاجرت اسکریپت خود به V8، انتظارات کد خود را در مورد خروجی JSON.stringify() روی اشیاء enum آزمایش و تنظیم کنید :
// Rhino runtime var enumName = JSON.stringify(Charts.ChartType.BUBBLE); // enumName evaluates to {} | // V8 runtime var enumName = JSON.stringify(Charts.ChartType.BUBBLE); // enumName evaluates to "BUBBLE" |
تنظیم نحوهی مدیریت پارامترهای تعریف نشده
در زمان اجرای اصلی Rhino، ارسال undefined به عنوان پارامتر به یک متد، منجر به ارسال رشته "undefined" به آن متد میشد.
در موتور V8، ارسال undefined به متدها معادل ارسال null است.
هنگام انتقال اسکریپت خود به V8، انتظارات کد خود را در مورد پارامترهای undefined آزمایش و تنظیم کنید :
// Rhino runtime SpreadsheetApp.getActiveRange() .setValue(undefined); // The active range now has the string // "undefined" as its value. | // V8 runtime SpreadsheetApp.getActiveRange() .setValue(undefined); // The active range now has no content, as // setValue(null) removes content from // ranges. |
تنظیم مدیریت سراسری this
زمان اجرای Rhino یک زمینه ویژه ضمنی برای اسکریپتهایی که از آن استفاده میکنند تعریف میکند. کد اسکریپت در این زمینه ضمنی اجرا میشود، متمایز از this سراسری واقعی. این بدان معناست که ارجاعات به " this سراسری" در کد در واقع به زمینه ویژه ارزیابی میشوند، که فقط شامل کد و متغیرهای تعریف شده در اسکریپت است. سرویسهای Apps Script داخلی و اشیاء ECMAScript از این استفاده از this مستثنی هستند. این وضعیت مشابه این ساختار جاوا اسکریپت بود:
// Rhino runtime // Apps Script built-in services defined here, in the actual global context. var SpreadsheetApp = { openById: function() { ... } getActive: function() { ... } // etc. }; function() { // Implicit special context; all your code goes here. If the global this // is referenced in your code, it only contains elements from this context. // Any global variables you defined. var x = 42; // Your script functions. function myFunction() { ... } // End of your code. }(); |
در V8، زمینه ویژه ضمنی حذف شده است. متغیرها و توابع سراسری تعریف شده در اسکریپت، در زمینه سراسری، در کنار سرویسهای داخلی Apps Script و توابع داخلی ECMAScript مانند Math و Date قرار میگیرند.
هنگام مهاجرت اسکریپت خود به V8، انتظارات کد خود را در مورد استفاده از this در یک زمینه سراسری آزمایش و تنظیم کنید. در بیشتر موارد، تفاوتها فقط در صورتی آشکار میشوند که کد شما کلیدها یا نامهای ویژگی شیء سراسری this را بررسی کند:
// Rhino runtime var myGlobal = 5; function myFunction() { // Only logs [myFunction, myGlobal]; console.log(Object.keys(this)); // Only logs [myFunction, myGlobal]; console.log( Object.getOwnPropertyNames(this)); } | // V8 runtime var myGlobal = 5; function myFunction() { // Logs an array that includes the names // of Apps Script services // (CalendarApp, GmailApp, etc.) in // addition to myFunction and myGlobal. console.log(Object.keys(this)); // Logs an array that includes the same // values as above, and also includes // ECMAScript built-ins like Math, Date, // and Object. console.log( Object.getOwnPropertyNames(this)); } |
تنظیم نحوهی مدیریت instanceof در کتابخانهها
استفاده از instanceof در یک کتابخانه روی شیءای که به عنوان پارامتر در یک تابع از پروژه دیگری ارسال شده است، میتواند نتایج منفی کاذب (false negative) بدهد. در زمان اجرای V8، یک پروژه و کتابخانههای آن در زمینههای اجرایی مختلفی اجرا میشوند و از این رو زنجیرههای سراسری و نمونه اولیه متفاوتی دارند.
توجه داشته باشید که این مورد فقط در صورتی صدق میکند که کتابخانه شما instanceof روی شیءای که در پروژه شما ایجاد نشده است استفاده کند. استفاده از آن روی شیءای که در پروژه شما ایجاد شده است، چه در همان اسکریپت یا اسکریپت دیگری در پروژه شما، باید مطابق انتظار کار کند.
اگر پروژهای که روی V8 اجرا میشود از اسکریپت شما به عنوان کتابخانه استفاده میکند، بررسی کنید که آیا اسکریپت شما از instanceof روی پارامتری که از پروژه دیگری ارسال میشود استفاده میکند یا خیر. نحوه استفاده از instanceof را تنظیم کنید و از گزینههای ممکن دیگر مطابق با مورد استفاده خود استفاده کنید.
یک جایگزین برای a instanceof b میتواند استفاده از سازنده a در مواردی باشد که نیازی به جستجوی کل زنجیره نمونه اولیه ندارید و فقط سازنده را بررسی میکنید. کاربرد: a.constructor.name == "b"
پروژه A و پروژه B را در نظر بگیرید که در آن پروژه A از پروژه B به عنوان کتابخانه استفاده میکند.
//Rhino runtime //Project A function caller() { var date = new Date(); // Returns true return B.callee(date); } //Project B function callee(date) { // Returns true return(date instanceof Date); } | //V8 runtime //Project A function caller() { var date = new Date(); // Returns false return B.callee(date); } //Project B function callee(date) { // Incorrectly returns false return(date instanceof Date); // Consider using return (date.constructor.name == // “Date”) instead. // return (date.constructor.name == “Date”) -> Returns // true } |
یک جایگزین دیگر میتواند معرفی تابعی باشد که instanceof در پروژه اصلی بررسی کند و هنگام فراخوانی یک تابع کتابخانهای، این تابع را به همراه پارامترهای دیگر ارسال کند. سپس میتوان از تابع ارسالی برای بررسی instanceof در داخل کتابخانه استفاده کرد.
//V8 runtime //Project A function caller() { var date = new Date(); // Returns True return B.callee(date, date => date instanceof Date); } //Project B function callee(date, checkInstanceOf) { // Returns True return checkInstanceOf(date); } |
تنظیم انتقال منابع غیر اشتراکی به کتابخانهها
ارسال یک منبع غیراشتراکی از اسکریپت اصلی به یک کتابخانه در زمان اجرای V8 متفاوت عمل میکند.
در زمان اجرای راینو، ارسال یک منبع غیراشتراکی کار نمیکند. کتابخانه به جای آن از منبع خودش استفاده میکند.
در زمان اجرای V8، ارسال یک منبع غیراشتراکی به کتابخانه کار میکند. کتابخانه از منبع غیراشتراکی ارسالی استفاده میکند.
منابع غیر اشتراکی را به عنوان پارامترهای تابع ارسال نکنید. همیشه منابع غیر اشتراکی را در همان اسکریپتی که از آنها استفاده میکند، تعریف کنید.
پروژه A و پروژه B را در نظر بگیرید که در آن پروژه A از پروژه B به عنوان کتابخانه استفاده میکند. در این مثال، PropertiesService یک منبع غیر اشتراکی است.
// Rhino runtime // Project A function testPassingNonSharedProperties() { PropertiesService.getScriptProperties() .setProperty('project', 'Project-A'); B.setScriptProperties(); // Prints: Project-B Logger.log(B.getScriptProperties( PropertiesService, 'project')); } | // V8 runtime // Project A function testPassingNonSharedProperties() { PropertiesService.getScriptProperties() .setProperty('project', 'Project-A'); B.setScriptProperties(); // Prints: Project-A Logger.log(B.getScriptProperties( PropertiesService, 'project')); } |
توصیههای JDBC در زمان اجرای V8
با اجرای V8، ویژگیهای جدیدی به سرویس JDBC اضافه کردهایم.
استفاده از executeBatch برای عملیات دستهای
شما میتوانید از عملیات executeBatch(params) برای انجام عملیات پایگاه داده به صورت دستهای استفاده کنید.
مثال زیر نحوه درج چندین ردیف در پایگاه داده با استفاده از دسته بندی را نشان میدهد:
این هم محیط اجرای راینو (روش قدیمی):
var conn = Jdbc.getCloudSqlConnection("jdbc:google:mysql://..."); var stmt = conn.prepareStatement("INSERT INTO employees (name, age) VALUES (?, ?)"); var params = [["John Doe", 30], ["John Smith", 25]]; for (var i = 0; i < params.length; i++) { stmt.setString(1, params[i][0]); stmt.setInt(2, params[i][1]); stmt.execute(); }
زمان اجرای V8 (روش جدید) به این صورت است:
var conn = Jdbc.getCloudSqlConnection("jdbc:google:mysql://..."); var stmt = conn.prepareStatement("INSERT INTO employees (name, age) VALUES (?, ?)"); var params = [["John Doe", 30], ["John Smith", 25]]; stmt.executeBatch(params);
استفاده از getRows برای دریافت مجموعه نتایج
شما میتوانید از getRows(queryString) برای دریافت دادههای مجموعه نتایج در یک فراخوانی استفاده کنید. queryString شامل فراخوانیهای جدا شده با کاما به متدهای getter از JdbcResultSet است، برای مثال: "getString(1), getDouble('price'), getDate(3, 'UTC')" . متدهای پشتیبانی شده شامل تمام متدهای getter هستند که مسئول خواندن دادههای ستون هستند، برای مثال getHoldability ، getMetaData و غیره پشتیبانی نمیشوند. آرگومانها میتوانند اندیسهای ستون عدد صحیح (مبتنی بر 1) یا برچسبهای ستون رشتهای با علامت نقل قول تکی یا دوتایی باشند.
مثال زیر نحوهی دریافت ردیفها از مجموعه نتایج را نشان میدهد:
این هم محیط اجرای راینو (روش قدیمی):
var conn = Jdbc.getCloudSqlConnection("jdbc:google:mysql://..."); var stmt = conn.createStatement(); var rs = stmt.executeQuery("SELECT name, age FROM employees"); while (rs.next()) { Logger.log(rs.getString('name') + ", " + rs.getInt('age')); }
زمان اجرای V8 (روش جدید) به این صورت است:
var conn = Jdbc.getCloudSqlConnection("jdbc:google:mysql://..."); var stmt = conn.createStatement(); var rs = stmt.executeQuery("SELECT name, age FROM employees"); var rows = rs.getRows("getString('name'), getInt('age')"); for (var i = 0; i < rows.length; i++) { Logger.log(rows[i][0] + ", " + rows[i][1]); }
بهروزرسانی دسترسی به اسکریپتهای مستقل
برای اسکریپتهای مستقل که در زمان اجرای V8 اجرا میشوند، برای اینکه محرکهای اسکریپت به درستی کار کنند، باید حداقل دسترسی مشاهده اسکریپت را برای کاربران فراهم کنید.