Aklımda Kalası Kelimeler
21 Eylül 2016 Çarşamba
Elasticsearch ve Mapping
Şema kavramı ile Mapping arasında terminolojik olarak aynılığı yukarıdaki resimde gördünüz.
Tablo ile Tip arasındaki aynılıkta dikkatinizi çekmiştir.
O halde ilişkisel veritabanlarında bir tablonun şeması olduğunu yani içindeki kolonların hangi tiplerde veri aldığını belirttiğinizi hatırlarsanız, şema
Mapping nedir, nasıl belirtilir, nasıl yapılandırılır ve verimize nasıl uygulanır diye bakalım.
Şema, bir ya da daha fazla alanları olan belgenin tanımıdır. ES JSON tipinde verileri muhafaza ettiğinden dolayı, JSON verisinin içinde veri tipini bu verinin nasıl indekslenmesi gerektiğini "mapping" ile belirtiriz ki mapping ES dünyasında şema demektir.
ES içinde 0 ya da daha fazla index ve bu indexler 0 veya daha fazla document içerir. Bir başka deyişle; bir belgenin bir tipe ve bir index'e bağlı tanımlayıcısı vardır.
Yukarıdaki şekilde INDEX, TIP be DOKUMAN kutularını görüyorsunuz. A,B,X ve Y belgelerinin my_type adında bir tipi ve my_index adında bir indexi var. Aynı indeksi bir başka tip olan "another_type" ve bu tipi kullanan belgeler de kullanıyor. Yukarıdaki figürdeki TIP aslında
19 Temmuz 2016 Salı
ASP.NET 5 Üzerine
ASP.NET 5 ile birlikte gelen komut satırı araçlarıyla Visual Studio dışından cross-platform ASP.NET uygulamalarını basit bir metin editörüyle(notepad gibi) geliştirebilecek visual studio çalıştırmadan CMD ya da Poweshell(windows üstünde tabii) derleyebileceğiz. Bu komutlar ASP.NET 5 içinde
- DNX (.Net Execution Environment-.Net çalıştırma ortamı) .NET 5 uygulamalarının ihtiyaç duyacağı bileşenleri içeren, eski usül .net çatısı olup içinde birden fazla .net versiyonunu içerebilmesi sayesinde dll cehennemini yaşamamızı sağlar,
- DNVM(.Net Version Manager) ile hangi DNX sürümünü kullanacağımızı seçeriz,
- DNU (DNX klasöründe bulunan DNU kütüphanesi sayesinde .NET 5 uyugulamasının project.json içinde tanımlanmış ihtiyaç duyacağı paketlerin yönetilmesini -yükleme(installation) veya geri yükleme(restoring)- sağlar.),
1 Temmuz 2016 Cuma
Pair Programming üzerine
Diyelimki 4 takımın var ve elbette ikişer kişiden oluşuyor. Periyodik olarak takım üyelerinin yerlerini değiştirmek iyidir, candır.
30 Mayıs 2016 Pazartesi
19 Mart 2016 Cumartesi
npm ayarları
NPM SET INIT
NPM addUser
npm client için www.npmjs.com adresinde kayıtlı olan kullanıcı bilgilerinizi bir kerede girmeniz ve ileride gerekmemesi için gerekli ayarlar:.gitignore Dosyasıyla Yoksayılacaklar
git add -A
Tüm dosyaları (.gitignore içinde olmayan tüm dosyaları) repository'e gönderecek şekilde işaretler.git commit -m "mesajınız"
Yaptığınız değişiklikleri bir mesaj ile repoya gönderilecek şekilde işaretlergit push
Artık github'a gittiler git push ile.npm publish
github üstünde artık kodlarınız bulunuyor ancak npm install paket_adi ile indirilebilimesi için npmjs.com adresine publish edilmesi gerekiyor.git tag
Buraya kadar kodunuzu ilk kez git's yüklediniz ve npm paketinizi kayıt ettirdiniz. artıknpm install paketinizin_adi
diyerek kullandırabilirsiniz ama zaman içinde çeşitli sürümler yaparak hem eski sürümlerinize erişim hem de yenilerini kullanma imkanı sunmak istiyorsunuz. O halde git tag [versiyonNo]
ile sürekli sürüm yapabilirsiniz git üstünde. Tabi bunları npm tarafında da güncel tutmanız gerekecek ama önce git etiketlemesine bakalım:Artık github üstünde versiyonNo etiketli sürümünüzü görebilir buna bir başlık açabilir üstünden sorunları giderebilirsiniz.
Artık Yeni Sürüm
npm install
npm install paketAdi // son stabil paketi npm install paketAdi@beta // son beta sürümünü npm install paketAdi@versiyonNo // son beta sürümünü
npm version patch
Sadece package.json içindeki sürüm bilgisinin patch sayısını bir arttırıp package.json içindeki bilgiyi güncelleyecektir. Tabii bu işi git üstünden yaptığı için (git içindeki git-tag-version ile) git versiyonu da değişecektir. Bunu git üstünden yapmamak içinnpm --no-git-tag-version version -f
çalıştırmalısınız. npm version major|minor|patch
şeklinde çeşitlerini buradan bulabilirsin.npm scripts
Ref: http://blog.npmjs.org/post/118810260230/building-a-simple-command-line-tool-with-npmBir versiyon temel olarak major.minor.patch bölümlerinden oluşur.
Yamalamak için versiyonlama işi kısaca
npm version patch
ile olabilir ancak bu versiyonu npmjs.com adresine publish etmek içinde npm publish
demek gerekecektir. Bunu otomatik hale getirmek için aşağıdaki blok iş görecektir. npm run patch-release
ile tümünü tek bir kod ile yapabilirsiniz.#package.json { "name": "my-project", "version": "1.0.0", "scripts": { "patch-release": "npm version patch && npm publish && git push --follow-tags" } }
Daha karmaşık bir yapıyı parçalara bölerek oluşturup tek elden çalıştırbilirsiniz
npm run deploy
ile."scripts": { "build": "...", "git-commit": "git add -A . && git commit -a -m 'gh-pages update'", "git-push": "git push origin gh-pages --force && git checkout master", "deploy": "npm run build && npm run git-commit && npm run git-push" },
git config --global credential.helper wincred
Git hesabınızı windows komut satırında kullanırken defalarca kullanıcı adınızın sorulmasını istemezseniz komut satırına$ git config --global credential.helper wincredyazmanız halinde artık kullanıcı bilgilerinizi windows tutacaktır. Yapmanız gereken git depolarından bir kaynak kodunuzla ilgili güncelleme yaparken bir kez kullanıcı adı ve şifrenizi girmek olacaktır.
git config --list
ile ayarlarınıza baktığınızda credential.helper=wincred satırını göreceksiniz ve sonraki tüm git işlemlerinizi komut satırından yaparken size kullanıcı adı ve şifresi sormayacak. Windows credentials ile baktığınızda "Generic Credentials" kısmında github şifrenizin depolandığını göreceksiniz.
git config --list
cem.topkaya@CZC11141WZ C:\_Projeler\Cop\modules\kuark-istisna $ git config --list core.symlinks=false core.autocrlf=false color.diff=auto color.status=auto color.branch=auto color.interactive=true pack.packsizelimit=2g help.format=html http.sslcainfo=/bin/curl-ca-bundle.crt sendemail.smtpserver=/bin/msmtp.exe diff.astextplain.textconv=astextplain rebase.autosquash=true user.name=cemtopkaya user.email=cem.topkaya@hotmail.com gui.recentrepo=C:/Users/cem.topkaya/Documents/Visual Studio 2013/Projects/ConsoleApplication8/CSharp_Orneklerim_Git credential.helper=wincred http.postbuffer=524288000 core.repositoryformatversion=0 core.filemode=false core.bare=false core.logallrefupdates=true core.symlinks=false core.ignorecase=true core.hidedotfiles=dotGitOnly remote.origin.url=https://github.com/cemtopkaya/repo-adi.git remote.origin.fetch=+refs/heads/*:refs/remotes/origin/* cem.topkaya@CZC11141WZ C:\_Projeler\Cop\modules\kuark-istisna
git config --global push.default matching
Daha sade bir çıktı almak istersek kullanacağız. Yani, normalde$ git push
aşağıdaki çıtıyı veriyorken:$ git config --global push.default matchingKomutunu çalıştırarak sadece şu çıktıyı alıyoruz:
Bu çıktıyı şu config listelerindeki değişimlerde görelim:
20 Ocak 2016 Çarşamba
Linq ile GroupBy ve Sum örneği
using System; using System.Collections.Generic; using System.Linq; namespace ConsoleApplication6 { class Tax { public int Orani; public int Amount; public int ReasonCode; public string Reason; public override string ToString() { return string.Format("Oranı:{0}, Amount:{1}, ReasonCode:{2}, Reason:{3}", Orani,Amount,ReasonCode,Reason); } } class Program { static void Main(string[] args) { ListÇıktısı:lst = new List () { new Tax(){Amount = 10, Orani = 18}, new Tax(){Amount = 5, Orani = 18}, new Tax(){Amount = 0, Orani = 0, Reason = "351", ReasonCode = 351}, new Tax(){Amount = 0, Orani = 0, Reason = "251", ReasonCode = 251}, new Tax(){Amount = 6, Orani = 8}, new Tax(){Amount = 16, Orani = 8}, }; // Sum Amount var total = (from l in lst select l.Amount).Sum(); Console.WriteLine("Toplam Vergi: "+total); // GroupBy var a = from l in lst group l by l.Orani into g orderby g.Key select g; foreach (IGrouping g in a) { Console.WriteLine(g.Key); foreach (Tax tax in g) { Console.WriteLine(tax); } } } } }
7 Ocak 2016 Perşembe
Dosyayı, sunucudaki adından farklı kaydetmek
Ders 10 - Bir oda rezervasyonu yaptırmak istiyorum.mp3
istiyoruz.
Eğer a etiketi içinde href özelliği bir adresi değilde doğrudan dosyayı içeriyor olsaydı kaydetmek için istediğimiz dosya adını download özelliğine yazmamız ve tıklamamız yeterliydi.
<a download="logo.png" href="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">Download transparent png</a>
RSS içindeki bilgileri çekmek için XPath kullanabilirsiniz. Bunu da Chrome browser ile yapabilirsiniz. Güzel bir anlatım için aşağıdaki resimlere bakabilirsiniz:
Kaynak: http://yizeng.me/2014/03/23/evaluate-and-validate-xpath-css-selectors-in-chrome-developer-tools/
Bizim a etiketlerimiz şöyle olacak:
<a href='http://radio-download.dw.de/Events/podcasts/tur/3803_DKpodcast_dwn1_tur/DWN_Tuerkisch_Serie1_Lektion01-podcast-3803-293588.mp3' data-saveas='Ders 01 - Bu bir şarkı.mp3'>Ders 01 - Bu bir şarkı</a>data-saveas içinde yeni dosya adı, href içinde ise sunucudaki dosyanın adresini tutacağız. Haydi başlayalım ! Aşağıdaki kodu Chrom'un Console sekmesinde çalıştırdığınızda xpath ile sogulamalar için hızlı ve manipule edebileceğiniz bir fonksiyonu yüklemiş olursunuz.
var xpath = function(xpathToExecute){ var result = []; var nodesSnapshot = document.evaluate(xpathToExecute, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null ); for ( var i=0 ; i < nodesSnapshot.snapshotLength; i++ ){ result.push( nodesSnapshot.snapshotItem(i) ); } return result; }Bu kod ile indirilecek a etiketlerini oluşturalım
var aDizi = [], arrTitle= xpath("//item/title/text()"), // Tüm title içindekilerini alalım. Bunlar bizim mp3 dosyamızı kaydederken kullanacağımız dosya adlarımız olacak arrUrl=xpath("//item/enclosure/@url/text()");// Tüm mp3 dosyalarının URL adreslerini alalım. Önce stream olarak alıp blob olarak saklayacak ve tıkladığımız a etiketlerinden diskimize kaydedeceğimiz akışlar arrTitle.forEach(function(_title, _idx){ console.log(_idx) console.log(arrUrl[_idx]) aDizi.push("<a href='"+arrUrl[_idx].value+"'>"+_title+"</a>"); }) console.log(aDizi); // Ekranda görelimki listeyi kopyalayıp html dosyamıza yapıştırarak indireceğizjQuery candır. Onu sayfamıza bir ekleyelim.
<html> <head> <script src=http://code.jquery.com/jquery-2.1.4.min.js></script>Sayfamızda data-saveas propertysi olan a etiketlerinin üstünden geçerek href özelliklerindeki adresten akışı indireceğiz ve Blob'a yazarak tekrar a etiketine bağlayacağız.
<script type=text/javascript> $(function() { // iterate over all the items that are marked as saveas $('a[data-saveas]').each(function() { var $this = $(this); // İndirmek istediğimiz adres ve diske hangi isimle kaydetmek istiyorsak, yeni dosya adı var target = $this.prop('href'), saveas = $this.data('saveas'); // kaynaktan dosyayı indirmek için ajax kullanacağız $.ajax({ url: target, type: 'GET', mimeType: 'text/plain; charset=x-user-defined', error: function(a, b, c, d) { debugger; } }).done(function(data, textStatus, jqXHR) { // VERİYİ ÇEKTİK VE ŞİMDİ BLOB OLARAK SAKLAYACAĞIZ var bufferBos = new Int8Array(new ArrayBuffer(data.length)); for (var i = 0; i < data.length; i++) { var charCode = data.charCodeAt(i); // ascii bufferBos[i] = charCode; // gelen her byte'ı 8 bitlik(octet) elemanlar olarak diziye yerleştirelim } // Blob oluşturmak yapıcı olarak veriyi ve verinin tipini vermemiz gerekiyor // new Blob([bufferlanmış veri], { type: mimeString }) var mimeString = jqXHR.getResponseHeader('Content-Type'); var blob = new Blob([bufferBos], { type: mimeString }); // ŞİMDİ DEFAULT HREF BİLGİLERİNE GÖRE KAYDETMEMEK İÇİN DÜZENLEYELİM // Blob içine kaydettiğimiz veriye erişebilmek için URL oluşturacağız. var href = (window.webkitURL || window.URL).createObjectURL(blob); $this.prop({ // Tıklandığında download propertysinden yer alan ad ile kaydedecek 'download': saveas, 'href': href, 'draggable': true }).data({ // <a href="#" class="dnd" data-downloadurl="MIME_Type:File_Name:Blob_URL"></a> // Örneğin: // <a href="#" class="dnd" data-downloadurl="image/jpeg:Penguins.jpg:https://www.box.net/box_download_file?file_id=f66690"></a> 'downloadurl': [mimeString, saveas, href].join(':') }); }); }); }); </script> </head>HTML dosyamıza bağlantılarımızı da ekleyerek tamamlayalım. Sayfa yüklendiğinde tüm a elemanlarının içinde dolaşarak ilgili dosyaları blob halinde browser'da tutacak ve tıkladığımızda belirttiğimiz dosya adıyla kaydetmiş olacağız.
<body> 0: <a href='http://radio-download.dw.de/Events/podcasts/tur/3803_DKpodcast_dwn1_tur/DWN_Tuerkisch_Serie1_Lektion01-podcast-3803-293588.mp3' data-saveas='Ders 01 - Bu bir şarkı.mp3'>Ders 01 - Bu bir şarkı</a> <br />1: <a href='http://radio-download.dw.de/Events/podcasts/tur/3806_DKpodcast_dwn3_tur/00eb5664-podcast-3806-306737.mp3' data-saveas='Ders 26 - Yalnızca birlikte olmak istiyoruz.mp3'>Ders 26 - Yalnızca birlikte olmak istiyoruz</a> <br />2: <a href='http://radio-download.dw.de/Events/podcasts/tur/3806_DKpodcast_dwn3_tur/00eb5675-podcast-3806-306736.mp3' data-saveas='Ders 25 - Önce ufak siparişler gelmesini umuyorum.mp3'>Ders 25 - Önce ufak siparişler gelmesini umuyorum</a> .. ... .... </body> </html>Haydi sonucuna bakalım. Önce dosyanın indiğini chrome network sekmesinden görelim: Şimdide tıkladığımızda ne olduğuna: Hepsi bu :)
3 Ocak 2016 Pazar
Dipkazimi
İnsanın tarım yoluyla ürün elde etme çabası başladığından buyana insanoğlu, elde ettiklerini nitelik ve nicelik yönünden daha artırmak, ucuzlatmak ve kolaylaştırmak için çabalar harcamıştır. Tarımda alet- makinalı hizmetin başladığı 18. yy. dan günümüze kadar büyük ve hızlı bir gelişme olduğu görülmüştür. Günümüzde tarım, alet ve makinasız yapılamayacak bir düzeye ulaştırılmıştır.
Ülkeler, birim alandan en fazla verim alabilmek amacıyla tekniğin bütün imkanlarından faydalanmak için büyük çaba sarfetmektedirler. Ürün artışının faydalanmasında, uygun toprak işlemenin ve iyi bir tohum yatağı hazırlanmasının rolü büyüktür. Ancak bu şartları sağlamak için tarlaya sokulan her türlü toprak işleme aleti toprağın fiziksel yapısının bozulmasına neden olmakta ve bu aletlerin aynı derinlikleri işlemesi sonucunda da, toprak profilinin bu derinliğinde pulluk tabanı denilen sert bir tabaka oluşmaktadır. Bu sert tabakanın oluşmasına sadce sürüm aletleri neden olmamaktadır. Topraktaki bazı mineraller ve oluşumlar da sert tabakanın oluşmasına neden olmaktadır. Makinaların kullanılmasıyla sert tabakanın oluşmasında toprak nemi çok önemli bir faktördür. Ağır tavda yapılan sürümler bu tabakanın daha çabuk oluşmasına neden olmaktadır. Bu tabaka sert olduğu için toprağa giren suyu pulluk tabakasının altına geçirmez. Bitki köklerinin derinlere ulaşmasını önler. Bu yüzden bu tabakanın belirli aralıklarla kırılması, kabartılması gerekir. Bu amaç için de dipkazan aletleri kullanılır.
Toprakların traktörle işlenmesi sonucu oluşan sert tabaka, genellikle 20-25 cm. derinlikte bulunmakta, bu tabakanın kalınlığı da 6-18 cm arasında değişmektedir. Ağır bünyeli topraklarda sert tabaka toprak yüzeyinden daha derinde (yaklaşık olarak 35-40 cm) teşekkül eder. Ancak orta ve hafif bünyeli topraklarda sert tabaka oluşumu, ağır bünyeli topraklara oranla daha çabuk ve daha sert olmaktadır.
Sert tabaka oluşmasının zararları
Sert tabaka oluşması toprağın gözenekliliğini azaltır. Toprak sıkıştığından bitki köklerinin gelişmesi için ihtiyaç duyulan oksijen miktarı azalır. Kökler iyi gelişemez.
Sert tabaka toprağın geçirgenliğini azaltır. Yağmur, sulama suyu şeklinde toprağa giren sular sert tabakadan geçemez, bunun sonucu olarak toprak derinliğine işleyemez. Dolayısıyla toprakta yeterince su depolanamayacağından bitkiler kurak dönemlerde ihtiyaç duydukları suyu toprakta bulamayacaklar ve sonuçta verim düşüşü kaçınılmaz olacaktır.
Bitki kökleri sert tabakayı geçemeyecekleri için yukarı veya yana doğru kıvrılarak topraktaki bitki besin maddelerinden ve mevcut toprak suyundan yeterince yararlanamayacaklardır. Tüm bunların sonucunda verimde bitki çeşidine bağlı olarak %25- 30 oranında azalma olacaktır.
Sert tabaka hangi aletlerle kırılmalıdır?
Toprakta genellikle pulluk sürümü derinliğinde oluşan sert tabakanın kırılması, yani patlatılması gerekir. Bunun için en uygun zaman da toprağın hangi derinlikte oluştuğunu ve kalınlığının kaç santimetre olduğunu bilmeliyiz ki, ona uygun bir alet seçelim. Bunun için toprak incelenir. Yapılan çalışmanın sonucuna göre;
* Sert tabaka toprak yüzeyinden 20-25 cm. derinlikte oluşmuş ise çizel aleti kullanılır.
* Sert tabaka toprak yüzeyinden 30-40 cm. derinde oluşmuş ise subsoiler (dipkazan) aleti kullanılmmalıdır.
* Sert tabaka toprak yüzeyinden 65-70 cm derinlikte oluşmuş ise riper aleti kullanılmalıdır.
Sert tabakanın kırılmasının faydaları:
Sert tabakadan dolayı ıslaklık sorunu olan yerlerde sert tabaka kırılarak geç tava gelme durumu ortadan kalkar, erken veya zamanında ekim yapılması sağlanır. Toprağın havalanması ve toprağın su tutma kapasitesi artar. Toprağın derinlerinde bulunan besin maddelerinin alınması kolaylaşır.
Beklenen faydaların olabilmesi için;
* Sert tabakanın iyice parçalanması ile bunu sağlayacak çizel, dipkazan ve riper aletlerinin çekimi için en uygun zaman toprağın kuru olmasıdır. Bu nedenle sert tabakanın kırılması yaz aylarında yapılmalıdır.
*Sert tabakanın çok iyi parçalanması için çizel veya dipkazan aletinin yırtıcı kısımları (derinliği bakımından) sert tabakanın hemen altından geçirilmelidir.
* Sert tabakayı kırmak için kullanılan aletin çok sık veya çok seyrek aralıklarla çekilmesi beklenen faydayı sağlamaz. Aletin 90X90 cm. aralıklarla çekilmesi halinde sert tabaka iyice parçalanmakta ve rantabl olmaktadır.
* Sert tabakanın kırılmasında çizel ve dipkazan kullanılması halinde 4-5 yılda bir, riper kullanılması halinde ise 8-10 yılda bir kırma işlemi yeniden yapılmalıdır.
11 Kasım 2015 Çarşamba
Marvel pluginini nasıl yükleriz?
C:\>cd C:\Program Files\Elasticsearch\bin C:\Program Files\Elasticsearch\bin>Plugin.bat -i elasticsearch/marvel/latestEğer yüklemede sorun yaşarsanız bilinki bu klasöre yazma hakkınız olmayabilir
Failed to install elasticsearch/marvel/latest, reason: plugin directory C:\Program Files\Elasticsearch\plugins is read only” then create a ‘plugins’ directory to root of your ElasticSearch installation path and make it write and Read write permissions for all user.
ElasticSearch servisini yeniden başlatalım.
Şimdi browserda görelim: http://localhost:9200/_plugin/marvel
‘Dashboard’ menüsünden ‘sense’ seçeneğini seçerek kod yazabilirsiniz.
10 Kasım 2015 Salı
JSON Schema da null olabilen boolean alan (nullable boolean property)
{ "$schema": "http://json-schema.org/draft-04/schema#", "id": "http://jsonschema.net", "type": "object", "properties": { "c": { "anyOf": [ { "type": "boolean" }, { "type": "null" } ] } } }
{c: null}
5 Ekim 2015 Pazartesi
json-schema-defaults ile node.js üstünde .json uzantılı şemaları dinamik yüklemek
var getRemoteRef = function (_uri, definitions) { // loadschema ileride async olarak şema yüklemelerini sağlamak için kullanacağım için şimdiden hazır edeyim dedim. var loadSchema = function (uri, callback) { var request = require('request'); request(uri, function (err, res, body) { console.log(body); // Bu gelen şemayı doğrulamaya göndermeden önce JSON'a çevirmelisiniz. if (err || res.statusCode >= 400) callback(err || new Error('Loading error: ' + res.statusCode)); else { callback(null, JSON.parse(body)); } }); }; // node uygulamasının hangi fiziksel klasörde olduğunu buluyorum var appRoot = require('app-root-path'), // dosya yolunun schema'lı halini oluşturuyorum indexOfSchema = _uri.indexOf('/schema/'); // .json dosyasının tam yolunu bulduktan sonra var filePath = appRoot + "/node/" + _uri.substr(indexOfSchema); console.log("Path: " + filePath); // reuqire ile çekiyoruz var result = require(filePath); if (!isObject(result)) { return result; } return cloneJSON(result); }
(function (root, factory) { 'use strict'; if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') { // CommonJS module.exports = factory(); } else if (typeof define === 'function' && define.amd) { // AMD define('json-schema-defaults', [], function () { return factory(); }); } else { // global with noConflict var jsonSchemaDefaults = root.jsonSchemaDefaults; root.jsonSchemaDefaults = factory(); root.jsonSchemaDefaults.noConflict = function () { var defaults = root.jsonSchemaDefaults; root.jsonSchemaDefaults = jsonSchemaDefaults; return defaults; }; } }(this, function () { 'use strict'; var ajv = null; /** * check whether item is plain object * @param {*} item * @return {Boolean} */ var isObject = function (item) { return typeof item === 'object' && item !== null && item.toString() === {}.toString(); }; /** * deep JSON object clone * * @param {Object} source * @return {Object} */ var cloneJSON = function (source) { return JSON.parse(JSON.stringify(source)); }; /** * returns a result of deep merge of two objects * * @param {Object} target * @param {Object} source * @return {Object} */ var merge = function (target, source) { target = cloneJSON(target); for (var key in source) { if (source.hasOwnProperty(key)) { if (isObject(target[key]) && isObject(source[key])) { target[key] = merge(target[key], source[key]); } else { target[key] = source[key]; } } } return target; }; /** * merge list of objects from allOf properties * if some of objects contains $ref field extracts this reference and merge it * * @param {Array} allOfList * @param {Object} definitions * @return {Object} */ var mergeAllOf = function (allOfList, definitions) { var length = allOfList.length, index = -1, result = {}; while (++index < length) { var item = allOfList[index]; item = (typeof item.$ref !== 'undefined') ? getLocalRef(item.$ref, definitions) : item; result = merge(result, item); } return result; }; /** * get object by reference. works only with local references that points on * definitions object * * @param {String} path * @param {Object} definitions * @return {Object} */ var getLocalRef = function (path, definitions) { path = path.replace(/^#\/definitions\//, '').split('/'); var find = function (path, root) { var key = path.shift(); if (!root[key]) { return {}; } else if (!path.length) { return root[key]; } else { return find(path, root[key]); } }; var result = find(path, definitions); if (!isObject(result)) { return result; } return cloneJSON(result); }; var getRemoteRef = function (_uri, definitions) { var loadSchema = function (uri, callback) { var request = require('request'); request(uri, function (err, res, body) { console.log(body); // Bu gelen şemayı doğrulamaya göndermeden önce JSON'a çevirmelisiniz. if (err || res.statusCode >= 400) callback(err || new Error('Loading error: ' + res.statusCode)); else { callback(null, JSON.parse(body)); } }); }; var Path = require('path'), appRoot = require('app-root-path'), indexOfSchema = _uri.indexOf('/schema/'); var filePath = appRoot + "/node/" + _uri.substr(indexOfSchema); console.log("Path: " + filePath); var result = require(filePath); if (!isObject(result)) { return result; } return cloneJSON(result); } /** * returns a object that built with default values from json schema * * @param {Object} schema * @param {Object} definitions * @return {Object} */ var defaults = function (schema, definitions) { console.log("schema: " + JSON.stringify(schema, null, ' ')); console.log("definitions: " + JSON.stringify(definitions)); if (typeof schema['default'] !== 'undefined') { return schema['default']; } else if (typeof schema.allOf !== 'undefined') { var mergedItem = mergeAllOf(schema.allOf, definitions); console.log("MergedItem: " + JSON.stringify(mergedItem)); return defaults(mergedItem, definitions); } else if (typeof schema.$ref !== 'undefined') { console.log("Reference name: " + schema.$ref); var reference; if (schema.$ref.indexOf("http") == 0) { reference = getRemoteRef(schema.$ref, definitions); //reference= getRemoteRef("http://localhost:3000/schema/providers/login/test.json", definitions); } else { reference = getLocalRef(schema.$ref, definitions); } console.log("Refernce: " + JSON.stringify(reference)); return defaults(reference, definitions); } else if (schema.type === 'object') { if (!schema.properties) { return {}; } for (var key in schema.properties) { if (schema.properties.hasOwnProperty(key)) { schema.properties[key] = defaults(schema.properties[key], definitions); if (typeof schema.properties[key] === 'undefined') { delete schema.properties[key]; } } } return schema.properties; } else if (schema.type === 'array') { if (!schema.items) { return []; } return [defaults(schema.items, definitions)]; } else if (schema.type && typeof(schema.type) === 'object') { console.log("Reference name: " + schema.type.$ref); var reference = getLocalRef(schema.$ref, definitions); console.log("Refernce: " + JSON.stringify(reference)); return defaults(reference, definitions); if (!schema.items) { return []; } return [defaults(schema.items, definitions)]; } }; /** * main function * * @param {Object} schema * @param {Object|undefined} definitions * @return {Object} */ return function (schema, definitions, _ajv) { ajv = _ajv; if (definitions && Array.isArray(definitions)) { var defs = {}; definitions.forEach(function (_definition) { defs = merge(_definition, schema.definitions); }); definitions = defs; } if (typeof definitions === 'undefined') { definitions = schema.definitions || {}; } else if (isObject(schema.definitions)) { definitions = merge(definitions, schema.definitions); } return defaults(cloneJSON(schema), definitions); }; }));
AJV'yi JSON doğrulamalarında kullanmak
{ "id": "http://localhost:3000/schema/providers/login/index", "title": "Providers", "$schema": "http://json-schema.org/draft-04/schema#", "description": "Kullanıcı Giriş Sağlayıcıları", "type": "object", "definitions": { "TW": {"$ref": "http://localhost:3000/schema/providers/login/test.json"} }, "additionalProperties": false, "properties": { "TW": {"$ref": "#/definitions/TW"} } }test.json
{ "id": "http://localhost:3000/schema/providers/login/test.json", "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { "id": { "type": "integer", "default": 0 }, "id_str": {"type": "string"}, "name": { "type": "string", "default": "" } }, "required": [ "id", "name" ] }Her iki şemanın ID'sinin, URL adresleri olduğuna dikkat! Çünkü bu sayede hem eşsizliği sağlamış olursunuz hem de bağlantılarını kopartmamış olursunuz. Ayrıca $ref kısmını definitions içinde veriyor ve properties içindeki özelliklere buradan verdiğimiz için aynı tipi başka bir yerde kullansakta bir kez http talebi yapmış olacağız (Örn. properties:{ ev_adresi:{$ref:'http:/..../adres.json'}, is_adresi:{$ref:'http:/..../adres.json'}, ..} olsaydı aynı json 2 kez çağrılmış olacaktı).
addSchema metodu
2 Parametre alıyor; ilki şemanın kendisi(json nesnesi olacak), ikincisi ise eğer şemanın içinde "id" tanımlanmamışsa kullanılması için sizin belirteceğiniz "id" değeri(string olacak).var Ajv = require('ajv'), ajv = Ajv({removeAdditional:true}); function addSchema() { var schTest = require('./providers/login/test.json'); var schIndex = require('./providers/login/index.json'); ajv.addSchema(schTest); ajv.addSchema(schIndex); var bValid = ajv.validate(schIndex.id, {TW: {id: 2, a: 1, name: "cem"}}); if (!bValid) { console.log("Hatalıysam ara: "); console.log(ajv.errors); }else{ console.log("Herkül müsün kardeşim:"); var sch2 = ajv.getSchema("http://localhost:3000/schema/providers/login/index"); console.log(sch2.schema); } } addSchema();
compile metodu
var Ajv = require('ajv'), ajv = Ajv({removeAdditional:true}); function compile() { var schTest = require('./providers/login/test.json'); var schIndex = require('./providers/login/index.json'); ajv.addSchema(schTest); // önce test şemasını ekleyelimki index.json içinde kullanılmadan önce hazır olsun var validate = ajv.compile(schIndex); // index.json'ı derleyerek doğrulayacak fonksiyonumuza ulaşalım. console.log(validate.schema) // şemamızın içinde test.json'ı referans olarak görürüz ama doğrulama sırasında bu referanslara bakarak veri nesnesini doğrulayacaktır var a = validate({TW: {id: 2, name: "cem"}}) // hata vermez ve başarıyla doğrulanmış olur if(validate.errors){ console.log(validate.errors) }else{ console.log(a); } } compile();
compileAsync metodu
Bu fonksiyonu kullanmadan önce asenkron olarak yükleme işini yapacak fonksiyonu tanımlamalısınız ve yükleme tamamlandıktan sonra doğrulama yapacak callback fonksiyonunu girmelisiniz. Bunun için AJV'nin options larından loadSchema'yı kullanacağız.ajv = Ajv({ loadSchema: function (uri, callback) { var request = require('request'); request(uri, function (err, res, body) { console.log(body); // Bu gelen şemayı doğrulamaya göndermeden önce JSON'a çevirmelisiniz. if (err || res.statusCode >= 400) callback(err || new Error('Loading error: ' + res.statusCode)); else { callback(null, JSON.parse(body)); } }); } }); function compileAsync() { var sch = require('./providers/login/index.json'); console.log("sch--------------"); console.log(JSON.stringify(sch)); ajv.compileAsync(sch, function (err, validate) { console.log(validate); // görelim ne var elimizde if (err) return; // hata varsa dön bebeğim var a = validate({TW:{id: 2, name: "cem"}}); console.log(validate.errors); // null döner console.log(a); // true döner(hatasız); }); } compileAsync();Tüm kod:
var Ajv = require('ajv'), //sch = require('./index'), ajv = Ajv({removeAdditional: true}); // options can be passed ajv = Ajv({ loadSchema: function (uri, callback) { var request = require('request'); request(uri, function (err, res, body) { console.log("request ended"); console.log(body); if (err || res.statusCode >= 400) callback(err || new Error('Loading error: ' + res.statusCode)); else { callback(null, JSON.parse(body)); } }); } }); function compile() { var schTest = require('./providers/login/test.json'); var schIndex = require('./providers/login/index.json'); ajv.addSchema(schTest); var validate = ajv.compile(schIndex); console.log(validate.schema); var a = validate({TW: {id: 2, name: "cem"}}); console.log(validate.errors); console.log(a); } //compile(); function compileAsync() { var sch = require('./providers/login/index.json'); console.log("sch--------------"); console.log(JSON.stringify(sch)); ajv.compileAsync(sch, function (err, validate) { console.log(validate); console.log("neredeyim") console.log("err: " + err); if (err) return; var a = validate({id: 2, name: "cem"}) console.log(validate.errors) console.log(a); console.log("buradayım"); }); } //compileAsync(); function addSchema() { var schTest = require('./providers/login/test.json'); var schIndex = require('./providers/login/index.json'); ajv.addSchema(schTest); ajv.addSchema(schIndex); var bValid = ajv.validate(schIndex.id, {a: 1,TW: {id: 2, name: "cem"}}); if (!bValid) { console.log("Hatalıysam ara: "); console.log(ajv.errors); }else{ console.log("Herkül müsün kardeşim:"); var sch2 = ajv.getSchema("http://localhost:3000/schema/providers/login/index"); console.log(sch2.schema); } } //addSchema();
29 Eylül 2015 Salı
Elasticsearch ile sorgulama
Search API
Önce ekşideki bilgi hapları alalım:en önemli özelliği distributed ve real-time olması.
solr gibi core olarak lucene kullaniyor (yani datastore aslinda lucene dokumanlari). kabuk demek daha dogru olur kanimca, daha cok orchestrator gibi
aslında bir nosql databasedir. datayı relational olmayan bir şekilde store ettiği için bayılmadan full text search yapabiliyorsunuz
kendi query-dsl'ini de üzerine barındırması fevkalade bir durum
query dsl'i biraz karışık ve aslında birbirinin yaptığı işleri aynen yapan farklı fonksiyonlar varPeki QUERY DSL ile sorgulama konusunda bool query'ye temel bakış atalım:
{ "query": { "bool": { "must": [ { "term": { "FIELD": { "value": "VALUE" } } }, { "query_string": { "default_field": "FIELD", "query": "this AND that OR thus" } } ], "should": [ { "match": { "FIELD": "TEXT" } } ], "minimum_number_should_match": 1, "must_not": [ { "range": { "FIELD": { "from": "10", "to": "20" } } } ], "boost": "4" } } }
localhost:9200/index/type
URL yapısında sorgulama yapmak için _search
api ile sorgulamak istenildiğinde localhost:9200/index/type/_search şeklinde sorgu yazılabilir. Search API aynı zamanda Faceting ve Filtering sağlayacaktır.Aşağıdaki sorgu sadece size ve query parametrelerinin atandığı facet ve filter'ın ise olmadığı temel bir sorgudur:
{ "size": 3, "query": { "match": { "hobbies": "skateboard" } } }Bu sorgu sadece hobiler içinde skateboard terimini aradığımız bir sorgudur ve hem
GET
hem POST
metotlarıyla sadece urlnin sonunda _search
olacak şekilde çalıştırılabilir.Temel sorgulama tipleri:
- Term
- Match
- Range
- Filters
Ref: http://exploringelasticsearch.com/searching_data.html
http://www.slideshare.net/clintongormley/elasticsearch-query-dsl-not-just-for-wizards
Mapping durumunu görüntüleme
Sadece bir indexin mappingi için
GET http://10.214.66.90:9200/_mapping/ihale
Birden fazla indexin mappingi için
GET http://10.214.66.90:9200/_mapping/ihale,Firma
Bir filed(alanın) mappingi için
GET http://10.214.66.90:9200/_mapping/ihale/field/Konusu
14 Eylül 2015 Pazartesi
zkemkeeper.dll ve Asp.Net uygulaması
copy .\sdk\*.dll %windir%\system32\ regsvr32 %windir%\system32\zkemkeeper.dll
Buna göre sdk içindeki tüm dll dosyalarını C:\Windows\system32 dizinine kopyalayıp zkemkeeper.dll dosyasını da registry'ye kaydetmiş oluyoruz. zkemkeper.dll için bir uygulama idsi oluşturdu {FE9D.....32C7} diye ve bunu da {00853....61F} ile çağırabilir bir DCOM objesi olarak sisteme kaydetti.
Normal olarak demo uygulamalarını bu kayıt işlemi yapılmadan önce çalıştırdığımda şu hatayı alıyordum:
FAE has stopped working
DLL register edildikten sonra uygulama çalışıyor ve biyometrik cihazlara bağlantı sağlıyordu ama başka makinelerde aldığım bir sorunun ekran görüntüsünü şöyle alıyordum:
Bu hatayı elde etmek için program FAE hatası almasın diye dll register ettim ve uygulama açıldıktan sonra unregister ederek bağlanmayı deneyince ekrandaki Error mesajını aldım. Bu mesaj biyometrik cihazın çeşitli hata seviyelerinden(sanırım 6-7 tane var) biri. Maksadım bunu gördüğünüzde neden olduğunu bir nebze anlamanızı sağlamak.
Şimdi "happy path"(mutluluğa giden keçi yoluna bakalım :) )
Dll kaydedildi ve demo uygulamasıyla cihaza bağlanalım:
ASP.NET uygulamamda ise şu hataları alıyordum:
- Class not registered diyerek CZKEMClass'tan bir nesne yaratmama müsade etmiyordu
- Başka bir makinede ise nesne yaratıyor ama aktif cihazlara peş peşe bağlantı sağla dediğimde sorun çıkartmazken, pasif bir cihaza bağlan dediğimde bir sonraki aktif cihaza bağlantı sağlamayı denemeden cihaza ulaşılamadı diyordu
1. Madde için aldığım sorunu göstereyim:
Retrieving the COM class factory for component with CLSID {00853A19-BD51-419B-9269-2DABE57EB61F} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
2. Madde için ekran görüntüsünü yaratamıyorum ama ikisinin çözümünü nerede bulduğumun ekranını paylaşayım:
IIS Express'in 64 bit versiyonunu çalışmaya zorlayınca dll'lerin register edildiği versiyona erişmesini sağlamış oldum. Çünkü zkemkeeper.dll'i kaydetmek istediğinizde 32/64 bit seçeneklerinden eğer 64 bitlik sistem üstünde koşuyorsanız 32 liğini yükleyemiyorsunuz(klasör adı "Communication Protocol SDK(32Bit Ver6.2.4.1)" olanı yükleyemiyorsunuz çünkü içeriğindeki zkemkeeper.dll 32 uyumlu değil).
Ancak Communication Protocol SDK(64Bit Ver6.2.4.1) klasöründeki zkemkeeper.dll dosyasını sisteme kaydedebiliyorsunuz. Bu durumda ASP.NET uygulamanızın IIS Express versiyonununda 64 bit olması için zorlamanız gerekiyor.
Ve tekrar çalıştırdığımda uygulamamı:
Lotus Notes ile gönderdiğiniz iletileri başka bir eposta hesabına gönderebilmek
Sub Initialize Dim s As New NotesSession Dim db As NotesDatabase ' current mail file Dim lupV As NotesView ' docs in forwarding folder Dim lupDoc As NotesDocument ' current lupE doc being forwarded Dim counter As Long ' counter, use for limit Dim dc As notesdocumentcollection Set db = s.CurrentDatabase Set dc=db.UnprocessedDocuments Set lupDoc = dc.GetFirstDocument Do While Not(lupDoc Is Nothing) If (ProcessEmail(s, db, lupDoc, "cem.topkaya@hotmail.com")=1) Then Set lupDoc = dc.GetNextDocument(lupDoc) End If counter =counter+1 Loop SkipDone: Print "Es geçilen belge" Exit Sub ErrorHandler: Print "Unexpected Error: " & Cstr(Err) & " " & Error$ & ", on line: " & Cstr(Erl) End Sub Function ProcessEmail(s As NotesSession, db As NotesDatabase, lupDoc As NotesDocument, newSendTo) As Integer ' forwards current entry/doc, and returns 1 if successful ' newSendTo should be internet address or Canonical Notes name Dim mDoc As NotesDocument ' new memo doc created from original doc On Error Goto FErrorHandler ' create new doc from current document Set mDoc = db.CreateDocument() Call lupDoc.CopyAllItems(mDoc, True) mDoc.SaveMessageOnSend = False ' remap from/sendto/replyto so when forwarded still be from original person Call mDoc.ReplaceItemValue("SendTo", newSendTo) Call mDoc.ReplaceItemValue("CopyTo", "") ' otherwise another copy will be sent Call mDoc.ReplaceItemValue("BlindCopyTo", "") ' otherwise another copy will be sent ' send new doc Call mDoc.Send(False, newSendTo) ' reset to nothing Set mDoc = Nothing ' başarılı bir eposta gönderimi yaptık ProcessEmail = 1 FExit: Exit Function FErrorHandler: Print "(ProcessEmail) Unexpected Error: " & Cstr(Err) & " " & Error$ & ", on line: " & Cstr(Erl) ProcessEmail = 0 Exit Function End Function